/** * Get name of the user this page referrs to */ public static function getUserName(Title $title, $namespaces, $fallbackToGlobal = true) { wfProfileIn(__METHOD__); global $wgUser, $wgRequest; $userName = null; if (in_array($title->getNamespace(), $namespaces)) { // get "owner" of this user / user talk / blog page $parts = explode('/', $title->getText()); } else { if ($title->getNamespace() == NS_SPECIAL) { if ($title->isSpecial('Following') || $title->isSpecial('Contributions')) { $target = $wgRequest->getText('target'); if ($target != '') { // /wiki/Special:Contributions?target=FooBar (RT #68323) $parts = array($target); } else { // get user this special page referrs to $parts = explode('/', $wgRequest->getText('title', false)); // remove special page name array_shift($parts); } } } } if (isset($parts[0]) && $parts[0] != '') { //this line was usign urldecode($parts[0]) before, see RT #107278, user profile pages with '+' symbols get 'non-existing' message $userName = str_replace('_', ' ', $parts[0]); } elseif ($fallbackToGlobal) { // fallback value $userName = $wgUser->getName(); } wfProfileOut(__METHOD__); return $userName; }
/** * @param Title|null $title * * @return bool */ public function isInvalidLoginRedirect($title) { return !$title instanceof Title || $title->isSpecial('Userlogout') || $title->isSpecial('Signup') || $title->isSpecial('Connect') || $title->isSpecial('FacebookConnect') || $title->isSpecial('UserLogin'); }
/** * Replace the MediaWiki login/logout links with direct links to SimpleSamlPhp. * This takes away the need to set up a redirect on the special UserLogin and UserLogout pages, * and as a side effect makes redirects after login/logout more predictable. * * @link http://www.mediawiki.org/wiki/Manual:Hooks/PersonalUrls * * @param &$personal_urls array the array of URLs set up so far * @param Title $title the Title object of the current article * * @return boolean|string true on success, false on silent error, string on verbose error */ public static function hookPersonalUrls(array &$personal_urls, Title $title) { if (!self::init()) { return true; } global $wgSamlRequirement; global $wgSamlPostLogoutRedirect; global $wgRequest; if ($wgSamlRequirement >= SAML_LOGIN_ONLY || self::$as->isAuthenticated()) { if (isset($personal_urls['logout'])) { if (isset($wgSamlPostLogoutRedirect)) { $personal_urls['logout']['href'] = self::$as->getLogoutURL($wgSamlPostLogoutRedirect); } elseif ($wgSamlRequirement >= SAML_REQUIRED) { $personal_urls['logout']['href'] = self::$as->getLogoutURL(self::$as->getLoginURL(Title::newMainPage()->getFullUrl())); } else { $personal_urls['logout']['href'] = self::$as->getLogoutURL($personal_urls['logout']['href']); } } if (!self::$as->isAuthenticated()) { foreach (array('login', 'anonlogin') as $link) { if (isset($personal_urls[$link])) { if ($returnTo = $wgRequest->getVal('returnto') && ($page = Title::newFromText($returnTo))) { $url = $page->getFullUrl(); $personal_urls[$link]['href'] = self::$as->getLoginURL($url); } elseif ($title->isSpecial('Userlogout')) { $personal_urls[$link]['href'] = self::$as->getLoginURL(Title::newMainPage()->getFullUrl()); } else { $personal_urls[$link]['href'] = self::$as->getLoginURL(); } } } } } return true; }
/** * Check if we should redirect back to the specified page by comparing it to this black list * @param Title|null $title * @return bool */ private function isInvalidRedirectOnConnect(Title $title = null) { return !$title instanceof Title || $title->isSpecial('Userlogout') || $title->isSpecial('Signup') || $title->isSpecial('UserLogin'); }
/** * @param $html string * @return string */ public function DOMParse($html) { global $wgScript; wfProfileIn(__METHOD__); $html = mb_convert_encoding($html, 'HTML-ENTITIES', "UTF-8"); libxml_use_internal_errors(true); $this->doc = new DOMDocument(); $this->doc->loadHTML('<?xml encoding="UTF-8">' . $html); libxml_use_internal_errors(false); $this->doc->preserveWhiteSpace = false; $this->doc->strictErrorChecking = false; $this->doc->encoding = 'UTF-8'; $itemToRemoveRecords = $this->parseItemsToRemove(); $zeroRatedBannerElement = $this->doc->getElementById('zero-rated-banner'); if (!$zeroRatedBannerElement) { $zeroRatedBannerElement = $this->doc->getElementById('zero-rated-banner-red'); } if ($zeroRatedBannerElement) { self::$zeroRatedBanner = $this->doc->saveXML($zeroRatedBannerElement, LIBXML_NOEMPTYTAG); } if (self::$isBetaGroupMember) { $ptLogout = $this->doc->getElementById('pt-logout'); if ($ptLogout) { $ptLogoutLink = $ptLogout->firstChild; self::$logoutHtml = $this->doc->saveXML($ptLogoutLink, LIBXML_NOEMPTYTAG); } $ptAnonLogin = $this->doc->getElementById('pt-anonlogin'); if (!$ptAnonLogin) { $ptAnonLogin = $this->doc->getElementById('pt-login'); } if ($ptAnonLogin) { $ptAnonLoginLink = $ptAnonLogin->firstChild; if ($ptAnonLoginLink && $ptAnonLoginLink->hasAttributes()) { $ptAnonLoginLinkHref = $ptAnonLoginLink->getAttributeNode('href'); $ptAnonLoginLinkTitle = $ptAnonLoginLink->getAttributeNode('title'); if ($ptAnonLoginLinkTitle) { $ptAnonLoginLinkTitle->nodeValue = self::$messages['mobile-frontend-login']; } if ($ptAnonLoginLinkHref) { $ptAnonLoginLinkHref->nodeValue = str_replace("&", "&", $ptAnonLoginLinkHref->nodeValue); } $ptAnonLoginLinkText = $ptAnonLoginLink->firstChild; if ($ptAnonLoginLinkText) { $ptAnonLoginLinkText->nodeValue = self::$messages['mobile-frontend-login']; } } self::$loginHtml = $this->doc->saveXML($ptAnonLoginLink, LIBXML_NOEMPTYTAG); } } if (self::$title->isSpecial('Userlogin') && self::$isBetaGroupMember) { $userlogin = $this->doc->getElementById('userloginForm'); if ($userlogin && get_class($userlogin) === 'DOMElement') { $firstHeading = $this->doc->getElementById('firstHeading'); if ($firstHeading) { $firstHeading->nodeValue = ''; } } } // Tags // You can't remove DOMNodes from a DOMNodeList as you're iterating // over them in a foreach loop. It will seemingly leave the internal // iterator on the foreach out of wack and results will be quite // strange. Though, making a queue of items to remove seems to work. // For example: if (self::$disableImages == 1) { $itemToRemoveRecords['TAG'][] = "img"; $itemToRemoveRecords['TAG'][] = "audio"; $itemToRemoveRecords['TAG'][] = "video"; $itemToRemoveRecords['CLASS'][] = "thumb tright"; $itemToRemoveRecords['CLASS'][] = "thumb tleft"; $itemToRemoveRecords['CLASS'][] = "thumbcaption"; $itemToRemoveRecords['CLASS'][] = "gallery"; } $tagToRemoveNodeIdAttributeValues = array('zero-language-search'); $domElemsToRemove = array(); foreach ($itemToRemoveRecords['TAG'] as $tagToRemove) { $tagToRemoveNodes = $this->doc->getElementsByTagName($tagToRemove); foreach ($tagToRemoveNodes as $tagToRemoveNode) { $tagToRemoveNodeIdAttributeValue = ''; if ($tagToRemoveNode) { $tagToRemoveNodeIdAttribute = $tagToRemoveNode->getAttributeNode('id'); if ($tagToRemoveNodeIdAttribute) { $tagToRemoveNodeIdAttributeValue = $tagToRemoveNodeIdAttribute->value; } if (!in_array($tagToRemoveNodeIdAttributeValue, $tagToRemoveNodeIdAttributeValues)) { $domElemsToRemove[] = $tagToRemoveNode; } } } } foreach ($domElemsToRemove as $domElement) { $domElement->parentNode->removeChild($domElement); } // Elements with named IDs foreach ($itemToRemoveRecords['ID'] as $itemToRemove) { $itemToRemoveNode = $this->doc->getElementById($itemToRemove); if ($itemToRemoveNode) { $itemToRemoveNode->parentNode->removeChild($itemToRemoveNode); } } // CSS Classes $xpath = new DOMXpath($this->doc); foreach ($itemToRemoveRecords['CLASS'] as $classToRemove) { $elements = $xpath->query('//*[@class="' . $classToRemove . '"]'); foreach ($elements as $element) { $element->parentNode->removeChild($element); } } // Tags with CSS Classes foreach ($itemToRemoveRecords['TAG_CLASS'] as $classToRemove) { $parts = explode('.', $classToRemove); $elements = $xpath->query('//' . $parts[0] . '[@class="' . $parts[1] . '"]'); foreach ($elements as $element) { $removedElement = $element->parentNode->removeChild($element); } } // Handle red links with action equal to edit $redLinks = $xpath->query('//a[@class="new"]'); foreach ($redLinks as $redLink) { // PHP Bug #36795 — Inappropriate "unterminated entity reference" $spanNode = $this->doc->createElement("span", str_replace("&", "&", $redLink->nodeValue)); if ($redLink->hasAttributes()) { $attributes = $redLink->attributes; foreach ($attributes as $i => $attribute) { if ($attribute->name != 'href') { $spanNode->setAttribute($attribute->name, $attribute->value); } } } $redLink->parentNode->replaceChild($spanNode, $redLink); } if (self::$title->isSpecial('Userlogin') && self::$isBetaGroupMember) { if ($userlogin && get_class($userlogin) === 'DOMElement') { $login = $this->renderLogin(); $loginNode = $this->doc->importNode($login, true); $userlogin->appendChild($loginNode); } } $content = $this->doc->getElementById('content'); $contentHtml = $this->doc->saveXML($content, LIBXML_NOEMPTYTAG); if (self::$isMainPage) { $contentHtml = $this->DOMParseMainPage($contentHtml); } $title = htmlspecialchars(self::$title->getText()); $htmlTitle = htmlspecialchars(self::$htmlTitle); if (strlen($contentHtml) > 4000 && $this->contentFormat == 'XHTML' && self::$device['supports_javascript'] === true && empty(self::$search) && !self::$isMainPage) { $contentHtml = $this->headingTransform($contentHtml); } elseif ($this->contentFormat == 'WML') { header('Content-Type: text/vnd.wap.wml'); $contentHtml = $this->headingTransform($contentHtml); // Content removal for WML rendering $elements = array('span', 'div', 'sup', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'sup', 'sub'); foreach ($elements as $element) { $contentHtml = preg_replace('#</?' . $element . '[^>]*>#is', '', $contentHtml); } // Wml for searching $searchWml = '<p><input emptyok="true" format="*M" type="text" name="search" value="" size="16" />' . '<do type="accept" label="' . self::$messages['mobile-frontend-search-submit'] . '">' . '<go href="' . $wgScript . '?title=Special%3ASearch&search=$(search)"></go></do></p>'; $contentHtml = $searchWml . $contentHtml; // Content wrapping $contentHtml = $this->createWMLCard($contentHtml); $applicationWmlTemplate = new ApplicationWmlTemplate(); $options = array('mainPageUrl' => self::$mainPageUrl, 'randomPageUrl' => self::$randomPageUrl, 'dir' => self::$dir, 'code' => self::$code, 'contentHtml' => $contentHtml, 'homeButton' => self::$messages['mobile-frontend-home-button'], 'randomButton' => self::$messages['mobile-frontend-random-button']); $applicationWmlTemplate->setByArray($options); $applicationHtml = $applicationWmlTemplate->getHTML(); } if ($this->contentFormat == 'XHTML' && self::$format != 'json') { if (!empty(self::$displayNoticeId)) { if (intval(self::$displayNoticeId) === 1) { $thanksNoticeTemplate = new ThanksNoticeTemplate(); $thanksNoticeTemplate->set('messages', self::$messages); $noticeHtml = $thanksNoticeTemplate->getHTML(); } } // header( 'Content-Type: application/xhtml+xml; charset=utf-8' ); $searchTemplate = $this->getSearchTemplate(); $searchWebkitHtml = $searchTemplate->getHTML(); $footerTemplate = $this->getFooterTemplate(); $footerHtml = $footerTemplate->getHTML(); $noticeHtml = !empty($noticeHtml) ? $noticeHtml : ''; $applicationTemplate = $this->getApplicationTemplate(); $options = array('noticeHtml' => $noticeHtml, 'htmlTitle' => $htmlTitle, 'searchWebkitHtml' => $searchWebkitHtml, 'contentHtml' => $contentHtml, 'footerHtml' => $footerHtml); $applicationTemplate->setByArray($options); $applicationHtml = $applicationTemplate->getHTML(); } if (self::$format === 'json') { header('Content-Type: application/javascript'); header('Content-Disposition: attachment; filename="data.js";'); $json_data = array(); $json_data['title'] = htmlspecialchars(self::$title->getText()); $json_data['html'] = $contentHtml; $json = FormatJson::encode($json_data); if (!empty(self::$callback)) { $json = urlencode(htmlspecialchars(self::$callback)) . '(' . $json . ')'; } wfProfileOut(__METHOD__); return $json; } wfProfileOut(__METHOD__); return $applicationHtml; }
/** * This hook is called when about to force a redirect to a canonical URL * for a title when we have no other parameters on the URL. * * Return false when we want to prevent the redirect to the canonical URL * for Our404Handler special page * * @see PLATFORM-811 * * @param WebRequest $request * @param Title $title * @param OutputPage $output * @return bool */ public static function onTestCanonicalRedirect(WebRequest $request, Title $title, OutputPage $output) { if ($title->isSpecial(self::NAME)) { return false; } return true; }
function isIgnoredPage(Title $title) { global $wgGoogleUniversalAnalyticsIgnoreNsIDs, $wgGoogleUniversalAnalyticsIgnorePages, $wgGoogleUniversalAnalyticsIgnoreSpecials; $ignoreSpecials = count(array_filter($wgGoogleUniversalAnalyticsIgnoreSpecials, function ($v) use($title) { return $title->isSpecial($v); })) > 0; return $ignoreSpecials || in_array($title->getNamespace(), $wgGoogleUniversalAnalyticsIgnoreNsIDs, true) || in_array($title->getPrefixedText(), $wgGoogleUniversalAnalyticsIgnorePages, true); }
static function isSpecialGoogleSearch(Title $title) { return $title->isSpecial('WRGoogleSearch'); }