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.
Completed
Push — master ( 8ee10e...f81903 )
by
unknown
05:06
created

NavbarHorizontal::getEditLinkHtml()   C

Complexity

Conditions 13
Paths 5

Size

Total Lines 41
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 19.2573

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 41
ccs 18
cts 27
cp 0.6667
rs 5.1234
cc 13
eloc 23
nc 5
nop 1
crap 19.2573

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * File holding the NavbarHorizontal class
4
 *
5
 * This file is part of the MediaWiki skin Chameleon.
6
 *
7
 * @copyright 2013 - 2015, Stephan Gambke
8
 * @license   GNU General Public License, version 3 (or any later version)
9
 *
10
 * The Chameleon skin is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by the Free
12
 * Software Foundation, either version 3 of the License, or (at your option) any
13
 * later version.
14
 *
15
 * The Chameleon skin is distributed in the hope that it will be useful, but
16
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
18
 * details.
19
 *
20
 * You should have received a copy of the GNU General Public License along
21
 * with this program. If not, see <http://www.gnu.org/licenses/>.
22
 *
23
 * @file
24
 * @ingroup   Skins
25
 */
26
27
namespace Skins\Chameleon\Components;
28
29
use Hooks;
30
use Skins\Chameleon\IdRegistry;
31
32
/**
33
 * The NavbarHorizontal class.
34
 *
35
 * A horizontal navbar containing the sidebar items.
36
 * Does not include standard items (toolbox, search, language links). They need
37
 * to be added to the page elsewhere
38
 *
39
 * The navbar is a list of lists wrapped in a nav element: <nav
40
 * role="navigation" id="p-navbar" >
41
 *
42
 * @author  Stephan Gambke
43
 * @since   1.0
44
 * @ingroup Skins
45
 */
