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