Completed
Push — master ( f47ce4...c9683e )
by mw
04:41
created

compareTargetToCurrentLanguage()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 7.1941

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 9.2888
c 0
b 0
f 0
ccs 5
cts 9
cp 0.5556
cc 5
nc 6
nop 2
crap 7.1941
1
<?php
2
3
namespace SIL;
4
5
use Title;
6
use ParserOutput;
7
8
/**
9
 * @license GNU GPL v2+
10
 * @since 1.0
11
 *
12
 * @author mwjames
13
 */
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 ) {
41 6
		$this->parserOutput = $parserOutput;
42 6
		$this->interlanguageLinksLookup = $interlanguageLinksLookup;
43 6
	}
44
45
	/**
46
	 * @since 1.0
47
	 *
48
	 * @param Title $target
49
	 *
50
	 * @return Title
51
	 */
52 2
	public function getRedirectTargetFor( Title $title ) {
53 2
		return $this->interlanguageLinksLookup->getRedirectTargetFor( $title );
54
	}
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 ) {
160
161 5
		unset( $languageTargetLinks[ $interlanguageLink->getLanguageCode() ] );
162 5
		ksort( $languageTargetLinks );
163
164 5
		return $languageTargetLinks;
165
	}
166
167 5
	private function doPurgeParserCache( $languageTargetLinks ) {
168 5
		foreach ( $languageTargetLinks as $languageTargetLink ) {
169
170 5
			if ( !$languageTargetLink instanceof Title ) {
171 1
				continue;
172
			}
173
174 4
			$languageTargetLink->invalidateCache();
175
		}
176 5
	}
177
178
}
179