1 <?php
// @codingStandardsIgnoreLine
3 use MediaWiki\MediaWikiServices
;
4 use MediaWiki\Revision\RevisionRecord
;
6 class LibertyTemplate
extends BaseTemplate
{
10 public function execute() {
11 global $wgLibertyAdSetting, $wgLibertyMobileReplaceAd;
13 $skin = $this->getSkin();
14 $user = $skin->getUser();
15 $request = $skin->getRequest();
16 $action = $request->getVal( 'action', 'view' );
17 $title = $skin->getTitle();
18 $LibertyUserSidebarSettings = $user->getOption( 'liberty-layout-sidebar' );
20 $this->html( 'headelement' );
23 <div
class="nav-wrapper navbar-fixed-top">
24 <?php
$this->navMenu(); ?
>
28 <div
class="content-wrapper">
29 <?php
if ( $LibertyUserSidebarSettings == false ) { ?
>
31 <div
class="liberty-sidebar">
32 <div
class="live-recent-wrapper">
33 <?php
$this->liveRecent(); ?
>
35 <?php
if ( isset( $wgLibertyAdSetting[ 'right' ] ) && $wgLibertyAdSetting[ 'right' ] ) {
36 $this->buildAd( 'right' );
41 <div
class="container-fluid liberty-content">
42 <div
class="liberty-content-header">
44 $this->data
['sitenotice'] &&
45 !$request->getCookie( 'disable-notice' )
47 <div
class="alert alert-dismissible fade in alert-info liberty-notice" role
="alert">
48 <button type
="button" class="close" data
-dismiss
="alert" aria
-label
="Close">
49 <span aria
-hidden
="true">×
;</span
>
51 <?php
$this->html( 'sitenotice' ); ?
>
54 <?php
if ( isset( $wgLibertyAdSetting['header'] ) && $wgLibertyAdSetting['header'] ) {
55 $this->buildAd( 'header' );
57 $this->contentsToolbox(); ?
>
60 <?php
$this->html( 'title' ); ?
>
63 <div
class="contentSub" <?php
$this->html( 'userlangattributes' ); ?
>>
64 <?php
$this->html( 'subtitle' ); ?
>
67 <div
class="liberty-content-main" id
="content">
68 <?php
if ( $this->data
['newtalk'] ) { ?
>
69 <div
class="usermessage"><?php
$this->html( 'newtalk' ) ?
></div
>
71 if ( $this->data
['catlinks'] ) {
72 $this->html( 'catlinks' );
75 <article
class="mw-body-content" id
="mw-content-text">
76 <?php
$this->html( 'bodycontent' ); ?
>
79 if ( isset( $wgLibertyAdSetting['belowarticle'] ) && $wgLibertyAdSetting['belowarticle'] ) {
80 $this->buildAd( 'belowarticle' );
86 <div
class="liberty-footer">
88 if ( $this->data
['dataAfterContent'] ) {
89 $this->html( 'dataAfterContent' );
92 <?php
if ( isset( $wgLibertyAdSetting['bottom'] ) && $wgLibertyAdSetting['bottom'] ) {
93 $this->buildAd( 'bottom' );
95 if ( isset( $wgLibertyMobileReplaceAd ) && $wgLibertyMobileReplaceAd &&
96 isset( $wgLibertyAdSetting[ 'right' ] ) && $wgLibertyAdSetting[ 'right' ] ) { ?
>
97 <div
class="mobile-ads"></div
>
99 <?php
$this->footer(); ?
>
102 <div id
="liberty-bottombtn">
103 <div
class="scroll-button" id
="liberty-scrollup"><i
class="fas fa-angle-up"></i
></div
>
104 <div
class="scroll-button" id
="liberty-scrolldown"><i
class="fas fa-angle-down"></i
></div
>
110 // Only load AdSense JS is ads are enabled in site configuration
111 if ( isset( $wgLibertyAdSetting['client'] ) && $wgLibertyAdSetting['client'] ) {
112 // @codingStandardsIgnoreLine
113 echo( '<script async defer src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>' );
116 <?php
$this->loginModal(); ?
>
119 $this->html( 'debughtml' );
120 echo Html
::closeElement( 'body' );
121 echo Html
::closeElement( 'html' );
126 * Nav menu function, build top menu.
128 protected function navMenu() {
129 $linkRenderer = MediaWikiServices
::getInstance()->getLinkRenderer();
130 $skin = $this->getSkin();
132 <nav
class="navbar navbar-dark">
133 <a
class="navbar-brand" href
="<?php echo Title::newMainPage()->getLocalURL(); ?>"></a
>
134 <ul
class="nav navbar-nav">
135 <li
class="nav-item">
136 <?php
echo $linkRenderer->makeKnownLink(
137 new TitleValue( NS_SPECIAL
, 'Recentchanges' ),
138 // @codingStandardsIgnoreStart
139 new HtmlArmor('<span class="fas fa-sync"></span><span class="hide-title">' . $skin->msg( 'recentchanges' )->plain() . '</span>'),
140 // @codingStandardsIgnoreEnd )
142 'class' => 'nav-link',
143 'title' => Linker
::titleAttrib( 'n-recentchanges', 'withaccess' ),
144 'accesskey' => Linker
::accesskey( 'n-recentchanges' )
147 <li
class="nav-item">
148 <?php
echo $linkRenderer->makeKnownLink(
149 new TitleValue( NS_SPECIAL
, 'Randompage' ),
150 // @codingStandardsIgnoreStart
151 new HtmlArmor('<span class="fa fa-random"></span><span class="hide-title">' . $skin->msg('randompage')->plain() . '</span>'),
152 // @codingStandardsIgnoreEnd
154 'class' => 'nav-link',
155 'title' => Linker
::titleAttrib( 'n-randompage', 'withaccess' ),
156 'accesskey' => Linker
::accesskey( 'n-randompage' )
160 <?php
echo $this->renderPortal( $this->parseNavbar() ); ?
>
162 <?php
$this->loginBox(); ?
>
163 <?php
$this->getNotification(); ?
>
164 <?php
$this->searchBox(); ?
>
170 * Search box function, build top menu's search box.
172 protected function searchBox() {
173 $skin = $this->getSkin();
175 <form action
="<?php $this->text( 'wgScript' ); ?>" id
="searchform" class="form-inline">
176 <input type
="hidden" name
="title" value
="<?php $this->text( 'searchtitle' ); ?>" />
177 <div
class="input-group">
178 <?php
echo $this->makeSearchInput( [ 'class' => 'form-control', 'id' => 'searchInput' ] ); ?
>
179 <span
class="input-group-btn">
181 // @codingStandardsIgnoreStart
183 <button type
="submit" name
="go" value
="<?php echo $skin->msg( 'go' )->plain() ?>"id
="searchGoButton" class="btn btn-secondary" type
="button"><span
class="fa fa-eye"></span
></button
>
184 <button type
="submit" name
="fulltext" value
="<?php echo $skin->msg( 'searchbutton' )->plain() ?>"id
="mw-searchButton" class="btn btn-secondary" type
="button">
185 <span
class="fa fa-search"></span
></button
>
187 // @codingStandardsIgnoreEnd
196 * Login box function, build top menu's login button.
198 protected function loginBox() {
199 global $wgLibertyUseGravatar;
201 $skin = $this->getSkin();
202 $user = $skin->getUser();
203 $linkRenderer = MediaWikiServices
::getInstance()->getLinkRenderer();
205 <div
class="navbar-login">
207 // If the user is logged in...
208 if ( $user->isRegistered() ) {
209 $personalTools = $this->getPersonalTools();
210 // ...and Gravatar is enabled in site config...
211 if ( $wgLibertyUseGravatar ) {
212 // ...and the user has a confirmed email...
213 if ( $user->getEmailAuthenticationTimestamp() ) {
214 // ...then, and only then, build the correct Gravatar URL
215 $email = trim( $user->getEmail() );
216 $email = strtolower( $email );
217 $email = md5( $email ) . '?d=identicon';
219 $email = '00000000000000000000000000000000?d=identicon&f=y';
221 $avatar = Html
::element( 'img', [
222 'class' => 'profile-img',
223 'src' => '//secure.gravatar.com/avatar/' . $email
229 // SocialProfile support
230 if ( class_exists( 'wAvatar' ) ) {
231 $avatar = new wAvatar( $user->getId(), 'm' );
232 $avatar = $avatar->getAvatarURL( [
233 'class' => 'profile-img'
237 <div
class="dropdown login-menu">
238 <a
class="dropdown-toggle" type
="button" id
="login-menu"
239 data
-toggle
="dropdown" aria
-haspopup
="true" aria
-expanded
="false">
240 <?php
echo $avatar; ?
>
242 <div
class="dropdown-menu dropdown-menu-right login-dropdown-menu"
243 aria
-labelledby
="login-menu">
244 <?php
echo $linkRenderer->makeKnownLink(
245 Title
::makeTitle( NS_USER
, $user->getName() ),
248 'id' => 'pt-userpage',
249 'class' => 'dropdown-item',
250 'title' => Linker
::titleAttrib( 'pt-userpage', 'withaccess' ),
251 'accesskey' => Linker
::accesskey( 'pt-userpage' )
254 <div
class="dropdown-divider"></div
>
256 if ( class_exists( 'EchoEvent' ) ) {
259 isset( $personalTools['notifications-alert'] ) &&
260 $personalTools['notifications-alert'] &&
261 isset( $personalTools['notifications-notice'] ) &&
262 $personalTools['notifications-notice']
264 $notiCount = $personalTools['notifications-alert']['links'][0]['data']['counter-num'] +
265 $personalTools['notifications-notice']['links'][0]['data']['counter-num'];
267 echo $linkRenderer->makeKnownLink(
268 new TitleValue( NS_SPECIAL
, 'Notifications' ),
269 $skin->msg( 'notifications' )->plain() . ( $notiCount ?
" ($notiCount)" : '' ),
271 'class' => 'dropdown-item',
272 'title' => $skin->msg( 'tooltip-pt-notifications-notice' )->text()
277 <?php
echo $linkRenderer->makeKnownLink(
278 SpecialPage
::getTitleFor( 'Contributions', $user->getName() ),
279 $skin->msg( 'mycontris' )->plain(),
281 'class' => 'dropdown-item',
282 'title' => Linker
::titleAttrib( 'pt-mycontris', 'withaccess' ),
283 'accesskey' => Linker
::accesskey( 'pt-mycontris' )
286 <?php
echo $linkRenderer->makeKnownLink(
287 Title
::makeTitle( NS_USER_TALK
, $user->getName() ),
288 $skin->msg( 'mytalk' )->plain(),
290 'class' => 'dropdown-item',
291 'title' => Linker
::titleAttrib( 'pt-mytalk', 'withaccess' ),
292 'accesskey' => Linker
::accesskey( 'pt-mytalk' )
295 <?php
echo $linkRenderer->makeKnownLink(
296 SpecialPage
::getTitleFor( 'Watchlist' ),
297 $skin->msg( 'watchlist' )->plain(),
299 'class' => 'dropdown-item',
300 'title' => Linker
::titleAttrib( 'pt-watchlist', 'withaccess' ),
301 'accesskey' => Linker
::accesskey( 'pt-watchlist' )
304 <div
class="dropdown-divider"></div
>
305 <?php
echo $linkRenderer->makeKnownLink(
306 SpecialPage
::getTitleFor( 'Preferences' ),
307 $skin->msg( 'preferences' )->plain(),
309 'class' => 'dropdown-item',
310 'title' => Linker
::titleAttrib( 'pt-preferences', 'withaccess' ),
311 'accesskey' => Linker
::accesskey( 'pt-preferences' )
314 <div
class="dropdown-divider view-logout"></div
>
315 <a href
="<?php echo $personalTools['logout']['links'][0]['href']; ?>"
316 class="dropdown-item view-logout"
317 title
="<?php echo Linker::titleAttrib( 'pt-logout', 'withaccess' ); ?>">
318 <?php
echo $skin->msg( 'logout' )->plain(); ?
></a
>
321 <a href
="<?php echo $personalTools['logout']['links'][0]['href']; ?>"
322 class="hide-logout logout-btn"
323 title
="<?php echo Linker::titleAttrib( 'pt-logout', 'withaccess' ); ?>">
324 <span
class="fa fa-sign-out"></span
></a
>
326 <a href
="#" class="none-outline" data
-toggle
="modal" data
-target
="#login-modal">
327 <span
class="fa fa-sign-in"></span
>
335 * Login model function, build login menu model.
337 protected function loginModal() {
338 $skin = $this->getSkin();
339 $title = $skin->getTitle();
340 $linkRenderer = MediaWikiServices
::getInstance()->getLinkRenderer();
342 // Probably no point in rendering a login window for the users who are
343 // already logged in?
344 if ( $skin->getUser()->isRegistered() ) {
348 // Turn off Continuous Integration warnings about "too long" lines which are
349 // perfectly acceptable in this particular context
350 // @codingStandardsIgnoreStart
352 <div
class="modal fade login-modal" id
="login-modal" tabindex
="-1" role
="dialog" aria
-labelledby
="login-modalLabel" aria
-hidden
="true">
353 <div
class="modal-dialog modal-sm" role
="document">
354 <div
class="modal-content">
355 <div
class="modal-header">
356 <button type
="button" class="close" data
-dismiss
="modal" aria
-label
="Close">
357 <span aria
-hidden
="true">×
;</span
>
359 <h4
class="modal-title"><?php
echo $skin->msg('liberty-login')->plain() ?
></h4
>
361 <div
class="modal-body">
362 <div id
="modal-login-alert" class="alert alert-hidden alert-danger" role
="alert">
364 <form id
="modal-loginform" name
="userlogin" class="modal-loginform" method
="post">
365 <input
class="loginText form-control" id
="wpName1" tabindex
="1" placeholder
="<?php echo $skin->msg('userlogin-yourname-ph')->plain() ?>" value
="" name
="lgname">
366 <label
for="inputPassword" class="sr-only"><?php
echo $skin->msg('userlogin-yourpassword')->plain() ?
></label
>
367 <input
class="loginPassword form-control" id
="wpPassword1" tabindex
="2" placeholder
="<?php echo $skin->msg('userlogin-yourpassword-ph')->plain() ?>" type
="password" name
="lgpassword">
368 <div
class="modal-checkbox">
369 <input name
="lgremember" type
="checkbox" value
="1" id
="lgremember" tabindex
="3">
370 <label
for="lgremember"><?php
echo $skin->msg('liberty-remember')->plain() ?
></label
>
372 <input
class="btn btn-success btn-block" type
="submit" value
="<?php echo $skin->msg('liberty-login-btn')->plain() ?>" tabindex
="4">
373 <?php
echo $linkRenderer->makeKnownLink(
374 SpecialPage
::getTitleFor('Userlogin'),
375 $skin->msg('userlogin-joinproject'),
377 'class' => 'btn btn-primary btn-block',
386 <?php
echo $linkRenderer->makeKnownLink(
387 SpecialPage
::getTitleFor('PasswordReset'),
388 $skin->msg('liberty-forgot-pw')->plain()
391 <?php
echo $linkRenderer->makeKnownLink(
392 SpecialPage
::getTitleFor('Userlogin'),
393 $skin->msg('liberty-login-alter')->plain()
395 <input type
="hidden" name
="action" value
="login" />
396 <input type
="hidden" name
="format" value
="json" />
399 <div
class="modal-footer">
400 <button type
="button" class="btn btn-secondary" data
-dismiss
="modal"><?php
echo $skin->msg('liberty-btn-close')->plain(); ?
></button
>
401 <button type
="button" class="btn btn-primary"><?php
echo $skin->msg('liberty-btn-save-changes')->plain(); ?
></button
>
407 // Turn Continuous Integration stuff back on
408 // @codingStandardsIgnoreEnd
412 * Live recent function, build right side's Recent menus.
414 protected function liveRecent() {
415 global $wgLibertyEnableLiveRC,
417 $wgLibertyLiveRCArticleNamespaces,
418 $wgLibertyLiveRCTalkNamespaces;
419 // Don't bother outputting this if the live RC feature is disabled in
420 // site configuration
421 if ( !$wgLibertyEnableLiveRC ) {
424 $skin = $this->getSkin();
425 $linkRenderer = MediaWikiServices
::getInstance()->getLinkRenderer();
426 $articleNS = implode( "|", $wgLibertyLiveRCArticleNamespaces );
427 $talkNS = implode( "|", $wgLibertyLiveRCTalkNamespaces );
429 <div
class="live-recent" data
-article
-ns
="<?php echo $articleNS ?>"
430 data
-talk
-ns
="<?php echo $talkNS ?>">
431 <div
class="live-recent-header">
432 <ul
class="nav nav-tabs">
433 <li
class="nav-item">
434 <a href
="javascript:" class="nav-link active" id
="liberty-recent-tab1">
435 <?php
echo $skin->msg( 'recentchanges' )->plain() ?
>
438 <li
class="nav-item">
439 <a href
="javascript:" class="nav-link" id
="liberty-recent-tab2">
440 <?php
echo $skin->msg( 'liberty-recent-discussions' )->plain() ?
>
445 <div
class="live-recent-content">
446 <ul
class="live-recent-list" id
="live-recent-list">
447 <?php
echo str_repeat(
448 '<li><span class="recent-item"> </span></li>',
453 <div
class="live-recent-footer">
454 <?php
echo $linkRenderer->makeKnownLink(
455 SpecialPage
::getTitleFor( 'Recentchanges' ),
456 new HtmlArmor( '<span class="label label-info">' .
457 $skin->msg( 'liberty-view-more' )->plain() .
466 * Contents tool box function, build article tool menu that will show at article title right.
468 protected function contentsToolbox() {
469 $skin = $this->getSkin();
470 $user = $skin->getUser();
471 $watchlistManager = MediaWikiServices
::getInstance()->getWatchlistManager();
472 $title = $skin->getTitle();
473 $revid = $skin->getRequest()->getText( 'oldid' );
474 $watched = $watchlistManager->isWatchedIgnoringRights( $user, $skin->getRelevantTitle() ) ?
'unwatch' : 'watch';
475 $editable = isset( $this->data
['content_navigation']['views']['edit'] );
476 $action = $skin->getRequest()->getVal( 'action', 'view' );
477 $permissionManager = MediaWikiServices
::getInstance()->getPermissionManager();
478 $linkRenderer = MediaWikiServices
::getInstance()->getLinkRenderer();
479 if ( $title->getNamespace() != NS_SPECIAL
) {
480 $companionTitle = $title->isTalkPage() ?
$title->getSubjectPage() : $title->getTalkPage();
482 <div
class="content-tools">
483 <div
class="btn-group" role
="group" aria
-label
="content-tools">
485 if ( $action != 'edit' ) {
486 $editIcon = $editable ?
'<i class="fa fa-edit"></i> ' : '<i class="fa fa-lock"></i> ';
487 echo $linkRenderer->makeKnownLink(
489 new HtmlArmor( $editIcon . $skin->msg( 'edit' )->plain() ),
491 'class' => 'btn btn-secondary tools-btn',
493 'title' => Linker
::titleAttrib( 'ca-edit', 'withaccess' ),
494 'accesskey' => Linker
::accesskey( 'ca-edit' )
496 $revid ?
[ 'action' => 'edit', 'oldid' => $revid ] : [ 'action' => 'edit' ]
499 if ( $action == 'edit' ||
$action == 'history' ) {
500 echo $linkRenderer->makeKnownLink(
502 $titlename = $skin->msg( 'article' )->plain(),
504 'class' => 'btn btn-secondary tools-btn',
505 'title' => Linker
::titleAttrib( 'ca-nstab-main', 'withaccess' ),
506 'accesskey' => Linker
::accesskey( 'ca-nstab-main' )
510 if ( $companionTitle && $action != 'edit' ) {
511 if ( $title->isTalkPage() && $action != 'history' ) {
512 $titlename = $skin->msg( 'nstab-main' )->plain();
513 $additionalArrayStuff = [
514 'title' => Linker
::titleAttrib( 'ca-nstab-main', 'withaccess' ),
515 'accesskey' => Linker
::accesskey( 'ca-nstab-main' )
518 $titlename = $skin->msg( 'talk' )->plain();
519 $additionalArrayStuff = [
520 'title' => Linker
::titleAttrib( 'ca-talk', 'withaccess' ),
521 'accesskey' => Linker
::accesskey( 'ca-talk' )
524 echo $linkRenderer->makeKnownLink(
528 'class' => 'btn btn-secondary tools-btn',
529 ] +
$additionalArrayStuff
532 if ( $action != 'history' ) {
533 echo $linkRenderer->makeKnownLink(
535 $skin->msg( 'history' )->plain(),
537 'class' => 'btn btn-secondary tools-btn',
538 'title' => Linker
::titleAttrib( 'ca-history', 'withaccess' ),
539 'accesskey' => Linker
::accesskey( 'ca-history' )
541 [ 'action' => 'history' ]
544 if ( $action == 'view' ) { ?
>
545 <button type
="button" class="btn btn-secondary tools-btn tools-share">
546 <i
class="far fa-share-square"></i
>
547 <?php
echo $skin->msg( 'liberty-share' )->plain() ?
>
551 // @codingStandardsIgnoreStart
553 <button type
="button" class="btn btn-secondary tools-btn dropdown-toggle" data
-toggle
="dropdown" aria
-expanded
="false">
554 <span
class="caret"></span
>
557 // @codingStandardsIgnoreEnd
559 <div
class="dropdown-menu dropdown-menu-right" role
="menu">
561 if ( $title->inNamespaces( NS_USER
, NS_USER_TALK
) ) {
562 // "User contributions" link on user and user talk pages
563 echo $linkRenderer->makeKnownLink(
564 SpecialPage
::getTitleFor( 'Contributions', $title->getText() ),
565 $skin->msg( 'contributions' )->escaped(),
567 'class' => 'dropdown-item',
568 'title' => Linker
::titleAttrib( 't-contributions', 'withaccess' ),
569 'accesskey' => Linker
::accesskey( 't-contributions' )
573 echo $linkRenderer->makeKnownLink(
575 $skin->msg( 'liberty-purge' )->plain(),
577 'class' => 'dropdown-item',
578 'title' => $skin->msg( 'liberty-tooltip-purge' )->plain() . ' [alt+shift+p]',
581 [ 'action' => 'purge' ]
583 echo $linkRenderer->makeKnownLink(
585 $skin->msg( $watched )->plain(),
587 'class' => 'dropdown-item',
588 'title' => Linker
::titleAttrib( 'ca-' . $watched, 'withaccess' ),
589 'accesskey' => Linker
::accesskey( 'ca-' . $watched )
591 [ 'action' => $watched ]
593 echo $linkRenderer->makeKnownLink(
594 SpecialPage
::getTitleFor( 'Whatlinkshere', $title ),
595 $skin->msg( 'whatlinkshere' )->plain(),
597 'class' => 'dropdown-item',
598 'title' => Linker
::titleAttrib( 't-whatlinkshere', 'withaccess' ),
599 'accesskey' => Linker
::accesskey( 't-whatlinkshere' )
602 echo $linkRenderer->makeKnownLink(
604 $skin->msg( 'liberty-info' )->plain(),
606 'class' => 'dropdown-item',
607 'title' => $skin->msg( 'liberty-tooltip-info' )->plain(),
609 [ 'action' => 'info' ]
611 if ( $permissionManager->quickUserCan( 'move', $user, $title ) && $title->exists() ) {
612 echo $linkRenderer->makeKnownLink(
613 SpecialPage
::getTitleFor( 'Movepage', $title ),
614 $skin->msg( 'move' )->plain(),
616 'class' => 'dropdown-item',
617 'title' => Linker
::titleAttrib( 'ca-move', 'withaccess' ),
618 'accesskey' => Linker
::accesskey( 'ca-move' )
622 if ( $permissionManager->quickUserCan( 'protect', $user, $title ) ) { ?
>
623 <div
class="dropdown-divider"></div
>
625 // different labels depending on whether the page is or isn't protected
626 $protectionMsg = $title->isProtected() ?
'unprotect' : 'protect';
627 echo $linkRenderer->makeKnownLink(
629 $skin->msg( $protectionMsg )->plain(),
631 'class' => 'dropdown-item',
632 'title' => Linker
::titleAttrib( 'ca-' . $protectionMsg, 'withaccess' ),
633 'accesskey' => Linker
::accesskey( 'ca-' . $protectionMsg )
635 [ 'action' => 'protect' ]
638 <?php
if ( $permissionManager->quickUserCan( 'delete', $user, $title ) && $title->exists() ) {
640 <div
class="dropdown-divider"></div
>
641 <?php
echo $linkRenderer->makeKnownLink(
643 $skin->msg( 'delete' )->plain(),
645 'class' => 'dropdown-item',
646 'title' => Linker
::titleAttrib( 'ca-delete', 'withaccess' ),
647 'accesskey' => Linker
::accesskey( 'ca-delete' )
649 [ 'action' => 'delete' ]
660 * Footer function, build footer.
662 protected function footer() {
663 foreach ( $this->getFooterLinks() as $category => $links ) { ?
>
664 <ul
class="footer-<?php echo $category; ?>">
665 <?php
foreach ( $links as $link ) { ?
>
666 <li
class="footer-<?php echo $category; ?>-<?php echo $link; ?>">
667 <?php
$this->html( $link ); ?
>
673 $footericons = $this->get( 'footericons' );
674 if ( count( $footericons ) ) {
676 <ul
class="footer-icons">
678 foreach ( $footericons as $blockName => $footerIcons ) {
680 <li
class="footer-<?php echo htmlspecialchars( $blockName ); ?>ico">
682 foreach ( $footerIcons as $icon ) {
683 echo $this->getSkin()->makeFooterIcon( $icon );
690 <li
class="designedbylibre">
691 <a href
="//librewiki.net">
692 <?php
// @codingStandardsIgnoreLine
694 <img src
="<?php echo $this->getSkin()->getConfig()->get( 'StylePath' ); //phpcs:ignore
695 ?>/Liberty/img/designedbylibre.png" style
="height:31px" alt
="Designed by Librewiki">
704 * Get Notification function, build notification menu.
706 protected function getNotification() {
707 $personalTools = $this->getPersonalTools();
709 isset( $personalTools['notifications-alert'] ) &&
710 $personalTools['notifications-alert']['links'][0]['data']['counter-num']
712 echo $this->makeListItem( 'notifications-alert', $personalTools['notifications-alert'] );
715 isset( $personalTools['notifications-notice'] ) &&
716 $personalTools['notifications-notice']['links'][0]['data']['counter-num']
718 echo $this->makeListItem( 'notifications-notice', $personalTools['notifications-notice'] );
723 * Render Portal function, build top menu contents.
725 * @param array $contents Menu data that will made by parseNavbar function.
727 protected function renderPortal( $contents ) {
728 $skin = $this->getSkin();
729 $user = $skin->getUser();
730 $userGroup = $user->getGroups();
731 $userRights = MediaWikiServices
::getInstance()->getPermissionManager()->getUserPermissions( $user );
733 foreach ( $contents as $content ) {
737 if ( ( $content['right'] && !in_array( $content['right'], $userRights ) ) ||
738 ( $content['group'] && !in_array( $content['group'], $userGroup ) )
743 echo Html
::openElement( 'li', [
744 'class' => [ 'dropdown', 'nav-item' ]
747 array_push( $content['classes'], 'nav-link' );
749 if ( is_array( $content['children'] ) && count( $content['children'] ) > 1 ) {
750 array_push( $content['classes'], 'dropdown-toggle', 'dropdown-toggle-fix' );
753 echo Html
::openElement( 'a', [
754 'class' => $content['classes'],
755 'data-toggle' => is_array( $content['children'] ) &&
756 count( $content['children'] ) > 1 ?
'dropdown' : '',
758 'aria-haspopup' => 'true',
759 'aria-expanded' => 'true',
760 'title' => $content['title'],
761 'href' => $content['href']
764 if ( isset( $content['icon'] ) ) {
765 echo Html
::rawElement( 'span', [
766 'class' => 'fa fa-' . $content['icon']
770 if ( isset( $content['text'] ) ) {
771 echo Html
::rawElement( 'span', [
772 'class' => 'hide-title'
773 ], $content['text'] );
776 echo Html
::closeElement( 'a' );
778 if ( is_array( $content['children'] ) && count( $content['children'] ) ) {
779 echo Html
::openElement( 'div', [
780 'class' => 'dropdown-menu',
784 foreach ( $content['children'] as $child ) {
785 if ( ( $child['right'] && !in_array( $child['right'], $userRights ) ) ||
786 ( $child['group'] && !in_array( $child['group'], $userGroup ) )
790 array_push( $child['classes'], 'dropdown-item' );
792 if ( is_array( $child['children'] ) ) {
793 array_push( $child['classes'], 'dropdown-toggle', 'dropdown-toggle-sub' );
796 echo Html
::openElement( 'a', [
797 'accesskey' => $child['access'],
798 'class' => $child['classes'],
799 'href' => $child['href'],
800 'title' => $child['title']
803 if ( isset( $child['icon'] ) ) {
804 echo Html
::rawElement( 'span', [
805 'class' => 'fa fa-' . $child['icon']
809 if ( isset( $child['text'] ) ) {
813 echo Html
::closeElement( 'a' );
816 is_array( $content['children'] ) &&
817 count( $content['children'] ) > 2 &&
818 !empty( $child['children'] )
820 echo Html
::openElement( 'div', [
821 'class' => 'dropdown-menu dropdown-submenu',
825 foreach ( $child['children'] as $sub ) {
826 if ( ( $sub['right'] && !in_array( $sub['right'], $userRights ) ) ||
827 ( $sub['group'] && !in_array( $sub['group'], $userGroup ) )
831 array_push( $sub['classes'], 'dropdown-item' );
833 echo Html
::openElement( 'a', [
834 'accesskey' => $sub['access'],
835 'class' => $sub['classes'],
836 'href' => $sub['href'],
837 'title' => $sub['title']
840 if ( isset( $sub['icon'] ) ) {
841 echo Html
::rawElement( 'span', [
842 'class' => 'fa fa-' . $sub['icon']
846 if ( isset( $sub['text'] ) ) {
850 echo Html
::closeElement( 'a' );
853 echo Html
::closeElement( 'div' );
857 echo Html
::closeElement( 'div' );
860 echo Html
::closeElement( 'li' );
865 * Parse [[MediaWiki:Liberty-Navbar]].
868 * * <icon name>|Name of the menu displayed to the user
869 * ** link target|Link title (can be the name of an interface message)
871 * @return array Menu data
873 protected function parseNavbar() {
874 global $wgArticlePath;
877 $currentHeading = null;
878 $userName = $this->getSkin()->getUser()->getName();
879 $userLang = $this->getSkin()->getLanguage()->mCode
;
880 $globalData = ContentHandler
::getContentText( WikiPage
::factory(
881 Title
::newFromText( 'Liberty-Navbar', NS_MEDIAWIKI
)
882 )->getContent( RevisionRecord
::RAW
) );
883 $globalLangData = ContentHandler
::getContentText( WikiPage
::factory(
884 Title
::newFromText( 'Liberty-Navbar/' . $userLang, NS_MEDIAWIKI
)
885 )->getContent( RevisionRecord
::RAW
) );
886 $userData = ContentHandler
::getContentText( WikiPage
::factory(
887 Title
::newFromText( $userName . '/Liberty-Navbar', NS_USER
)
888 )->getContent( RevisionRecord
::RAW
) );
889 if ( !empty( $userData ) ) {
891 } elseif ( !empty( $globalLangData ) ) {
892 $data = $globalLangData;
896 // Well, [[MediaWiki:Liberty-Navbar]] *should* have some content, but
897 // if it doesn't, bail out here so that we don't trigger E_NOTICEs
898 // about undefined indexes later on
899 if ( empty( $data ) ) {
903 $lines = explode( "\n", $data );
905 $types = [ 'icon', 'display', 'title', 'link', 'access', 'class' ];
907 foreach ( $lines as $line ) {
908 $line = rtrim( $line, "\r" );
909 if ( $line[0] !== '*' ) {
910 // Line does not start with '*'
913 if ( $line[1] !== '*' ) {
916 $split = explode( '|', $line );
917 $split[0] = substr( $split[0], 1 );
918 foreach ( $split as $key => $value ) {
919 $valueArr = explode( '=', trim( $value ) );
920 if ( isset( $valueArr[1] ) ) {
921 $data[$valueArr[0]] = $valueArr[1];
923 $data[$types[$key]] = trim( $value );
928 $icon = isset( $data['icon'] ) ?
htmlentities( $data['icon'], ENT_QUOTES
, 'UTF-8' ) : null;
931 $group = isset( $data['group'] ) ?
htmlentities( $data['group'], ENT_QUOTES
, 'UTF-8' ) : null;
934 $right = isset( $data['right'] ) ?
htmlentities( $data['right'], ENT_QUOTES
, 'UTF-8' ) : null;
936 // support the usual [[MediaWiki:Sidebar]] syntax of
937 // ** link target|<some MW: message name> and if the
938 // thing on the right side of the pipe isn't the name of a MW:
939 // message, then and _only_ then render it as-is
940 if ( isset( $data['display'] ) ) {
941 $textObj = wfMessage( $data['display'] );
942 if ( $textObj->isDisabled() ) {
943 $text = htmlentities( $data['display'], ENT_QUOTES
, 'UTF-8' );
945 $text = $textObj->text();
951 // If icon and text both empty
952 if ( empty( $icon ) && empty( $text ) ) {
957 if ( isset( $data['title'] ) ) {
958 $titleObj = wfMessage( $data['title'] );
959 if ( $titleObj->isDisabled() ) {
960 $title = htmlentities( $data['title'], ENT_QUOTES
, 'UTF-8' );
962 $title = $titleObj->text();
969 if ( isset( $data['link'] ) ) {
970 // @todo CHECKME: Should this use wfUrlProtocols() or somesuch instead?
971 if ( preg_match( '/^((?:(?:http(?:s)?)?:)?\/\/(?:.{4,}))$/i', $data['link'] ) ) {
972 $href = htmlentities( $data['link'], ENT_QUOTES
, 'UTF-8' );
974 $href = str_replace( '%3A', ':', urlencode( $data['link'] ) );
975 $href = str_replace( '$1', $href, $wgArticlePath );
981 if ( isset( $data['access'] ) ) {
983 $access = preg_match( '/^([0-9a-z]{1})$/i', $data['access'] ) ?
$data['access'] : '';
988 if ( isset( $data['class'] ) ) {
990 $classes = explode( ',', htmlentities( $data['class'], ENT_QUOTES
, 'UTF-8' ) );
991 foreach ( $classes as $key => $value ) {
992 $classes[$key] = trim( $value );
1000 'classes' => $classes,
1008 $level2Children = &$item['children'];
1009 $headings[] = $item;
1012 if ( $line[2] !== '*' ) {
1013 // Second level menu
1015 $split = explode( '|', $line );
1016 $split[0] = substr( $split[0], 2 );
1017 foreach ( $split as $key => $value ) {
1018 $valueArr = explode( '=', trim( $value ) );
1019 if ( isset( $valueArr[1] ) ) {
1020 $data[$valueArr[0]] = $valueArr[1];
1022 $data[$types[$key]] = trim( $value );
1027 $icon = isset( $data['icon'] ) ?
htmlentities( $data['icon'], ENT_QUOTES
, 'UTF-8' ) : null;
1030 $group = isset( $data['group'] ) ?
htmlentities( $data['group'], ENT_QUOTES
, 'UTF-8' ) : null;
1033 $right = isset( $data['right'] ) ?
htmlentities( $data['right'], ENT_QUOTES
, 'UTF-8' ) : null;
1035 // support the usual [[MediaWiki:Sidebar]] syntax of
1036 // ** link target|<some MW: message name> and if the
1037 // thing on the right side of the pipe isn't the name of a MW:
1038 // message, then and _only_ then render it as-is
1039 if ( isset( $data['display'] ) ) {
1040 $textObj = wfMessage( $data['display'] );
1041 if ( $textObj->isDisabled() ) {
1042 $text = htmlentities( $data['display'], ENT_QUOTES
, 'UTF-8' );
1044 $text = $textObj->text();
1050 // If icon and text both empty
1051 if ( empty( $icon ) && empty( $text ) ) {
1056 if ( isset( $data['title'] ) ) {
1057 $titleObj = wfMessage( $data['title'] );
1058 if ( $titleObj->isDisabled() ) {
1059 $title = htmlentities( $data['title'], ENT_QUOTES
, 'UTF-8' );
1061 $title = $titleObj->text();
1067 if ( isset( $data['link'] ) ) {
1069 // @todo CHECKME: Should this use wfUrlProtocols() or somesuch instead?
1070 if ( preg_match( '/^((?:(?:http(?:s)?)?:)?\/\/(?:.{4,}))$/i', $data['link'] ) ) {
1071 $href = htmlentities( $data['link'], ENT_QUOTES
, 'UTF-8' );
1073 $href = str_replace( '%3A', ':', urlencode( $data['link'] ) );
1074 $href = str_replace( '$1', $href, $wgArticlePath );
1078 if ( isset( $data['access'] ) ) {
1080 $access = preg_match( '/^([0-9a-z]{1})$/i', $data['access'] ) ?
$data['access'] : '';
1085 if ( isset( $data['class'] ) ) {
1087 $classes = explode( ',', htmlentities( $data['class'], ENT_QUOTES
, 'UTF-8' ) );
1088 foreach ( $classes as $key => $value ) {
1089 $classes[$key] = trim( $value );
1096 'access' => $access,
1097 'classes' => $classes,
1105 $level3Children = &$item['children'];
1106 $level2Children[] = $item;
1109 if ( $line[3] !== '*' ) {
1112 $split = explode( '|', $line );
1113 $split[0] = substr( $split[0], 3 );
1114 foreach ( $split as $key => $value ) {
1115 $valueArr = explode( '=', trim( $value ) );
1116 if ( isset( $valueArr[1] ) ) {
1117 $data[$valueArr[0]] = $valueArr[1];
1119 $data[$types[$key]] = trim( $value );
1124 $icon = isset( $data['icon'] ) ?
htmlentities( $data['icon'], ENT_QUOTES
, 'UTF-8' ) : null;
1127 $group = isset( $data['group'] ) ?
htmlentities( $data['group'], ENT_QUOTES
, 'UTF-8' ) : null;
1130 $right = isset( $data['right'] ) ?
htmlentities( $data['right'], ENT_QUOTES
, 'UTF-8' ) : null;
1132 // support the usual [[MediaWiki:Sidebar]] syntax of
1133 // ** link target|<some MW: message name> and if the
1134 // thing on the right side of the pipe isn't the name of a MW:
1135 // message, then and _only_ then render it as-is
1136 if ( isset( $data['display'] ) ) {
1137 $textObj = wfMessage( $data['display'] );
1138 if ( $textObj->isDisabled() ) {
1139 $text = htmlentities( $data['display'], ENT_QUOTES
, 'UTF-8' );
1141 $text = $textObj->text();
1147 // If icon and text both empty
1148 if ( empty( $icon ) && empty( $text ) ) {
1153 if ( isset( $data['title'] ) ) {
1154 $titleObj = wfMessage( $data['title'] );
1155 if ( $titleObj->isDisabled() ) {
1156 $title = htmlentities( $data['title'], ENT_QUOTES
, 'UTF-8' );
1158 $title = $titleObj->text();
1165 // @todo CHECKME: Should this use wfUrlProtocols() or somesuch instead?
1166 if ( preg_match( '/^((?:(?:http(?:s)?)?:)?\/\/(?:.{4,}))$/i', $data['link'] ) ) {
1167 $href = htmlentities( $data['link'], ENT_QUOTES
, 'UTF-8' );
1169 $href = str_replace( '%3A', ':', urlencode( $data['link'] ) );
1170 $href = str_replace( '$1', $href, $wgArticlePath );
1174 if ( isset( $data['access'] ) ) {
1175 $access = preg_match( '/^([0-9a-z]{1})$/i', $data['access'] ) ?
$data['access'] : '';
1180 if ( isset( $data['class'] ) ) {
1182 $classes = explode( ',', htmlentities( $data['class'], ENT_QUOTES
, 'UTF-8' ) );
1183 foreach ( $classes as $key => $value ) {
1184 $classes[$key] = trim( $value );
1191 'access' => $access,
1192 'classes' => $classes,
1200 $level3Children[] = $item;
1212 * Build an AdSense ad unit wrapped in a div tag.
1214 * @param string $position Ad position
1216 protected function buildAd( $position ) {
1217 global $wgLibertyAdSetting;
1220 $fullWidthResponsive = 'true';
1221 if ( $position === 'header' ) {
1222 $adFormat = 'horizontal';
1223 $fullWidthResponsive = 'false';
1226 <div
class="<?php echo $position; ?>-ads">
1227 <ins
class="adsbygoogle"
1228 data
-full
-width
-responsive
="<?php echo $fullWidthResponsive; ?>"
1229 data
-ad
-client
="<?php echo $wgLibertyAdSetting['client']; ?>"
1230 data
-ad
-slot
="<?php echo $wgLibertyAdSetting[$position]; ?>"
1231 data
-ad
-format
="<?php echo $adFormat; ?>">