46
class NavbarHorizontal extends Component {
47
48
	private $mHtml = null;
49
	private $htmlId = null;
50
51
	/**
52
	 * Builds the HTML code for this component
53
	 *
54
	 * @return String the HTML code
55
	 */
56 11
	public function getHtml() {
57
58 11
		if ( $this->mHtml === null ) {
59 11
			$this->buildHtml();
60 11
		}
61
62 11
		return $this->mHtml;
63
	}
64
65
	/**
66
	 *
67
	 */
68 11
	protected function buildHtml() {
69
70 11
		if ( $this->getDomElement() === null ) {
71 1
			$this->mHtml = '';
72 1
			return;
73
		}
74
75 10
		$this->mHtml =
76 10
			$this->buildFixedNavBarIfRequested() .
77 10
			$this->buildNavBarOpeningTags() .
78 10
			$this->buildNavBarComponents() .
79 10
			$this->buildNavBarClosingTags();
80 10
	}
81
82
	/**
83
	 *
84
	 */
85 10
	protected function buildFixedNavBarIfRequested() {
86
		// if a fixed navbar is requested
87 10
		if ( filter_var( $this->getDomElement()->getAttribute( 'fixed' ), FILTER_VALIDATE_BOOLEAN ) === true ||
88 10
			$this->getDomElement()->getAttribute( 'position' ) === 'fixed'
89 10
		) {
90
91
			// first build the actual navbar and set a class so it will be fixed
92 1
			$this->getDomElement()->setAttribute( 'fixed', '0' );
93 1
			$this->getDomElement()->setAttribute( 'position', '' );
94
95 1
			$realNav = new self( $this->getSkinTemplate(), $this->getDomElement(), $this->getIndent() );
96 1
			$realNav->setClasses( $this->getClassString() . ' navbar-fixed-top' );
97
98
			// then add an invisible copy of the nav bar that will act as a spacer
99 1
			$this->addClasses( 'navbar-static-top invisible' );
100
101 1
			return $realNav->getHtml();
102
		} else {
103 10
			return '';
104
		}
105
	}
106
107
	/**
108
	 * @return string
109
	 */
110 10
	protected function buildNavBarOpeningTags() {
111
		$openingTags =
112 10
			$this->indent() . '<!-- navigation bar -->' .
113 10
			$this->indent() . \Html::openElement( 'nav', array(
114 10
					'class' => 'navbar navbar-default p-navbar ' . $this->getClassString(),
115 10
					'role'  => 'navigation',
116 10
					'id'    => $this->getHtmlId()
117 10
				)
118 10
			) .
119 10
			$this->indent( 1 ) . '<div class="container-fluid">';
120
121 10
		$this->indent( 1 );
122
123 10
		return $openingTags;
124
	}
125
126
	/**
127
	 * @return string
128
	 */
129 10
	private function getHtmlId() {
130 10
		if ( $this->htmlId === null ) {
131 10
			$this->htmlId = IdRegistry::getRegistry()->getId( 'mw-navigation' );
132 10
		}
133 10
		return $this->htmlId;
134
	}
135
136
	/**
137
	 *
138
	 */
139 10
	protected function buildNavBarComponents() {
140
141 10
		$elements = $this->buildNavBarElementsFromDomTree();
142
143 10
		if ( !empty( $elements[ 'right' ] ) ) {
144
145 4
			$elements[ 'left' ][ ] =
146 4
				$this->indent( 1 ) . '<div class="navbar-right-aligned">' .
147 4
				implode( $elements[ 'right' ] ) .
148 4
				$this->indent() . '</div> <!-- navbar-right-aligned -->';
149
150 4
			$this->indent( -1 );
151 4
		}
152
153
		return
154 10
			$this->buildHead( $elements[ 'head' ] ) .
155 10
			$this->buildTail( $elements[ 'left' ] );
156
	}
157
158
	/**
159
	 * @return string[][]
160
	 */
161 10
	protected function buildNavBarElementsFromDomTree() {
162
163
		$elements = array(
164 10
			'head'  => array(),
165 10
			'left'  => array(),
166 10
			'right' => array(),
167 10
		);
168
169
		/** @var \DOMElement[] $children */
170 10
		$children = $this->getDomElement()->hasChildNodes() ? $this->getDomElement()->childNodes : array();
171
172
		// add components
173 10
		foreach ( $children as $node ) {
174 9
			$this->buildAndCollectNavBarElementFromDomElement( $node, $elements );
175 10
		}
176 10
		return $elements;
177
	}
178
179
	/**
180
	 * @param \DOMElement $node
181
	 * @param $elements
182
	 */
183 9
	protected function buildAndCollectNavBarElementFromDomElement( $node, &$elements ) {
184
185 9
		if ( is_a( $node, 'DOMElement' ) && $node->tagName === 'component' && $node->hasAttribute( 'type' ) ) {
186
187 9
			$position = $node->getAttribute( 'position' );
188
189 9
			if ( !array_key_exists( $position, $elements ) ) {
190 9
				$position = 'left';
191 9
			}
192
193 9
			$indentation = ( $position === 'right' ) ? 2 : 1;
194
195 9
			$this->indent( $indentation );
196 9
			$html = $this->buildNavBarElementFromDomElement( $node );
197 9
			$this->indent( -$indentation );
198
199 9
			$elements[ $position ][ ] = $html;
200
201 9
		} else {
202
			// TODO: Warning? Error?
203
		}
204 9
	}
205
206
	/**
207
	 * @param \DomElement $node
208
	 *
209
	 * @return string
210
	 */
211 9
	protected function buildNavBarElementFromDomElement( $node ) {
212 9
		switch ( $node->getAttribute( 'type' ) ) {
213 9
			case 'Logo':
214 7
				$html = $this->getLogo( $node );
215 7
				break;
216 9
			case 'NavMenu':
217 8
				$html = $this->getNavMenu( $node );
218 8
				break;
219 8
			case 'PageTools':
220 7
				$html = $this->getPageTools( $node );
221 7
				break;
222 8
			case 'SearchBar':
223 7
				$html = $this->getSearchBar( $node );
224 7
				break;
225 8
			case 'PersonalTools':
226 7
				$html = $this->getPersonalTools();
227 7
				break;
228 1
			case 'Menu':
229 1
				$html = $this->getMenu( $node );
230 1
				break;
231
			default:
232
				$html = '';
233 9
		}
234 9
		return $html;
235
	}
236
237
	/**
238
	 * Creates HTML code for the wiki logo in a navbar
239
	 *
240
	 * @param \DOMElement $domElement
241
	 *
242
	 * @return String
243
	 */
244 7 View Code Duplication
	protected function getLogo( \DOMElement $domElement = null ) {
245
246 7
		$logo = new Logo( $this->getSkinTemplate(), $domElement, $this->getIndent() );
247 7
		$logo->addClasses( 'navbar-brand' );
248
249
//        return \Html::rawElement( 'li', array(), $logo->getHtml() );
250 7
		return $logo->getHtml();
251
	}
252
253
	/**
254
	 * Creates a list of navigational links usually found in the sidebar
255
	 *
256
	 * @param \DOMElement $domElement
257
	 *
258
	 * @return string
259
	 */
260 8 View Code Duplication
	protected function getNavMenu( \DOMElement $domElement = null ) {
261
262 8
		$navMenu = new NavMenu( $this->getSkinTemplate(), $domElement, $this->getIndent() );
263
264 8
		return '<ul class="nav navbar-nav">' . $navMenu->getHtml() . "</ul>\n";
265
266
	}
267
268
	/**
269
	 * Create a dropdown containing the page tools (page, talk, edit, history,
270
	 * ...)
271
	 *
272
	 * @param \DOMElement $domElement
273
	 *
274
	 * @return string
275
	 */
276 7
	protected function getPageTools( \DOMElement $domElement = null ) {
277
278 7
		$ret = '';
279
280 7
		$pageTools = new PageTools( $this->getSkinTemplate(), $domElement, $this->getIndent() + 1 );
281
282 7
		$pageTools->setFlat( true );
283 7
		$pageTools->removeClasses( 'text-center list-inline' );
284 7
		$pageTools->addClasses( 'dropdown-menu' );
285
286 7
		$editLinkHtml = $this->getEditLinkHtml( $pageTools );
287
288 7
		$pageToolsHtml = $pageTools->getHtml();
289
290 7
		if ( $editLinkHtml || $pageToolsHtml ) {
291
			$ret =
292 7
				$this->indent() . '<!-- page tools -->' .
293 7
				$this->indent() . '<ul class="navbar-tools navbar-nav" >';
294
295 7
			if ( $editLinkHtml !== '' ) {
296 7
				$ret .= $this->indent( 1 ) . $editLinkHtml;
297 7
			}
298
299 7
			if ( $pageToolsHtml !== '' ) {
300
				$ret .=
301 7
					$this->indent( 1 ) . '<li class="navbar-tools-tools dropdown">' .
302 7
					$this->indent( 1 ) . '<a data-toggle="dropdown" class="dropdown-toggle" href="#" title="' . $this->getSkinTemplate()->getMsg( 'specialpages-group-pagetools' )->text() . '" ><span>...</span></a>' .
303 7
					$pageToolsHtml .
304 7
					$this->indent( -1 ) . '</li>';
305 7
			}
306
307
			$ret .=
308 7
				$this->indent( -1 ) . '</ul>' . "\n";
309 7
		}
310
311 7
		return $ret;
312
	}
313
314
	/**
315
	 * @param \DOMElement $domElement
316
	 *
317
	 * @return string
318
	 */
319 7 View Code Duplication
	protected function getSearchBar( \DOMElement $domElement = null ) {
320
321 7
		$search = new SearchBar( $this->getSkinTemplate(), $domElement, $this->getIndent() );
322 7
		$search->addClasses( 'navbar-form' );
323
324 7
		return $search->getHtml();
325
	}
326
327
	/**
328
	 * Creates a user's personal tools and the newtalk notifier
329
	 *
330
	 * @return string
331
	 */
332 7
	protected function getPersonalTools() {
333
334 7
		$user = $this->getSkinTemplate()->getSkin()->getUser();
335
336 7
		if ( $user->isLoggedIn() ) {
337 2
			$toolsClass = 'navbar-userloggedin';
338 2
			$toolsLinkText = $this->getSkinTemplate()->getMsg( 'chameleon-loggedin' )->params( $user->getName() )->text();
339 2
		} else {
340 5
			$toolsClass = 'navbar-usernotloggedin';
341 5
			$toolsLinkText = $this->getSkinTemplate()->getMsg( 'chameleon-notloggedin' )->text();
342
		}
343
344 7
		$linkText = '<span class="glyphicon glyphicon-user"></span>';
345 7
		\Hooks::run('ChameleonNavbarHorizontalPersonalToolsLinkText', array( &$linkText, $this->getSkin() ) );
346
347
		// start personal tools element
348
		$ret =
349 7
			$this->indent() . '<!-- personal tools -->' .
350 7
			$this->indent() . '<ul class="navbar-tools navbar-nav" >' .
351 7
			$this->indent( 1 ) . '<li class="dropdown navbar-tools-tools">' .
352 7
			$this->indent( 1 ) . '<a class="dropdown-toggle ' . $toolsClass . '" href="#" data-toggle="dropdown" title="' . $toolsLinkText . '" >' . $linkText . '</a>' .
353 7
			$this->indent() . '<ul class="p-personal-tools dropdown-menu dropdown-menu-right" >';
354
355 7
		$this->indent( 1 );
356
357
		// add personal tools (links to user page, user talk, prefs, ...)
358 7 View Code Duplication
		foreach ( $this->getSkinTemplate()->getPersonalTools() as $key => $item ) {
359 7
			$ret .= $this->indent() . $this->getSkinTemplate()->makeListItem( $key, $item );
360 7
		}
361
362
		$ret .=
363 7
			$this->indent( -1 ) . '</ul>' .
364 7
			$this->indent( -1 ) . '</li>';
365
366
		// if the user is logged in, add the newtalk notifier
367 7
		if ( $user->isLoggedIn() ) {
368
369 2
			$newMessagesAlert = '';
370 2
			$newtalks = $user->getNewMessageLinks();
371 2
			$out = $this->getSkinTemplate()->getSkin()->getOutput();
372
373
			// Allow extensions to disable the new messages alert;
374
			// since we do not display the link text, we ignore the actual value returned in $newMessagesAlert
375 2
			if ( Hooks::run( 'GetNewMessagesAlert', array( &$newMessagesAlert, $newtalks, $user, $out ) ) ) {
376
377 2
				if ( count( $user->getNewMessageLinks() ) > 0 ) {
378 1
					$newtalkClass = 'navbar-newtalk-available';
379 1
					$newtalkLinkText = $this->getSkinTemplate()->getMsg( 'chameleon-newmessages' )->text();
380 1
				} else {
381 1
					$newtalkClass = 'navbar-newtalk-not-available';
382 1
					$newtalkLinkText = $this->getSkinTemplate()->getMsg( 'chameleon-nonewmessages' )->text();
383
				}
384
385 2
				$linkText = '<span class="glyphicon glyphicon-envelope"></span>';
386 2
				\Hooks::run('ChameleonNavbarHorizontalNewTalkLinkText', array( &$linkText, $this->getSkin() ) );
387
388 2
				$ret .= $this->indent() . '<li class="navbar-newtalk-notifier">' .
389 2
					$this->indent( 1 ) . '<a class="dropdown-toggle ' . $newtalkClass . '" title="' .
390 2
					$newtalkLinkText . '" href="' . $user->getTalkPage()->getLinkURL( 'redirect=no' ) . '">' . $linkText . '</a>' .
391 2
					$this->indent( -1 ) . '</li>';
392
393 2
			}
394
395 2
		}
396
397 7
		$ret .= $this->indent( -1 ) . '</ul>' . "\n";
398
399 7
		return $ret;
400
	}
401
402
	/**
403
	 * Creates a list of navigational links from a message key or message text
404
	 *
405
	 * @param \DOMElement $domElement
406
	 *
407
	 * @return string
408
	 */
409 1 View Code Duplication
	protected function getMenu( \DOMElement $domElement = null ) {
410
411 1
		$menu = new Menu( $this->getSkinTemplate(), $domElement, $this->getIndent() );
412
413 1
		return '<ul class="nav navbar-nav">' . $menu->getHtml() . "</ul>\n";
414
415
	}
416
417
	/**
418
	 * @param string[] $headElements
419
	 *
420
	 * @return string
421
	 */
422 10
	protected function buildHead( $headElements ) {
423
424
		$head =
425 10
			$this->indent() . "<div class=\"navbar-header\">\n" .
426 10
			$this->indent( 1 ) . "<button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\"#" . $this->getHtmlId() . "-collapse\">" .
427 10
			$this->indent( 1 ) . "<span class=\"sr-only\">Toggle navigation</span>" .
428 10
			$this->indent() . str_repeat( "<span class=\"icon-bar\"></span>", 3 ) .
429 10
			$this->indent( -1 ) . "</button>\n" .
430 10
			implode( '', $headElements ) . "\n" .
431 10
			$this->indent( -1 ) . "</div>\n";
432
433 10
		return $head;
434
	}
435
436
	/**
437
	 * @param string[] $tailElements
438
	 *
439
	 * @return string
440
	 */
441 10
	protected function buildTail( $tailElements ) {
442
443
		return
444 10
			$this->indent() . '<div class="collapse navbar-collapse" id="' . $this->getHtmlId() . '-collapse">' .
445 10
			implode( '', $tailElements ) .
446 10
			$this->indent() . '</div><!-- /.navbar-collapse -->';
447
	}
448
449
	/**
450
	 * @return string
451
	 */
452 10
	protected function buildNavBarClosingTags() {
453
		return
454 10
			$this->indent( -1 ) . '</div>' .
455 10
			$this->indent( -1 ) . '</nav>' . "\n";
456
	}
457
458
	/**
459
	 * @param $pageTools
460
	 * @param $editActionId
461
	 *
462
	 * @return string
463
	 */
464 7
	protected function getLinkAndRemoveFromPageToolStructure( $pageTools, $editActionId ) {
465
466 7
		$pageToolsStructure  = $pageTools->getPageToolsStructure();
467 7
		$editActionStructure = $pageToolsStructure[ 'views' ][ $editActionId ];
468
469 7
		$editActionStructure[ 'text' ] = '';
470
471 7
		if ( array_key_exists( 'class', $editActionStructure ) ) {
472 7
			$editActionStructure[ 'class' ] .= ' navbar-tools-tools';
473 7
		} else {
474
			$editActionStructure[ 'class' ] = 'navbar-tools-tools';
475
		}
476
477
		$options = array (
478
			'text-wrapper' => array(
479 7
				'tag' => 'span',
480 7
				'attributes' => array('class' => 'glyphicon glyphicon-pencil',)
481 7
			),
482 7
		);
483
484 7
		$editLinkHtml = $this->getSkinTemplate()->makeListItem(
485 7
			$editActionId,
486 7
			$editActionStructure,
487
			$options
488 7
		);
489
490 7
		$pageTools->setRedundant( $editActionId );
491
492 7
		return $editLinkHtml;
493
	}
494
495
	/**
496
	 * @param $pageTools
497
	 * @return string
498
	 */
499 7
	protected function getEditLinkHtml( $pageTools ) {
0 ignored issues
show
Coding Style introduced by
getEditLinkHtml uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
500
501 7
		$pageToolsStructure = $pageTools->getPageToolsStructure();
502
503 7
		if ( array_key_exists( 'views', $pageToolsStructure ) &&
504 7
			array_key_exists( 'sfgRenameEditTabs', $GLOBALS ) &&
505 7
			array_key_exists( 'formedit', $pageToolsStructure[ 'views' ] ) && // SemanticForms 3.5+
506
			$GLOBALS[ 'sfgRenameEditTabs' ] === true
507
508 7
		) {
509
510
			$editLinkHtml = $this->getLinkAndRemoveFromPageToolStructure( $pageTools, 'formedit' );
511
			return $editLinkHtml;
512
513 7
		} elseif ( array_key_exists( 'views', $pageToolsStructure ) &&
514 7
			array_key_exists( 'sfgRenameEditTabs', $GLOBALS ) &&
515 7
			array_key_exists( 'form_edit', $pageToolsStructure[ 'views' ] ) && // SemanticForms <3.5
516
			$GLOBALS[ 'sfgRenameEditTabs' ] === true
517
518 7
		) {
519
520
			$editLinkHtml = $this->getLinkAndRemoveFromPageToolStructure( $pageTools, 'form_edit' );
521
			return $editLinkHtml;
522
523 7
		} elseif ( array_key_exists( 'views', $pageToolsStructure ) &&
524 7
			array_key_exists( 've-edit', $pageToolsStructure[ 'views' ] )
525 7
		) {
526
527
			$editLinkHtml = $this->getLinkAndRemoveFromPageToolStructure( $pageTools, 've-edit' );
528
			return $editLinkHtml;
529
530 7
		} elseif ( array_key_exists( 'views', $pageToolsStructure ) &&
531 7
			array_key_exists( 'edit', $pageToolsStructure[ 'views' ] )
532 7
		) {
533
534 7
			$editLinkHtml = $this->getLinkAndRemoveFromPageToolStructure( $pageTools, 'edit' );
535 7
			return $editLinkHtml;
536
537
		}
538
		return '';
539
	}
540
541
}
542