Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 64
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
LinksTableUpdater
0.00% covered (danger)
0.00%
0 / 64
0.00% covered (danger)
0.00%
0 / 4
420
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 doUpdate
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 mutateParserOutput
0.00% covered (danger)
0.00%
0 / 41
0.00% covered (danger)
0.00%
0 / 1
240
 getReferencesForTitle
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace Flow;
4
5use Flow\Data\ManagerGroup;
6use Flow\Model\Reference;
7use Flow\Model\URLReference;
8use Flow\Model\WikiReference;
9use Flow\Model\Workflow;
10use MediaWiki\Deferred\DeferredUpdates;
11use MediaWiki\MediaWikiServices;
12use MediaWiki\Title\Title;
13use MediaWiki\WikiMap\WikiMap;
14use ParserOutput;
15
16class LinksTableUpdater {
17
18    /** @var ManagerGroup */
19    protected $storage;
20
21    /**
22     * @param ManagerGroup $storage A ManagerGroup
23     */
24    public function __construct( ManagerGroup $storage ) {
25        $this->storage = $storage;
26    }
27
28    public function doUpdate( Workflow $workflow ) {
29        $title = $workflow->getArticleTitle();
30        $page = MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle( $title );
31
32        $page->doSecondaryDataUpdates( [ 'defer' => DeferredUpdates::PRESEND, 'causeAction' => 'flow' ] );
33    }
34
35    /**
36     * @param Title $title
37     * @param ParserOutput $parserOutput
38     * @param Reference[]|null $references
39     */
40    public function mutateParserOutput( Title $title, ParserOutput $parserOutput, array $references = null ) {
41        $references ??= $this->getReferencesForTitle( $title );
42
43        $linkBatch = MediaWikiServices::getInstance()->getLinkBatchFactory()->newLinkBatch();
44        /** @var Title[] $internalLinks */
45        $internalLinks = [];
46        /** @var Title[] $templates */
47        $templates = [];
48
49        foreach ( $references as $reference ) {
50            if ( $reference->getType() === 'link' ) {
51                if ( $reference instanceof URLReference ) {
52                    $parserOutput->addExternalLink( $reference->getUrl() );
53                } elseif ( $reference instanceof WikiReference ) {
54                    $internalLinks[$reference->getTitle()->getPrefixedDBkey()] = $reference->getTitle();
55                    $linkBatch->addObj( $reference->getTitle() );
56                }
57            } elseif ( $reference->getType() === WikiReference::TYPE_CATEGORY ) {
58                if ( $reference instanceof WikiReference ) {
59                    $title = $reference->getTitle();
60                    $parserOutput->addCategory(
61                        $title->getDBkey(),
62                        // parsoid moves the sort key into the fragment
63                        $title->getFragment()
64                    );
65                }
66            } elseif ( $reference->getType() === 'file' ) {
67                if ( $reference instanceof WikiReference ) {
68                    // Only local images supported
69                    $parserOutput->addImage( $reference->getTitle()->getDBkey() );
70                }
71            } elseif ( $reference->getType() === 'template' ) {
72                if ( $reference instanceof WikiReference ) {
73                    $templates[$reference->getTitle()->getPrefixedDBkey()] = $reference->getTitle();
74                    $linkBatch->addObj( $reference->getTitle() );
75                }
76            }
77        }
78
79        $linkBatch->execute();
80        $linkCache = MediaWikiServices::getInstance()->getLinkCache();
81
82        foreach ( $internalLinks as $title ) {
83            $ns = $title->getNamespace();
84            $dbk = $title->getDBkey();
85            if ( !isset( $parserOutput->getLinks()[$ns] ) ) {
86                $parserOutput->getLinks()[$ns] = [];
87            }
88
89            $id = $linkCache->getGoodLinkID( $title->getPrefixedDBkey() );
90            $parserOutput->getLinks()[$ns][$dbk] = $id;
91        }
92
93        foreach ( $templates as $title ) {
94            $ns = $title->getNamespace();
95            $dbk = $title->getDBkey();
96            if ( !isset( $parserOutput->getTemplates()[$ns] ) ) {
97                $parserOutput->getTemplates()[$ns] = [];
98            }
99
100            $id = $linkCache->getGoodLinkID( $title->getPrefixedDBkey() );
101            $parserOutput->getTemplates()[$ns][$dbk] = $id;
102        }
103    }
104
105    public function getReferencesForTitle( Title $title ) {
106        $wikiReferences = $this->storage->find(
107            'WikiReference',
108            [
109                'ref_src_wiki' => WikiMap::getCurrentWikiId(),
110                'ref_src_namespace' => $title->getNamespace(),
111                'ref_src_title' => $title->getDBkey(),
112            ]
113        );
114
115        $urlReferences = $this->storage->find(
116            'URLReference',
117            [
118                'ref_src_wiki' => WikiMap::getCurrentWikiId(),
119                'ref_src_namespace' => $title->getNamespace(),
120                'ref_src_title' => $title->getDBkey(),
121            ]
122        );
123
124        // let's make sure the merge doesn't fail when nothing was found
125        $wikiReferences = $wikiReferences ?: [];
126        $urlReferences = $urlReferences ?: [];
127
128        return array_merge( $wikiReferences, $urlReferences );
129    }
130}