data['namespace_urls'] = $this->data['content_navigation']['namespaces']; $this->data['view_urls'] = $this->data['content_navigation']['views']; $this->data['action_urls'] = $this->data['content_navigation']['actions']; $this->data['variant_urls'] = $this->data['content_navigation']['variants']; $this->data['watch_urls'] = []; if( $GLOBALS['wgNextBestNetworkSkinUseRealnames'] == true && $this->data['username'] ) { $this->data['username'] = NextBestNetworkHooks::getRealname( $this->data['username'] ); } $this->data['advanced'] = MediaWikiServices::getInstance()->getUserOptionsLookup()->getOption( $this->getSkin()->getUser(), 'nextbestnetwork-advanced' ); // Remove the watch/unwatch star from the "actions" menu if ( $this->config->get( 'NextBestNetworkSkinUseIconWatch' ) ) { if ( method_exists( MediaWikiServices::class, 'getWatchlistManager' ) ) { // MediaWiki 1.36+ $watchlistManager = MediaWikiServices::getInstance()->getWatchlistManager(); $watched = $watchlistManager->isWatched( $this->getSkin()->getUser(), $this->getSkin()->getRelevantTitle() ); } else { $watched = $this->getSkin()->getUser()->isWatched( $this->getSkin()->getRelevantTitle() ); } $mode = $watched ? 'unwatch' : 'watch'; if ( isset( $this->data['action_urls'][$mode] ) ) { $this->data['watch_urls'][$mode] = $this->data['action_urls'][$mode]; unset( $this->data['action_urls'][$mode] ); } } $this->data['pageLanguage'] = $this->getSkin()->getTitle()->getPageLanguage()->getHtmlCode(); //set userStateClass if ( $this->data['loggedin'] ) { $this->data['userstateclass'] = "user-loggedin"; } else { $this->data['userstateclass'] = "user-loggedout"; } if ( ( isset( $this->config->get( 'GroupPermissions' )['*']['edit'] ) && $this->config->get( 'GroupPermissions' )['*']['edit'] ) || $this->data['loggedin'] ) { $this->data['userstateclass'] .= " editable"; } else { $this->data['userstateclass'] .= " not-editable"; } //set 'namespace' and 'title_formatted' variables $this->data['title_formatted'] = $this->data['title']; $this->data['namespace'] = str_replace( "_", " ", $this->getSkin()->getTitle()->getNsText() ); // the following is obsolete since MW 1.39, namespace and separator have their own spans if( strpos( $this->data['title_formatted'], $this->data['namespace'] . ':' ) === 0 ) { $this->data['title_formatted'] = '' . $this->data['namespace'] . ": " . str_replace( $this->data['namespace'] . ':', '', $this->data['title_formatted'] ); } call_user_func_array( $this->config->get( 'NextBestNetworkSkinPageRenderer' ), [ $this ] ); ?> getConfig( 'NextBestNetworkSkinGridNone' )['mainoffset']; $main_width = $skin->getConfig( 'NextBestNetworkSkinGridNone' )['mainwidth']; $left_width = 0; $left_offset = 0; $right_width = 0; $right_offset = 0; // TODO: check for situational emptiness of sidebar (e.g. on special pages) if( true ) { $sidebar_left = $skin->checkVisibility( 'sidebar-left' ) && !$skin->checkEmptiness( 'sidebar-left' ); $sidebar_right = $skin->checkVisibility( 'sidebar-right' ) && !$skin->checkEmptiness( 'sidebar-right' ); if( $sidebar_left && $sidebar_right ) { // both sidebars $left_offset = $skin->getConfig( 'NextBestNetworkSkinGridBoth' )['leftoffset']; $left_width = $skin->getConfig( 'NextBestNetworkSkinGridBoth' )['leftwidth']; $main_offset = $skin->getConfig( 'NextBestNetworkSkinGridBoth' )['mainoffset']; $main_width = $skin->config->get( 'NextBestNetworkSkinGridBoth' )['mainwidth']; $right_offset = $skin->getConfig( 'NextBestNetworkSkinGridBoth' )['rightoffset']; $right_width = $skin->getConfig( 'NextBestNetworkSkinGridBoth' )['rightwidth']; } if( $sidebar_left XOR $sidebar_right ) { // only one of the sidebars if( $sidebar_left ) { $left_offset = $skin->getConfig( 'NextBestNetworkSkinGridLeft' )['leftoffset']; $left_width = $skin->getConfig( 'NextBestNetworkSkinGridLeft' )['leftwidth']; $main_offset = $skin->getConfig( 'NextBestNetworkSkinGridLeft' )['mainoffset']; $main_width = $skin->getConfig( 'NextBestNetworkSkinGridLeft' )['mainwidth']; } else { $main_offset = $skin->getConfig( 'NextBestNetworkSkinGridRight' )['mainoffset']; $main_width = $skin->getConfig( 'NextBestNetworkSkinGridRight' )['mainwidth']; $right_offset = $skin->getConfig( 'NextBestNetworkSkinGridRight' )['rightoffset']; $right_width = $skin->getConfig( 'NextBestNetworkSkinGridRight' )['rightwidth']; } } } $contentclass = $skin->data['userstateclass']; $contentclass .= ' ' . wfMessage( 'nextbestnetwork-container-class' )->escaped(); $contentclass .= ( $skin->checkVisibility( 'navbar' ) ) ? ' with-navbar' : ' without-navbar'; if( false !== stripos( wfMessage( 'nextbestnetwork-navbar-class' ), 'fixed' ) ) { $contentclass .= ' with-navbar-fixed'; } $mainclass = 'col-md-' . $main_width; if( $main_offset > 0 ) { $mainclass .= ' offset-md-' . $main_offset; } elseif( $main_width == 12 ) { $mainclass = 'col'; } call_user_func_array( $skin->getConfig( 'NextBestNetworkSkinNavbarRenderer' ), [ $skin ] ); ?>
checkEmptiness( 'subnav' ) ) { $skin->renderSubnav( $mainclass ); } ?>
renderContent(); ?>
checkEmptiness( 'sidebar-left' ) ) { $leftclass = 'col-md-' . $left_width; $skin->renderSidebar( 'left', $leftclass ); } if( !$skin->checkEmptiness( 'sidebar-right' ) ) { $rightclass = 'col-md-' . $right_width; $skin->renderSidebar( 'right', $rightclass ); } ?>
renderFooter(); } public function getConfig( $config ) { return $this->config->get($config); } /** * Render one or more navigations elements by name, automatically reversed by css * when UI is in RTL mode * * @param $elements * @param String $context */ protected function renderNavigation( $elements, $context = '' ) { // If only one element was given, wrap it in an array, allowing more // flexible arguments if ( !is_array( $elements ) ) { $elements = [ $elements ]; // If there's a series of elements, reverse them when in RTL mode } elseif ( $this->data['rtl'] ) { $elements = array_reverse( $elements ); } // Render elements foreach ( $elements as $name => $element ) { if ( !$this->checkVisibility( $element ) ) { return []; } // was this element defined in LocalSettings? if ( isset( $this->config->get( 'NextBestNetworkSkinNavigationalElements' )[ $element ] ) ) { return call_user_func( $this->config->get( 'NextBestNetworkSkinNavigationalElements' )[ $element ], $this, $context ); } // is it a special element with special non-buttonesque rendering? if ( isset( $this->config->get( 'NextBestNetworkSkinSpecialElements' )[ $element ] ) ) { return [ [ 'special' => $element ] ]; } switch ( $element ) { case 'EDIT': $views = $this->data['view_urls']; if(count( $views ) > 0) { unset( $views['view'] ); if( isset( $views['formedit'] ) ) { $link = $views['formedit']; } else { $link = array_shift( $views ); } $link['icon'] = wfMessage( 'nextbestnetwork-edit-icon' )->plain(); $link['text'] = wfMessage( 'nextbestnetwork-edit', $link['text'] )->plain(); unset( $link['class'] ); // interferes with btn classing if( $link['id'] == 'ca-ve-edit' ) { $link['id'] = 'ca-edit'; } return [ $link ]; } return []; break; case 'EDIT-EXT': $views = $this->data['view_urls']; if(count( $views ) > 0) { unset( $views['view'] ); if ( $this->checkVisibility( 'EDIT-EXT-special' ) ) { $items = $views; if(count($this->data['action_urls']) > 0) { $items[] = []; #divider $actions = $this->renderNavigation( 'ACTIONS' ); $items = array_merge( $items, $actions[0]['items'] ); } if( strpos( $context, 'navbar' ) !== false ) { $button = [ 'href' => '#', 'html' => wfMessage( 'nextbestnetwork-edit-ext-nav' )->plain(), 'id' => 'ca-edit-ext', 'items' => $items ]; } else { if( isset( $items['formedit'] ) ) { $link = $items['formedit']; unset( $items['formedit'] ); } else { $link = array_shift( $items ); } $button = [ 'href' => $link['href'], 'href_implicit' => false, 'id' => 'ca-edit', 'icon' => wfMessage( 'nextbestnetwork-edit-ext-icon' )->plain(), 'text' => wfMessage( 'nextbestnetwork-edit-ext', $this->data['namespace'] )->plain(), 'name' => 'ca-edit-ext' ]; if( isset( $items['edit'] ) ) { $items['edit']['id'] = 'ca-edit-source'; } $button['items'] = $items; } } else { $link = array_shift( $views ); $button = [ 'href' => $link['href'], 'id' => 'ca-edit', 'icon' => wfMessage( 'nextbestnetwork-edit-ext-icon' )->plain(), 'text' => wfMessage( 'nextbestnetwork-edit-ext', $this->data['namespace'] )->plain() ]; } return [ $button ]; } return []; break; case 'PAGE': $items = array_merge( $this->data['namespace_urls'], $this->data['view_urls'] ); $text = wfMessage( 'namespaces' ); foreach ( $items as $key => $link ) { if ( array_key_exists( 'context', $link ) && $link['context'] == 'subject' ) { $text = $link['text']; } if (preg_match('/^ca-(view|edit)$/', $link['id'])) { unset( $items[$key] ); } } return [[ 'href' => '#', 'text' => $text, 'id' => 'n-namespaces', 'items' => $items ]]; break; case 'NAMESPACES': $items = $this->data['namespace_urls']; $text = wfMessage( 'namespaces' ); /* foreach ( $items as $key => $link ) { if ( array_key_exists( 'context', $link ) && $link['context'] == 'subject' ) { $text = $link['text']; } if ( array_key_exists( 'attributes', $link ) && false !== strpos( $link['attributes'], 'selected' ) || array_key_exists( 'class', $link ) && false !== strpos( $link['class'], 'selected' ) ) { unset( $items[$key] ); } } */ return [[ 'href' => '#', 'text' => $text, 'id' => 'n-namespaces', 'items' => $items ]]; break; case 'TALK': $items = $this->data['namespace_urls']; foreach ( $items as $key => &$link ) { if( isset( $link['context'] ) ) { $link['icon'] = wfMessage( 'nextbestnetwork-namespace-' . $link['context'] . '-icon' )->plain(); } if ( array_key_exists( 'attributes', $link ) && false !== strpos( $link['attributes'], 'selected' ) || array_key_exists( 'class', $link ) && false !== strpos( $link['class'], 'selected' ) ) { unset( $items[$key] ); } else { unset( $link['class'] ); // interferes with btn classing } } return $items; break; case 'TOOLBOX': $items = array_reverse($this->get('sidebar')['TOOLBOX']); $divideditems = []; $html = (wfMessage( 'nextbestnetwork-toolbox' )->plain() == "") ? wfMessage( 'toolbox' )->plain() : wfMessage( 'nextbestnetwork-toolbox' )->plain(); foreach($items as $key => $item) { if(!isset( $item['text'] ) ) { $item['text'] = wfMessage( isset( $item['msg'] ) ? $item['msg'] : $key )->text(); } if(preg_match( '/specialpages|whatlinkshere/', $key )) { $divideditems[] = []; } $divideditems[$key] = $item; } return [[ 'href' => '#', 'html' => $html, 'id' => 't-tools', 'items' => $divideditems ]]; break; case 'TOOLBOX-EXT': $items = array_reverse($this->get('sidebar')['TOOLBOX']); $divideditems = []; $html = (wfMessage( 'nextbestnetwork-toolbox' )->plain() == "") ? wfMessage( 'toolbox' )->plain() : wfMessage( 'nextbestnetwork-toolbox' )->plain(); foreach($items as $key => $item) { if(!isset( $item['text'] ) ) { $item['text'] = wfMessage( isset( $item['msg'] ) ? $item['msg'] : $key )->text(); } if(preg_match( '/specialpages|whatlinkshere/', $key )) { $divideditems[] = []; } $divideditems[$key] = $item; } $divideditems[] = []; $divideditems['recent'] = [ 'text' => wfMessage( 'recentchanges' )->plain(), 'href' => Title::newFromText( 'Special:RecentChanges' )->getLocalURL(), 'id' => 't-recentchanges', ]; return [[ 'href' => '#', 'html' => $html, 'id' => 't-tools', 'items' => $divideditems ]]; break; case 'VARIANTS': $theMsg = 'variants'; $items = $this->data['variant_urls']; if (count($items) > 0) { return [[ 'href' => '#', 'text' => wfMessage( 'variants' ), 'id' => 'ca-variants', 'items' => $items ]]; } break; case 'VIEWS': $items = $this->data['view_urls']; if (count($items) > 0) { return [[ 'href' => '#', 'text' => wfMessage( 'views' ), 'id' => 'ca-views', 'items' => $items ]]; } break; case 'HISTORY': $button = null; $views = $this->data['view_urls']; if( isset( $views['history'] ) ) { if ( array_key_exists( 'attributes', $views['history'] ) && false !== strpos( $views['history']['attributes'], 'selected' ) || array_key_exists( 'class', $views['history'] ) && false !== strpos( $views['history']['class'], 'selected' ) ) { $button = array_shift( $this->data['namespace_urls'] ); } else { $button = $views['history']; $button['icon'] = wfMessage( 'nextbestnetwork-history-icon' )->plain(); } } if( !is_null( $button ) ) { $button['options'] = [ 'wrapperid' => $button['id'] ]; unset( $button['id'] ); unset( $button['class'] ); return [ $button ]; } break; case 'ACTIONS': $items = array_reverse($this->data['action_urls']); if (count($items) > 0) { return [[ 'href' => '#', 'text' => wfMessage( 'actions' ), 'id' => 'ca-actions', 'items' => $items ]]; } break; case 'WATCH': $button = null; $actions = $this->data['action_urls']; if( isset( $actions['watch'] ) ) { $button = $actions['watch']; } else if( isset( $actions['unwatch'] ) ) { $button = $actions['unwatch']; } if( !is_null( $button ) ) { $button['options'] = [ 'wrapperid' => $button['id'] ]; unset( $button['id'] ); return [ $button ]; } break; case 'ICONWATCH': $button = null; $watch = $this->data['watch_urls']; if( isset( $watch['watch'] ) ) { $button = $watch['watch']; } else if( isset( $watch['unwatch'] ) ) { $button = $watch['unwatch']; } if( !is_null( $button ) ) { $button['class'] .= 'icon'; $button['options'] = [ 'wrapperid' => $button['id'], 'wrapperclass' => 'nav icon' ]; if( strpos( $context, 'nav' ) !== false ) { $button['class'] .= ' nav-link'; $button['options']['wrapperclass'] .= ' nav-item'; } unset( $button['id'] ); return [ $button ]; } break; case 'PERSONAL': $items = $this->getPersonalTools(); $divideditems = []; foreach($items as $key => $item) { if(!isset( $item['text'] ) ) { $item['text'] = wfMessage( isset( $item['msg'] ) ? $item['msg'] : $key )->text(); } if(!isset( $item['href'] ) ) { $item['href'] = $item['links'][0]['href']; } if(preg_match( '/preferences|logout/', $key )) { $divideditems[] = []; } unset( $item['links'] ); $divideditems[$key] = $item; } if ( array_key_exists( 'login', $divideditems ) ) { if( array_key_exists( 'createaccount', $divideditems ) ) { // If ConfirmAccount Extension is used return [ $divideditems['login'], $divideditems['createaccount'] ]; } $divideditems['login']['text'] = wfMessage( 'nextbestnetwork-login' )->plain(); return [ $divideditems['login'] ]; } if ( array_key_exists( 'login-private', $divideditems ) ) { if( array_key_exists( 'createaccount', $divideditems ) ) { // If ConfirmAccount Extension is used return [ $divideditems['login-private'], $divideditems['createaccount'] ]; } $divideditems['login-private']['text'] = wfMessage( 'nextbestnetwork-login' )->plain(); return [ $divideditems['login-private'] ]; } if (count($items) > 0) { $personal = [ 'href' => '#', 'html' => '' . wfMessage( 'nextbestnetwork-personaltools-text', $this->data['username'] )->text() . '', 'icon' => wfMessage( 'nextbestnetwork-personaltools-icon' )->text(), 'id' => 'pt-personaltools', 'items' => $divideditems ]; if( isset( $GLOBALS['wgNextBestNetworkSkinUserImageProperty'] ) && $GLOBALS['wgNextBestNetworkSkinUserImageProperty'] !== false ) { $userImages = \SMW\StoreFactory::getStore()->getPropertyValues( \SMW\DIWikiPage::newFromTitle( $this->getSkin()->getUser()->getUserPage() ), \SMW\DIProperty::newFromUserLabel( $GLOBALS['wgNextBestNetworkSkinUserImageProperty'] ) ); //die(var_dump( \SMW\DIProperty::newFromUserLabel( $GLOBALS['wgNextBestNetworkSkinUserImageProperty'] ) ) ); if ( !empty( $userImages ) ) { $userImage = reset( $userImages ); if ( is_a( $userImage, '\SMW\DIWikiPage' ) && $userImage->getNamespace() === NS_FILE ) { $imagePage = new WikiFilePage( $userImage->getTitle() ); $personal['html'] = ''; unset( $personal['icon'] ); } } } return [$personal]; } break; case 'PERSONAL-EXT': $items = $this->getPersonalTools(); $divideditems = []; foreach($items as $key => $item) { if(!isset( $item['text'] ) ) { $item['text'] = wfMessage( isset( $item['msg'] ) ? $item['msg'] : $key )->text(); } if(!isset( $item['href'] ) ) { $item['href'] = isset( $item['links'][0]['href'] ) ? $item['links'][0]['href'] : ''; } if(preg_match( '/preferences|logout/', $key )) { $divideditems[] = []; } unset( $item['links'] ); $divideditems[$key] = $item; } if ( array_key_exists( 'login', $divideditems ) ) { return [ [ 'special' => 'LOGIN-EXT' ] ]; } if ( array_key_exists( 'login-private', $divideditems ) ) { return [ [ 'special' => 'LOGIN-EXT' ] ]; } if (count($items) > 0) { return [[ 'href' => '#', 'html' => '' . wfMessage( 'nextbestnetwork-personaltools-text', $this->data['username'] )->text() . '', 'icon' => wfMessage( 'nextbestnetwork-personaltools-icon' )->text(), 'id' => 'pt-personaltools-ext', 'items' => $divideditems ]]; } break; case 'LOGIN': $items = $this->getPersonalTools(); if ( array_key_exists( 'login', $items ) ) { if( array_key_exists( 'createaccount', $items ) ) { // If ConfirmAccount Extension is used return [ $items['login'], $items['createaccount'] ]; } $items['login']['links'][0]['text'] = wfMessage( 'nextbestnetwork-login' )->plain(); return [ $items['login'] ]; } if ( array_key_exists( 'login-private', $items ) ) { if( array_key_exists( 'createaccount', $items ) ) { // If ConfirmAccount Extension is used return [ $items['login-private'], $items['createaccount'] ]; } $items['login-private']['links'][0]['text'] = wfMessage( 'nextbestnetwork-login' )->plain(); return [ $items['login-private'] ]; } return []; break; case 'SIDEBAR': $sidebar = []; foreach ( $this->data['sidebar'] as $name => $content ) { if( !in_array( $name , ['TOOLBOX', 'SEARCH', 'LANGUAGES'] ) ) { if ( empty ( $content ) ) { if( strpos( $name, '|' ) !== false ) { $parser = MediaWikiServices::getInstance()->getParserFactory()->create(); $parser->setOutputType(Parser::OT_HTML); $sidebarItem = NextBestNetworkHooks::parseButtonLink( $name, $parser, false ); $sidebar[] = $sidebarItem[0]; continue; } // navigational keywords $navigation = $this->renderNavigation( $name ); if( is_array( $navigation ) ) { if( isset( $navigation[0] ) ) { $sidebar[] = $navigation[0]; } continue; } } $msgObj = wfMessage( $name ); $name = htmlspecialchars( $msgObj->exists() ? $msgObj->text() : $name ); $sidebar[] = [ 'href' => '#', 'text' => $name, 'items' => $content ]; } } return $sidebar; break; case 'LANGUAGES': $items = $this->data['language_urls']; if (is_array($items) && count($items) > 0 && $items) { return [[ 'href' => '#', 'text' => wfMessage( 'otherlanguages' ), 'id' => 'p-otherlanguages', 'items' => $items ]]; } return []; break; default: return $element; break; } } } /** * Check navigational sections for content * * @param $item String */ public function checkEmptiness( $item ) { return wfMessage( 'nextbestnetwork-' . $item )->isDisabled(); } /** * Elements can be hidden for anonymous or logged in users or for everybody who has not opted * to show the advanced features in their preferences * * @param $item String */ public function checkVisibility( $item ) { $hookContainer = MediaWikiServices::getInstance()->getHookContainer(); return ( ( !$this->checkVisibilitySetting( $item, $this->config->get( 'NextBestNetworkSkinHideNonAdvanced' ) ) || $this->data['advanced'] // not hidden for non-advanced OR advanced ) && ( !$this->checkVisibilitySetting( $item, $this->config->get( 'NextBestNetworkSkinHideAnon' ) ) || $this->data['loggedin'] // not hidden for anonymous users OR non-anonymous user ) && ( !$this->checkVisibilitySetting( $item, $this->config->get( 'NextBestNetworkSkinHideLoggedin' ) ) || !$this->data['loggedin'] // not hidden for logged-in users OR anonymous user ) && !$this->checkVisibilitySetting( $item, $this->config->get( 'NextBestNetworkSkinHideAll' ) ) // not hidden for all && !$this->checkVisibilityGroups( $item ) // not hidden for all OR user is in exempted group && false !== $hookContainer->run( 'SkinNextBestNetworkCheckVisibility', [ $this, $item ] ) // not hidden via hook ); } /** * Check if an element has an entry in a configuration option and if it's set to true * (i.e. the element should be hidden) * * @param $item Element to be tested * @param $setting Configuration option to be searched * * @return Boolean returns true, if the element is hidden */ public function checkVisibilitySetting( $item, $setting ) { // this is for backwards compatibility if( in_array( $item, $setting, true ) ) { return true; } if( array_key_exists( $item, $setting ) ) { return $setting[$item] ? true : false; } return false; } /** * Check if an element has an entry in $wgNextBestNetworkSkinExcept or if the user is * in the corresponding group * * @param $item Element to be tested * * @return Boolean returns true, if the element is hidden */ public function checkVisibilityGroups( $item ) { // has the option been used? if( !$this->config->has( 'NextBestNetworkSkinHideExcept' ) ) { return false; } $group_settings = $this->config->get( 'NextBestNetworkSkinHideExcept' ); // has the option been set for this item? if( isset( $group_settings[$item] ) && is_array( $group_settings[$item] ) ) { $userGroupManager = MediaWikiServices::getInstance()->getUserGroupManager(); $groups = $userGroupManager->getUserEffectiveGroups($this->getSkin()->getUser()); // is the user in the exempted group? if( count( array_intersect( $group_settings[$item], $groups ) ) > 0 ) { return false; } return true; } return false; } /** * Get a navigational element's content as defined in the respective message or customized with {{#nextbestnetworknav}} * * @param $item Element whose content should be returned * * @return String Element's content */ public function getNavContent( $item ) { if( isset( $GLOBALS['wgNextBestNetworkSkinCustomNav'][$item] ) ) { return $GLOBALS['wgNextBestNetworkSkinCustomNav'][$item]; } return wfMessage( 'nextbestnetwork-' . $item )->plain(); } /** * Render Subnavigation */ public function renderSubnav() { $options = $this->getParsingOptions( 'subnav' ); if( !wfMessage( 'nextbestnetwork-subnav' )->isDisabled() && $this->checkVisibility( 'subnav' ) ) { ?> getMsg( 'nextbestnetwork-navbar-class' ); if ( $skin->checkVisibility( 'navbar' ) ) { ?>
getParsingOptions( $element ); $options['wrapperclass'] = 'nav-item'; $options['class'] = 'nav-link'; $this->buildItems( $this->getNavContent( $element ), $options, $element ); } /** * Render Sidebar * * @param $side string * @param $class string */ public function renderSidebar( $side, $class = '' ) { $element = 'sidebar-' . $side; $options = $this->getParsingOptions( $element ); $classes = $class; if( wfMessage( 'nextbestnetwork-sidebar-class' )->exists() ) { $classes .= ' ' . $this->getMsg( 'nextbestnetwork-sidebar-class' ); } if( wfMessage( 'nextbestnetwork-' . $element . '-class' )->exists() ) { $classes .= ' ' . $this->getMsg( 'nextbestnetwork-' . $element . '-class' ); } /* TODO: can we move these criteria elsewhere? rather there should be some handling for empty sidebars */ if ( ( true || count( $this->data['view_urls'] ) > 0 || $this->data['isarticle'] ) && $this->checkVisibility( $element ) ) { ?>
buildItems( $this->getNavContent( $element ), $options, $element ); ?>
data['sitenotice'] ) { ?>
html( 'sitenotice' ) ?>
checkVisibility( 'firstHeading' ) ) { ?>

html( 'title_formatted' ) ?>

html( 'prebodyhtml' ) ?>
data['isarticle'] ) { ?>
msg( 'tagline' ) ?>
html( 'userlangattributes' ) ?>>html( 'subtitle' ) ?>
data['undelete'] ) { ?>
html( 'undelete' ) ?>
data['newtalk'] ) { ?>
html( 'newtalk' ) ?>
msg( 'jumpto' ) ?> msg( 'jumptonavigation' ) ?>msg( 'comma-separator' ) ?> msg( 'jumptosearch' ) ?>
html( 'bodycontent' ) ?> data['printfooter'] ) { ?>
html( 'printfooter' ); ?>
data['catlinks'] ) { ?> html( 'catlinks' ); ?> data['dataAfterContent'] ) { ?> html( 'dataAfterContent' ); ?>
html( 'debughtml' ); ?>
getParsingOptions( 'footer' ); if ( $this->checkVisibility( 'footer' ) ) { ?> exists() ) { /* the btnclass option's name for the parser is different */ if( $option === 'btnclass' ) { $option = 'class'; } $options[$option] = $msg->parse(); } } return $options; } /** * Build Items for navbar, subnav, sidebar * * @param $items String * @param $options Array * @param $context String */ public function buildItems( $items, $options, $context ) { $buttons = []; $customItems = []; $navbarItems = preg_split( '/[\n,]/', $items ); foreach( $navbarItems as $navbarItem ) { $navbarItem = trim( $navbarItem ); $navbarItem = $this->renderNavigation( $navbarItem, $context ); if ( is_array( $navbarItem ) ) { $this->renderCustomNavigation( $buttons, $customItems ); if(count($navbarItem) !== 0) { $buttons = array_merge( $buttons, $navbarItem ); } } else { $customItems[] = $navbarItem; } } $this->renderCustomNavigation( $buttons, $customItems ); foreach( $buttons as $button ) { /* standard button rendering */ if( !isset( $button['special'] ) ) { $button_options = []; if( isset( $button['options'] ) ) { $button_options = $button['options']; unset( $button['options'] ); } echo NextBestNetworkHooks::renderButtons( [ $button ], array_merge( $options, $button_options ) ); } /* special cases */ else { call_user_func_array( $this->config->get( 'NextBestNetworkSkinSpecialElements' )[$button['special']], [ $this, $context, $options ] ); } } } /** * Render navigations elements that renderNavigation hasn't dealt with * * @param $buttons array * @param $customItems array */ private function renderCustomNavigation( &$buttons, &$customItems ) { $parser = MediaWikiServices::getInstance()->getParserFactory()->create(); $parser->setOutputType(Parser::OT_HTML); $parser->setOptions( ParserOptions::newFromContext( $this->getSkin()->getContext() ) ); $parser->setTitle( $this->getSkin()->getTitle() ); $parser->clearState(); if( count( $customItems ) !== 0 ) { $newButtons = NextBestNetworkHooks::parseButtons( implode( chr(10), $customItems ), $parser, false ); $buttons = array_merge( $buttons, $newButtons ); $customItems = []; } } /** * Render firstheading */ public function renderFirstHeading( $skin, $context ) { echo '
' . $skin->data[ 'title_formatted' ] . '
'; } /** * Render TOC */ public function renderTOC( $skin, $context ) { if( $context == 'sidebar-left' || $context == 'sidebar-right' ) { echo '
'; } else { echo ''; } } /** * Render logo */ public function renderLogo( $skin, $context ) { $mainPageLink = $skin->data['nav_urls']['mainpage']['href']; $toolTip = Xml::expandAttributes( Linker::tooltipAndAccesskeyAttribs( 'p-logo' ) ); echo ' '; } /** * Render Login-ext */ public function renderLoginExt( $skin, $context ) { SessionManager::getGlobalSession()->persist(); //build path for form action $returntotitle = $skin->getSkin()->getTitle(); $returnto = $returntotitle->getFullText(); if ( $returntotitle->equals( SpecialPage::getTitleFor( 'Userlogin' ) ) || $returntotitle->equals( SpecialPage::getTitleFor( 'Userlogout' ) ) || !$returntotitle->exists() ) { $returnto = Title::newMainPage()->getFullText(); } $returnto = $this->getSkin()->getRequest()->getVal( 'returnto', $returnto ); if ( $this->config->has( 'NextBestNetworkReturnto' ) && $returnto == Title::newMainPage()->getFullText() ) { $returnto = $this->config->get( 'NextBestNetworkReturnto' ); } $action = $GLOBALS['wgScript'] . '?title=Special:UserLogin&action=submitlogin&type=login&returnto=' . $returnto; //create login token if it doesn't exist if( !$this->getSkin()->getRequest()->getSession()->getToken( '', 'login' ) ) $this->getSkin()->getRequest()->getSession()->resetToken( 'login' ); $this->getSkin()->getUser()->setCookies(); $dropdown['class'] = ' dropdown-toggle'; if( strpos( $context, 'navbar' ) === 0 ) { $dropdown['class'] .= ' nav-link'; } $dropdown['data-bs-toggle'] = 'dropdown'; $dropdown['text'] = $this->getMsg( 'nextbestnetwork-login' )->text(); $dropdown['html'] = $dropdown['text'] . ' '; $dropdown['href'] = '#'; $dropdown['type'] = 'button'; $dropdown['id'] = 'n-login-ext'; $renderedDropdown = NextBestNetworkHooks::makeLink( $dropdown); $wrapperclass = ( $context == 'footer' ) ? 'dropup' : 'nav-item dropdown'; echo '
  • ' . $renderedDropdown . '
  • '; /* echo ''; */ } /** * Render search */ public function renderSearch( $skin, $context ) { if( $context == 'subnav' ) { echo '