1 | <?php |
||
14 | class SiteLanguageLinksParserOutputAppender { |
||
15 | |||
16 | /** |
||
17 | * @var ParserOutput |
||
18 | */ |
||
19 | private $parserOutput; |
||
20 | |||
21 | /** |
||
22 | * @var InterlanguageLinksLookup |
||
23 | */ |
||
24 | private $interlanguageLinksLookup; |
||
25 | |||
26 | /** |
||
27 | * This is made static by choice to monitor multiple parser calls and filter |
||
28 | * out links with the same target. |
||
29 | * |
||
30 | * @var array |
||
31 | */ |
||
32 | private static $languageTargetLinksMap = []; |
||
33 | |||
34 | /** |
||
35 | * @since 1.0 |
||
36 | * |
||
37 | * @param ParserOutput $parserOutput |
||
38 | * @param InterlanguageLinksLookup $interlanguageLinksLookup |
||
39 | */ |
||
40 | 6 | public function __construct( ParserOutput $parserOutput, InterlanguageLinksLookup $interlanguageLinksLookup ) { |
|
44 | |||
45 | /** |
||
46 | * @since 1.0 |
||
47 | * |
||
48 | * @param Title $target |
||
49 | * |
||
50 | * @return Title |
||
51 | */ |
||
52 | 2 | public function getRedirectTargetFor( Title $title ) { |
|
55 | |||
56 | /** |
||
57 | * @since 1.0 |
||
58 | * |
||
59 | * @param InterlanguageLink $interlanguageLink |
||
60 | * @param Title|null $target |
||
61 | * |
||
62 | * @return string |
||
63 | */ |
||
64 | 5 | public function tryAddLanguageTargetLinksToOutput( InterlanguageLink $interlanguageLink, Title $target = null ) { |
|
65 | |||
66 | 5 | $knownTargetLink = ''; |
|
67 | 5 | $selectedTargetLinkForCurrentLanguage = false; |
|
68 | |||
69 | 5 | $languageTargetLinks = $this->interlanguageLinksLookup->queryLanguageTargetLinks( |
|
70 | 5 | $interlanguageLink, |
|
71 | 5 | $target |
|
72 | ); |
||
73 | |||
74 | // Always update the cache entry with an annotation directly made to avoid |
||
75 | // extra lookup during the view action |
||
76 | 5 | $this->interlanguageLinksLookup->pushPageLanguageToLookupCache( |
|
77 | 5 | $target, |
|
78 | 5 | $interlanguageLink->getLanguageCode() |
|
79 | ); |
||
80 | |||
81 | 5 | if ( isset( $languageTargetLinks[ $interlanguageLink->getLanguageCode() ] ) ) { |
|
82 | 3 | $selectedTargetLinkForCurrentLanguage = $languageTargetLinks[ $interlanguageLink->getLanguageCode() ]; |
|
83 | } |
||
84 | |||
85 | 5 | $knownTargetLink = $this->compareTargetToCurrentLanguage( |
|
86 | 5 | $target, |
|
87 | 5 | $selectedTargetLinkForCurrentLanguage |
|
88 | ); |
||
89 | |||
90 | 5 | if ( !$knownTargetLink ) { |
|
91 | 5 | $this->addLanguageLinksToOutput( |
|
92 | 5 | $interlanguageLink, |
|
93 | 5 | $languageTargetLinks |
|
94 | ); |
||
95 | } |
||
96 | |||
97 | 5 | $this->doPurgeParserCache( $languageTargetLinks ); |
|
98 | |||
99 | 5 | return $knownTargetLink; |
|
100 | } |
||
101 | |||
102 | /** |
||
103 | * Identify whether a double assignment did occur by comparing the target |
||
104 | * for the requested language and the current article as target that invoked |
||
105 | * INTERLANGUAGELINK parser. |
||
106 | * |
||
107 | * @return boolean|string |
||
108 | */ |
||
109 | 5 | private function compareTargetToCurrentLanguage( Title $target = null, $selectedTargetLinkForCurrentLanguage ) { |
|
110 | |||
111 | 5 | if ( $selectedTargetLinkForCurrentLanguage instanceof Title ) { |
|
112 | 3 | $selectedTargetLinkForCurrentLanguage = $selectedTargetLinkForCurrentLanguage->getPrefixedText(); |
|
113 | } |
||
114 | |||
115 | 5 | if ( $target !== null && $selectedTargetLinkForCurrentLanguage !== $target->getPrefixedText() ) { |
|
116 | |||
117 | $title = Title::newFromText( $selectedTargetLinkForCurrentLanguage ); |
||
118 | |||
119 | if ( $title->isRedirect() ) { |
||
120 | // $this->interlanguageLinksLookup->resetLookupCacheBy( $target ); |
||
121 | return false; |
||
122 | } |
||
123 | |||
124 | return $selectedTargetLinkForCurrentLanguage; |
||
125 | } |
||
126 | |||
127 | 5 | return false; |
|
128 | } |
||
129 | |||
130 | /** |
||
131 | * `sil:` is used as internal code to distinguish any language link that |
||
132 | * was not added by SIL |
||
133 | */ |
||
134 | 5 | private function addLanguageLinksToOutput( InterlanguageLink $interlanguageLink, array $languageTargetLinks ) { |
|
135 | |||
136 | 5 | $languageTargetLinks = $this->sanitizeLanguageTargetLinks( |
|
137 | 5 | $interlanguageLink, |
|
138 | 5 | $languageTargetLinks |
|
139 | ); |
||
140 | |||
141 | 5 | foreach ( $languageTargetLinks as $languageCode => $target ) { |
|
142 | |||
143 | 4 | if ( $target instanceof Title ) { |
|
144 | 3 | $target = $target->getPrefixedText(); |
|
145 | } |
||
146 | |||
147 | // Multiple parser calls can create maps that contain the same targets, |
||
148 | // safeguard against mutliple entries with the same target |
||
149 | 4 | if ( isset( self::$languageTargetLinksMap[$languageCode] ) && self::$languageTargetLinksMap[$languageCode] === $target ) { |
|
150 | 1 | continue; |
|
151 | } |
||
152 | |||
153 | 4 | self::$languageTargetLinksMap[$languageCode] = $target; |
|
154 | |||
155 | 4 | $this->parserOutput->addLanguageLink( 'sil:' . $languageCode . ':' . $target ); |
|
156 | } |
||
157 | 5 | } |
|
158 | |||
159 | 5 | private function sanitizeLanguageTargetLinks( InterlanguageLink $interlanguageLink, array $languageTargetLinks ) { |
|
166 | |||
167 | 5 | private function doPurgeParserCache( $languageTargetLinks ) { |
|
168 | 5 | foreach ( $languageTargetLinks as $languageTargetLink ) { |
|
169 | |||
177 | |||
178 | } |
||
179 |