/** * Render one or more navigations elements by name, automatically reveresed * when UI is in RTL mode * * @param $elements array */ public function renderNavigation($elements) { global $wgUser, $wgTweekiSkinHideNonAdvanced, $wgParser, $wgTweekiSkinNavigationalElements, $wgTweekiSkinSpecialElements; // If only one element was given, wrap it in an array, allowing more // flexible arguments if (!is_array($elements)) { $elements = array($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 array(); } // was this element defined in LocalSettings? if (isset($wgTweekiSkinNavigationalElements[$element])) { return call_user_func($wgTweekiSkinNavigationalElements[$element], $this); } // is it a special element with special non-buttonesque rendering? if (isset($wgTweekiSkinSpecialElements[$element])) { return array(array('special' => $element)); } switch ($element) { case 'EDIT': $views = $this->data['view_urls']; if (count($views) > 0) { unset($views['view']); $link = array_shift($views); $link['icon'] = 'pencil'; return array($link); } return array(); break; case 'EDIT-EXT': $views = $this->data['view_urls']; if (count($views) > 0) { unset($views['view']); $link = array_shift($views); if ($this->checkVisibility('EDIT-EXT-special')) { $button = array('href' => $link['href'], 'href_implicit' => false, 'id' => 'ca-edit', 'icon' => 'pencil', 'text' => wfMessage('tweeki-edit-ext', $this->data['namespace'])->plain(), 'class' => 'btn-primary btn-edit'); $button['items'] = $views; if (count($this->data['action_urls']) > 0) { $button['items'][] = array(); #divider $actions = $this->renderNavigation('ACTIONS'); $button['items'] = array_merge($button['items'], $actions[0]['items']); } } else { $button = $link; $button['icon'] = 'pencil'; $button['id'] = 'ca-edit'; $button['text'] = wfMessage('tweeki-edit-ext', $this->data['namespace'])->plain(); } return array($button); } return array(); 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 array(array('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')) { unset($items[$key]); } } return array(array('href' => '#', 'text' => $text, 'id' => 'n-namespaces', 'items' => $items)); break; case 'TALK': $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')) { unset($items[$key]); } unset($link['class']); // interferes with btn classing } return $items; break; case 'TOOLBOX': $items = array_reverse($this->getToolbox()); $divideditems = array(); $html = wfMessage('tweeki-toolbox')->plain() == "" ? wfMessage('toolbox')->plain() : wfMessage('tweeki-toolbox')->plain(); foreach ($items as $key => $item) { if (!isset($item['text'])) { $item['text'] = $this->translator->translate(isset($item['msg']) ? $item['msg'] : $key); } if (preg_match('/specialpages|whatlinkshere/', $key)) { $divideditems[] = array(); } $divideditems[$key] = $item; } return array(array('href' => '#', 'html' => $html, 'id' => 't-tools', 'items' => $divideditems)); break; case 'VARIANTS': $theMsg = 'variants'; $items = $this->data['variant_urls']; if (count($items) > 0) { return array(array('href' => '#', 'text' => wfMessage('variants'), 'id' => 'ca-variants', 'items' => $items)); } break; case 'VIEWS': $items = $this->data['view_urls']; if (count($items) > 0) { return array(array('href' => '#', 'text' => wfMessage('views'), 'id' => 'ca-views', 'items' => $items)); } break; case 'ACTIONS': $items = array_reverse($this->data['action_urls']); if (count($items) > 0) { return array(array('href' => '#', 'text' => wfMessage('actions'), 'id' => 'ca-actions', 'items' => $items)); } break; case 'PERSONAL': $items = $this->getPersonalTools(); $divideditems = array(); foreach ($items as $key => $item) { if (!isset($item['text'])) { $item['text'] = $this->translator->translate(isset($item['msg']) ? $item['msg'] : $key); } if (!isset($item['href'])) { $item['href'] = $item['links'][0]['href']; } if (preg_match('/preferences|logout/', $key)) { $divideditems[] = array(); } $divideditems[$key] = $item; } if (array_key_exists('login', $divideditems)) { $divideditems['login']['links'][0]['text'] = wfMessage('tweeki-login')->plain(); return array($divideditems['login']); } if (array_key_exists('anonlogin', $divideditems)) { $divideditems['anonlogin']['links'][0]['text'] = wfMessage('tweeki-login')->plain(); return array($divideditems['anonlogin']); } if (count($items) > 0) { return array(array('href' => '#', 'text' => $this->data['username'], 'icon' => 'user', 'id' => 'pt-personaltools', 'items' => $divideditems)); } break; case 'PERSONAL-EXT': $items = $this->getPersonalTools(); $divideditems = array(); foreach ($items as $key => $item) { if (!isset($item['text'])) { $item['text'] = $this->translator->translate(isset($item['msg']) ? $item['msg'] : $key); } if (!isset($item['href'])) { $item['href'] = $item['links'][0]['href']; } if (preg_match('/preferences|logout/', $key)) { $divideditems[] = array(); } $divideditems[$key] = $item; } if (array_key_exists('login', $divideditems)) { return array(array('special' => 'LOGIN-EXT')); } if (array_key_exists('anonlogin', $divideditems)) { return array(array('special' => 'LOGIN-EXT')); } if (count($items) > 0) { return array(array('href' => '#', 'text' => $this->data['username'], 'icon' => 'user', 'id' => 'pt-personaltools', 'items' => $divideditems)); } break; case 'LOGIN': $items = $this->getPersonalTools(); if (array_key_exists('login', $items)) { $items['login']['links'][0]['text'] = wfMessage('tweeki-login')->plain(); return array($items['login']); } if (array_key_exists('anonlogin', $items)) { $items['anonlogin']['links'][0]['text'] = wfMessage('tweeki-login')->plain(); return array($items['anonlogin']); } return array(); break; case 'SIDEBAR': $sidebar = array(); foreach ($this->data['sidebar'] as $name => $content) { if (empty($content)) { if (strpos($name, '|') !== false) { /* TODO: replace $wgParser with local parser - might not work properly */ $sidebarItem = TweekiHooks::parseButtonLink($name, $wgParser, false); $sidebar[] = $sidebarItem[0]; continue; } // navigational keywords $navigation = $this->renderNavigation($name); if (is_array($navigation)) { $sidebar[] = $navigation[0]; continue; } } $msgObj = wfMessage($name); $name = htmlspecialchars($msgObj->exists() ? $msgObj->text() : $name); $sidebar[] = array('href' => '#', 'text' => $name, 'items' => $content); } return $sidebar; break; case 'LANGUAGES': $items = $this->data['language_urls']; if (count($items) > 0 && $items) { return array(array('href' => '#', 'text' => wfMessage('otherlanguages'), 'id' => 'p-otherlanguages', 'items' => $items)); } return array(); break; default: return $element; break; } } }
/** * Parse specific link * * @param $line string * @param $parser Parser current parser * @param $frame Frame current frame * @return array */ static function parseButtonLink($line, $parser, $frame) { $extraAttribs = array(); $href_implicit = false; $active = false; // semantic queries if (strpos($line, '{{#ask:') === 0) { if ($parser->getTitle() instanceof Title) { $semanticQuery = substr($line, 7, -2); $semanticHitNumber = $parser->recursiveTagParse('{{#ask:' . $semanticQuery . '|format=count}}', false); if (!is_numeric($semanticHitNumber) || $semanticHitNumber < 1) { return array(array('text' => $semanticQuery, 'href' => 'INVALID QUERY')); } $semanticHits = $parser->recursiveTagParse('{{#ask:' . $semanticQuery . '|format=list|link=none}}', false); $semanticHits = explode(',', $semanticHits); $semanticLinks = array(); foreach ($semanticHits as $semanticHit) { $semanticLink = TweekiHooks::parseButtonLink($semanticHit, $parser, $frame); $semanticLinks[] = $semanticLink[0]; } return $semanticLinks; } else { $text = 'broken'; } } $line = explode('|', $line); foreach ($line as &$single_line) { $single_line = trim($single_line); } // is the text explicitly set? $href = $line[0]; if (isset($line[1]) && $line[1] != "") { $text = $line[1]; } else { $href_implicit = true; $text = $line[0]; } // parse text $msgText = wfMessage($text)->inContentLanguage(); if ($msgText->exists()) { $text = $msgText->parse(); } else { if ($parser->getTitle() instanceof Title) { $text = $parser->recursiveTagParse($text, $frame); } else { $text = 'INVALID-TITLE/PARSER-BROKEN'; } } // parse href $msgLink = wfMessage($href)->inContentLanguage(); if ($msgLink->exists()) { $href = $msgLink->parse(); } else { if ($parser->getTitle() instanceof Title) { $href = $parser->replaceVariables($href, $frame); } else { $href = 'INVALID-HREF/PARSER-BROKEN'; } } if (preg_match('/^(?i:' . wfUrlProtocols() . ')/', $href)) { // Parser::getExternalLinkAttribs won't work here because of the Namespace things global $wgNoFollowLinks, $wgNoFollowDomainExceptions; if ($wgNoFollowLinks && !wfMatchesDomainList($href, $wgNoFollowDomainExceptions)) { $extraAttribs['rel'] = 'nofollow'; } global $wgExternalLinkTarget; if ($wgExternalLinkTarget) { $extraAttribs['target'] = $wgExternalLinkTarget; } } else { $title = Title::newFromText($href); if ($title) { if ($title->equals($parser->getTitle())) { $active = true; } $title = $title->fixSpecialName(); $href = $title->getLinkURL(); } else { $href = 'INVALID-TITLE:' . $href; } } if (isset($line[2]) && $line[2] != "") { $extraAttribs['class'] = $line[2]; } $link = array_merge(array('html' => $text, 'href' => $href, 'href_implicit' => $href_implicit, 'id' => 'n-' . Sanitizer::escapeId(strtr($line[0], ' ', '-'), 'noninitial'), 'active' => $active), $extraAttribs); return array($link); }