GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Test Setup Failed
Push — master ( 1f58dd...e46154 )
by
unknown
31:29
created

src/Element.php (2 issues)

1
<?php
2
3
/**
4
 * File holding the Lingo\Element class.
5
 *
6
 * This file is part of the MediaWiki extension Lingo.
7
 *
8
 * @copyright 2011 - 2018, Stephan Gambke
9
 * @license GPL-2.0-or-later
10
 *
11
 * The Lingo extension is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by the Free
13
 * Software Foundation; either version 2 of the License, or (at your option) any
14
 * later version.
15
 *
16
 * The Lingo extension is distributed in the hope that it will be useful, but
17
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19
 * details.
20
 *
21
 * You should have received a copy of the GNU General Public License along
22
 * with this program. If not, see <http://www.gnu.org/licenses/>.
23
 *
24
 * @author Stephan Gambke
25
 *
26
 * @file
27
 * @ingroup Lingo
28
 */
29
30
namespace Lingo;
31
32
use DOMDocument;
33
use DOMElement;
34
use DOMText;
35
use Title;
36
37
/**
38
 * This class represents a term-definition pair.
39
 * One term may be related to several definitions.
40
 *
41
 * @ingroup Lingo
42
 */
43
class Element {
44
	const ELEMENT_TERM = 0;
45
	const ELEMENT_DEFINITION = 1;
46
	const ELEMENT_SOURCE = 2;
47
	const ELEMENT_LINK = 3;
48
	const ELEMENT_STYLE = 4;
49
50
	const ELEMENT_FIELDCOUNT = 5;  // number of fields stored for each element; (last field's index) + 1
51
52
	const LINK_TEMPLATE_ID = 'LingoLink';
53
54
	private $formattedTerm = null;
55
	private $formattedDefinitions = null;
56
57
	private $mDefinitions = [];
58
	private $mTerm = null;
59
60
	private $hasBeenDisplayed = false;
61
62
	/**
63
	 * Lingo\Element constructor.
64
	 *
65
	 * @param string $term
66
	 * @param string[] $definition
67
	 */
68 12
	public function __construct( &$term, &$definition ) {
69 12
		$this->mTerm = $term;
70 12
		$this->addDefinition( $definition );
71 12
	}
72
73
	/**
74
	 * @param array $definition
75
	 */
76 11
	public function addDefinition( &$definition ) {
77 11
		$this->mDefinitions[] = $definition + array_fill( 0, self::ELEMENT_FIELDCOUNT, null );
78 11
	}
79
80
	/**
81
	 * @param DOMDocument $doc
82
	 *
83
	 * @return DOMElement|DOMText
84
	 */
85 11
	public function getFormattedTerm( DOMDocument &$doc ) {
86 11
		global $wgexLingoDisplayOnce;
87
88 11
		if ( $wgexLingoDisplayOnce && $this->hasBeenDisplayed ) {
89 2
			return $doc->createTextNode( $this->mTerm );
90
		}
91
92 11
		$this->hasBeenDisplayed = true;
93
94 11
		$this->buildFormattedTerm( $doc );
95
96 11
		return $this->formattedTerm->cloneNode( true );
97
	}
98
99
	/**
100
	 * @param DOMDocument $doc
101
	 */
102 11
	private function buildFormattedTerm( DOMDocument &$doc ) {
103
		// only create if not yet created
104 11
		if ( $this->formattedTerm === null || $this->formattedTerm->ownerDocument !== $doc ) {
105
106 11
			if ( $this->isSimpleLink() ) {
107 7
				$this->formattedTerm = $this->buildFormattedTermAsLink( $doc );
108
			} else {
109 4
				$this->formattedTerm = $this->buildFormattedTermAsTooltip( $doc );
110
			}
111
		}
112 11
	}
113
114
	/**
115
	 * @return bool
116
	 */
117 11
	private function isSimpleLink() {
118 11
		return count( $this->mDefinitions ) === 1 &&
119 11
			!is_string( $this->mDefinitions[ 0 ][ self::ELEMENT_DEFINITION ] ) &&
120 11
			is_string( $this->mDefinitions[ 0 ][ self::ELEMENT_LINK ] );
121
	}
122
123
	/**
124
	 * @param DOMDocument $doc
125
	 * @return DOMElement
126
	 */
127 7
	protected function buildFormattedTermAsLink( DOMDocument &$doc ) {
128 7
		$linkTarget = $this->mDefinitions[ 0 ][ self::ELEMENT_LINK ];
129 7
		$descriptor = $this->getDescriptorFromLinkTarget( $linkTarget );
130
131 7
		if ( $descriptor === null ) {
132 2
			$this->mDefinitions = [];
133 2
			$this->addErrorMessageForInvalidLink( $linkTarget );
134 2
			return $this->buildFormattedTermAsTooltip( $doc );
135
		}
136
137
		// create link element
138 5
		$link = $doc->createElement( 'a', htmlentities( $this->mDefinitions[ 0 ][ self::ELEMENT_TERM ] ) );
139
140
		// set the link target
141 5
		$link->setAttribute( 'href', $descriptor[ 'url' ] );
142 5
		$link->setAttribute( 'class', implode( ' ', $this->getClassesForLink( $descriptor ) ) );
143
144 5
		$title = $this->getTitleForLink( $descriptor );
145 5
		if ( $title !== null ) {
146 4
			$link->setAttribute( 'title', $title );
147
		}
148
149 5
		return $link;
150
	}
151
152
	/**
153
	 * @param DOMDocument $doc
154
	 *
155
	 * @return DOMElement
156
	 */
157 6
	protected function buildFormattedTermAsTooltip( DOMDocument &$doc ) {
158
		// Wrap term and definition in <span> tags
159 6
		$span = $doc->createElement( 'span', htmlentities( $this->mTerm ) );
160 6
		$span->setAttribute( 'class', 'mw-lingo-term' );
161 6
		$span->setAttribute( 'data-lingo-term-id', $this->getId() );
162
163 6
		return $span;
164
	}
165
166
	/**
167
	 * @param $descriptor
168
	 *
169
	 * @return string[]
170
	 */
171 5
	protected function getClassesForLink( $descriptor ) {
172
		// TODO: should this be more elaborate?
173
		// Cleanest would probably be to use Linker::link and parse it
174
		// back into a DOMElement, but we are in a somewhat time-critical
175
		// part here.
176
177
		// set style
178 5
		$classes = [ 'mw-lingo-term' ];
179
180 5
		$classes[] = $this->mDefinitions[ 0 ][ self::ELEMENT_STYLE ];
181
182 5
		if ( array_key_exists( 'title', $descriptor ) && $descriptor[ 'title' ] instanceof Title ) {
183
184 4
			if ( !$descriptor['title']->isKnown() ) {
185 2
				$classes[] = 'new';
186
			}
187
188 4
			if ( $descriptor['title']->isExternal() ) {
189 4
				$classes[] = 'extiw';
190
			}
191
192
		} else {
193 1
			$classes[] = 'ext';
194
		}
195
196 5
		return array_filter( $classes );
197
	}
198
199
	/**
200
	 * @param Title $target
201
	 * @param DOMElement $link
202
	 *
203
	 * @return string
204
	 */
205 5
	protected function getTitleForLink( $descriptor ) {
206
		/** @var \Title $target */
207 5
		$target = $descriptor[ 'title' ];
208
209 5
		if ( is_string( $target ) ) {
210 1
			return $target;
211
		}
212
213 4
		if ( $target->getPrefixedText() === '' ) {
214 1
			return null;
215
		}
216
217 3
		if ( $target->isKnown() ) {
218 1
			return $target->getPrefixedText();
219
		}
220
221 2
		return wfMessage( 'red-link-title', $target->getPrefixedText() )->text();
222
	}
223
224
	/**
225
	 * @return string[]
226
	 */
227 4
	public function getFormattedDefinitions() {
228 4
		if ( $this->formattedDefinitions === null ) {
229 4
			$this->buildFormattedDefinitions();
230
		}
231
232 4
		return $this->formattedDefinitions;
233
	}
234
235
	/**
236
	 */
237 4
	protected function buildFormattedDefinitions() {
238 4
		if ( $this->isSimpleLink() ) {
239 1
			$this->formattedDefinitions = '';
240 1
			return;
241
		}
242
243 3
		$divDefinitions = "<div class='mw-lingo-tooltip' id='{$this->getId()}'>";
244
245 3
		$definition = reset( $this->mDefinitions );
246 3
		while ( $definition !== false ) {
247
248 3
			$text = $definition[ self::ELEMENT_DEFINITION ];
249 3
			$link = $definition[ self::ELEMENT_LINK ];
250 3
			$style = $definition[ self::ELEMENT_STYLE ];
251
252 3
			$divDefinitions .= "<div class='mw-lingo-definition {$style}'><div class='mw-lingo-definition-text'>\n{$text}\n</div>";
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $style instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $text instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
253
254 3
			if ( $link !== null ) {
255
256 2
				$descriptor = $this->getDescriptorFromLinkTarget( $link );
257
258 2
				if ( $descriptor === null ) {
259 1
					$this->addErrorMessageForInvalidLink( $link );
260
				} else {
261 1
					$divDefinitions .= "<div class='mw-lingo-definition-link'>[{$descriptor[ 'url' ]} <nowiki/>]</div>";
262
				}
263
			}
264
265 3
			$divDefinitions .= "</div>";
266
267 3
			$definition = next( $this->mDefinitions );
268
		}
269
270 3
		$divDefinitions .= "\n</div>";
271
272 3
		$this->formattedDefinitions = $divDefinitions;
273 3
	}
274
275
	/**
276
	 * @return string
277
	 */
278 6
	public function getId() {
279 6
		return md5( $this->mTerm );
280
	}
281
282
	/**
283
	 * @param string $linkTarget
284
	 *
285
	 * @return string[]
286
	 */
287 9
	protected function getDescriptorFromLinkTarget( $linkTarget ) {
288 9
		if ( $this->isValidLinkTarget( $linkTarget ) ) {
289 1
			return [ 'url' => $linkTarget, 'title' => $this->mTerm ];
290
		}
291
292 8
		$title = Title::newFromText( $linkTarget );
293
294 8
		if ( $title !== null ) {
295 5
			return [ 'url' => $title->getFullURL(), 'title' => $title ];
296
		}
297
298 3
		return null;
299
	}
300
301
	/**
302
	 * @param string $linkTarget
303
	 *
304
	 * @return bool
305
	 */
306 9
	protected function isValidLinkTarget( $linkTarget ) {
307 9
		return wfParseUrl( $linkTarget ) !== false;
308
	}
309
310
	/**
311
	 * @param $link
312
	 */
313 3
	protected function addErrorMessageForInvalidLink( $link ) {
314 3
		$errorMessage = wfMessage( 'lingo-invalidlinktarget', $this->mTerm, $link )->text();
315 3
		$errorDefinition = [ self::ELEMENT_DEFINITION => $errorMessage, self::ELEMENT_STYLE => 'invalid-link-target' ];
316
317 3
		$this->addDefinition( $errorDefinition );
318 3
	}
319
320
}
321