createSiteLanguageLinks()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 13
cts 13
cp 1
rs 9.536
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
namespace SIL;
4
5
use Onoi\Cache\CacheFactory;
6
use Title;
7
use Language;
8
9
use SMW\Localizer;
10
11
/**
12
 * @license GNU GPL v2+
13
 * @since 1.0
14
 *
15
 * @author mwjames
16
 */
17
class InterlanguageLinkParserFunction {
18
19
	/**
20
	 * @var Title
21
	 */
22
	private $title;
23
24
	/**
25
	 * @var LanguageLinkAnnotator
26
	 */
27
	private $languageLinkAnnotator;
28
29
	/**
30
	 * @var SiteLanguageLinksParserOutputAppender
31
	 */
32
	private $siteLanguageLinksParserOutputAppender;
33
34
	/**
35
	 * @var pageContentLanguageOnTheFlyModifier
36
	 */
37
	private $pageContentLanguageOnTheFlyModifier;
38
39
	/**
40
	 * @var PageContentLanguageDbModifier
41
	 */
42
	private $pageContentLanguageDbModifier;
43
44
	/**
45
	 * @var boolean
46
	 */
47
	private $interlanguageLinksHideState = false;
48
49
	/**
50
	 * @var boolean
51
	 */
52
	private $inRevisionMode = false;
53
54
	/**
55
	 * @since 1.0
56
	 *
57
	 * @param Title $title
58
	 * @param LanguageLinkAnnotator $languageLinkAnnotator
59
	 * @param SiteLanguageLinksParserOutputAppender $siteLanguageLinksParserOutputAppender
60
	 * @param PageContentLanguageOnTheFlyModifier $pageContentLanguageOnTheFlyModifier
61
	 * @param PageContentLanguageDbModifier $pageContentLanguageDbModifier
62
	 */
63 12
	public function __construct( Title $title, LanguageLinkAnnotator $languageLinkAnnotator, SiteLanguageLinksParserOutputAppender $siteLanguageLinksParserOutputAppender, PageContentLanguageOnTheFlyModifier $pageContentLanguageOnTheFlyModifier, PageContentLanguageDbModifier $pageContentLanguageDbModifier ) {
64 12
		$this->title = $title;
65 12
		$this->languageLinkAnnotator = $languageLinkAnnotator;
66 12
		$this->siteLanguageLinksParserOutputAppender = $siteLanguageLinksParserOutputAppender;
67 12
		$this->pageContentLanguageOnTheFlyModifier = $pageContentLanguageOnTheFlyModifier;
68 12
		$this->pageContentLanguageDbModifier = $pageContentLanguageDbModifier;
69 12
	}
70
71
	/**
72
	 * @since 1.0
73
	 *
74
	 * @param boolean $interlanguageLinksHideState
75
	 */
76 6
	public function setInterlanguageLinksHideState( $interlanguageLinksHideState ) {
77 6
		$this->interlanguageLinksHideState = $interlanguageLinksHideState;
78 6
	}
79
80
	/**
81
	 * Revision mode means either in preview or edit state which is not to be
82
	 * handled to avoid storage of yet unprocessed data in cache.
83
	 *
84
	 * @since 1.2
85
	 *
86
	 * @param boolean $inRevisionMode
87
	 */
88 4
	public function setRevisionModeState( $inRevisionMode ) {
89 4
		$this->inRevisionMode = $inRevisionMode;
90 4
	}
91
92
	/**
93
	 * @since 1.0
94
	 *
95
	 * @param string $languageCode
96
	 * @param string $linkReference
97
	 *
98
	 * @return null|string
99
	 */
100 11
	public function parse( $languageCode, $linkReference ) {
101
102 11
		$languageCode = Localizer::asBCP47FormattedLanguageCode( $languageCode );
103
104
		// Keep reference while editing is on going to avoid a possible lag when
105
		// a DV is trying to access the page content language
106 11
		if ( ( $isSupportedLanguage = $this->isSupportedLanguage( $languageCode ) ) === true ) {
107 11
			$this->pageContentLanguageOnTheFlyModifier->addToIntermediaryCache( $this->title, $languageCode );
108
		}
109
110 11
		if ( !( $title = $this->getTitleFrom( $isSupportedLanguage, $languageCode, $linkReference ) ) instanceof Title ) {
111 4
			return $title;
112
		}
113
114 7
		$interlanguageLink = new InterlanguageLink(
115 7
			$languageCode,
116 7
			$this->siteLanguageLinksParserOutputAppender->getRedirectTargetFor( $title )
117
		);
118
119 7
		$this->pageContentLanguageDbModifier->updatePageLanguage( $languageCode );
120
121 7
		if ( $this->languageLinkAnnotator->hasDifferentLanguageAnnotation( $interlanguageLink ) ) {
122 1
			return $this->createErrorMessageFor( 'sil-interlanguagelink-multiplecalls-different-languagecode', $languageCode );
123
		}
124
125 7
		return $this->createSiteLanguageLinks( $interlanguageLink );
126
	}
127
128 11
	private function getTitleFrom( $isSupportedLanguage, $languageCode, $linkReference ) {
129
130 11
		if ( $this->inRevisionMode || !$this->languageLinkAnnotator->canAddAnnotation() ) {
131 3
			return '';
132
		}
133
134 8
		if ( $this->interlanguageLinksHideState ) {
135 1
			return $this->createErrorMessageFor( 'sil-interlanguagelink-hideinterlanguagelinks' );
136
		}
137
138 8
		if ( !$isSupportedLanguage ) {
139 1
			return $this->createErrorMessageFor( 'sil-interlanguagelink-invalidlanguagecode', $languageCode );
140
		}
141
142 8
		$title = Title::newFromText( $linkReference );
143
144 8
		if ( $title === null ) {
145 1
			return $this->createErrorMessageFor( 'sil-interlanguageparser-linkreference-error', $linkReference );
146
		}
147
148 7
		return $title;
149
	}
150
151 7
	private function createSiteLanguageLinks( InterlanguageLink $interlanguageLink ) {
152
153 7
		$knownTargetLink = $this->siteLanguageLinksParserOutputAppender->tryAddLanguageTargetLinksToOutput(
154 7
			$interlanguageLink,
155 7
			$this->title
156
		);
157
158
		// If target is known we stop processing and output an error
159 7
		if ( $knownTargetLink ) {
160 1
			return $this->createErrorMessageFor(
161 1
				'sil-interlanguagelink-languagetargetcombination-exists',
162 1
				$interlanguageLink->getLanguageCode(),
163 1
				$interlanguageLink->getLinkReference()->getPrefixedText(),
164
				$knownTargetLink,
0 ignored issues
show
Bug introduced by
It seems like $knownTargetLink defined by $this->siteLanguageLinks...uageLink, $this->title) on line 153 can also be of type boolean; however, SIL\InterlanguageLinkPar...createErrorMessageFor() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
165 1
				$this->title->getPrefixedText()
166
			);
167
		}
168
169 6
		$this->languageLinkAnnotator->addAnnotationForInterlanguageLink(
170 6
			$interlanguageLink
171
		);
172
173 6
		return '<div class="sil-interlanguagelink"></div>';
174
	}
175
176 11
	private function isSupportedLanguage( $languageCode ) {
177
178 11
		$languageCode = trim( mb_strtolower( $languageCode ) );
179
180 11
		if ( strlen( $languageCode ) == 0 ) {
181 1
			return false;
182
		}
183
184 11
		return Language::isSupportedLanguage( $languageCode );
185
	}
186
187 3
	private function createErrorMessageFor( $messageKey, $arg1 = '', $arg2 = '', $arg3 = '',$arg4 = '' ) {
188 3
		return '<div class="smw-callout smw-callout-error">' . wfMessage(
189 3
			$messageKey,
190
			$arg1,
191
			$arg2,
192
			$arg3,
193
			$arg4
194 3
		)->inContentLanguage()->text() . '</div>';
195
	}
196
197
}
198