/** * @since 1.9 * * @return true */ public function process() { $applicationFactory = ApplicationFactory::getInstance(); // Delete all data for a non-enabled target NS if (!$applicationFactory->getNamespaceExaminer()->isSemanticEnabled($this->newTitle->getNamespace()) || $this->newId == 0) { $applicationFactory->getStore()->deleteSubject($this->oldTitle); } else { // Using a different approach since the hook is not triggered // by #REDIRECT which can cause inconsistencies // @see 2.3 / StoreUpdater // $applicationFactory->getStore()->changeTitle( // $this->oldTitle, // $this->newTitle, // $this->oldId, // $this->newId // ); } $eventHandler = EventHandler::getInstance(); $dispatchContext = $eventHandler->newDispatchContext(); $dispatchContext->set('title', $this->oldTitle); $eventHandler->getEventDispatcher()->dispatch('cached.propertyvalues.prefetcher.reset', $dispatchContext); $dispatchContext = $eventHandler->newDispatchContext(); $dispatchContext->set('title', $this->newTitle); $eventHandler->getEventDispatcher()->dispatch('cached.propertyvalues.prefetcher.reset', $dispatchContext); return true; }
/** * 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; }
/** * @return bool|int|null */ protected function saveContent() { global $wgLogRestrictions; $dbw = wfGetDB(DB_MASTER); $log_id = $dbw->nextSequenceValue('logging_log_id_seq'); $this->timestamp = $now = wfTimestampNow(); $data = array('log_id' => $log_id, 'log_type' => $this->type, 'log_action' => $this->action, 'log_timestamp' => $dbw->timestamp($now), 'log_user' => $this->doer->getId(), 'log_user_text' => $this->doer->getName(), 'log_namespace' => $this->target->getNamespace(), 'log_title' => $this->target->getDBkey(), 'log_page' => $this->target->getArticleId(), 'log_comment' => $this->comment, 'log_params' => $this->params); $dbw->insert('logging', $data, __METHOD__); $newId = !is_null($log_id) ? $log_id : $dbw->insertId(); # And update recentchanges if ($this->updateRecentChanges) { $titleObj = SpecialPage::getTitleFor('Log', $this->type); RecentChange::notifyLog($now, $titleObj, $this->doer, $this->getRcComment(), '', $this->type, $this->action, $this->target, $this->comment, $this->params, $newId); } elseif ($this->sendToUDP) { # Don't send private logs to UDP if (isset($wgLogRestrictions[$this->type]) && $wgLogRestrictions[$this->type] != '*') { return true; } # Notify external application via UDP. # We send this to IRC but do not want to add it the RC table. $titleObj = SpecialPage::getTitleFor('Log', $this->type); $rc = RecentChange::newLogEntry($now, $titleObj, $this->doer, $this->getRcComment(), '', $this->type, $this->action, $this->target, $this->comment, $this->params, $newId); $rc->notifyRC2UDP(); } return $newId; }
/** @brief Allows to edit or not archived talk pages and its subpages * * @author Andrzej 'nAndy' Łukaszewski * * @param $pernErrors * @param Title $title * * @return boolean true -- because it's a hook */ public function onAfterEditPermissionErrors($permErrors, $title, $removeArray) { $app = F::App(); if (empty($app->wg->EnableWallExt) && ($title->getNamespace() == NS_USER_WALL || $title->getNamespace() == NS_USER_WALL_MESSAGE || $title->getNamespace() == NS_USER_WALL_MESSAGE_GREETING)) { $permErrors[] = array(0 => 'protectedpagetext', 1 => 'archived'); } return true; }
/** * Initialize from a Title and if possible initializes a corresponding * Revision and File. * * @param Title $title */ protected function initFromTitle($title) { $this->mTitle = $title; if (!is_null($this->mTitle)) { $id = false; wfRunHooks('SearchResultInitFromTitle', array($title, &$id)); $this->mRevision = Revision::newFromTitle($this->mTitle, $id, Revision::READ_NORMAL); if ($this->mTitle->getNamespace() === NS_FILE) { $this->mImage = wfFindFile($this->mTitle); } } }
/** * Initialize from a Title and if possible initializes a corresponding * Revision and File. * * @param Title $title */ protected function initFromTitle($title) { $this->mTitle = $title; if (!is_null($this->mTitle)) { $id = false; Hooks::run('SearchResultInitFromTitle', [$title, &$id]); $this->mRevision = Revision::newFromTitle($this->mTitle, $id, Revision::READ_NORMAL); if ($this->mTitle->getNamespace() === NS_FILE) { $this->mImage = wfFindFile($this->mTitle); } } $this->searchEngine = MediaWikiServices::getInstance()->newSearchEngine(); }
/** * Check if the given local page title is a spam regex source. * @param Title $title * @return bool */ function isLocalSource($title) { global $wgDBname; if ($title->getNamespace() == NS_MEDIAWIKI) { $sources = array("Spam-blacklist", "Spam-whitelist"); if (in_array($title->getDBkey(), $sources)) { return true; } } $thisHttp = wfExpandUrl($title->getFullUrl('action=raw'), PROTO_HTTP); $thisHttpRegex = '/^' . preg_quote($thisHttp, '/') . '(?:&.*)?$/'; foreach ($this->files as $fileName) { $matches = array(); if (preg_match('/^DB: (\\w*) (.*)$/', $fileName, $matches)) { if ($wgDBname == $matches[1]) { if ($matches[2] == $title->getPrefixedDbKey()) { // Local DB fetch of this page... return true; } } } elseif (preg_match($thisHttpRegex, $fileName)) { // Raw view of this page return true; } } return false; }
function fnForumIndexProtector(Title &$title, User &$user, $action, &$result) { if ($user->isLoggedIn()) { #this doesnt apply to logged in users, bail, but keep going return true; } if ($action != 'edit' && $action != 'create') { #only kill editing actions (what else can anons even do?), bail, but keep going return true; } #this only applies to Forum:Index and Forum_talk:Index #check pagename if ($title->getText() != 'Index') { #wrong pagename, bail, but keep going return true; } $ns = $title->getNamespace(); #check namespace(s) if ($ns == NS_FORUM || $ns == NS_FORUM_TALK) { #bingo bango, its a match! $result = array('protectedpagetext'); Wikia::log(__METHOD__, __LINE__, "anon trying to edit forum:index, killing request"); #bail, and stop the request return false; } return true; }
/** * Determine which FilePage to show based on skin and File type (image/video) * * @param Title $oTitle * @param Article $oArticle * @return bool true */ public static function onArticleFromTitle(&$oTitle, &$oArticle) { if ($oTitle instanceof Title && $oTitle->getNamespace() == NS_FILE) { $oArticle = WikiaFileHelper::getMediaPage($oTitle); } return true; }
/** * Target URL for a link provided by a support button/aid. * * @param $title Title Title object for the translation message. * @since 2015.09 */ public static function getSupportUrl(Title $title) { global $wgTranslateSupportUrl, $wgTranslateSupportUrlNamespace; $namespace = $title->getNamespace(); // Fetch the configuration for this namespace if possible, or the default. if (isset($wgTranslateSupportUrlNamespace[$namespace])) { $config = $wgTranslateSupportUrlNamespace[$namespace]; } elseif ($wgTranslateSupportUrl) { $config = $wgTranslateSupportUrl; } else { throw new TranslationHelperException("Support page not configured"); } // Preprocess params $params = array(); if (isset($config['params'])) { foreach ($config['params'] as $key => $value) { $params[$key] = str_replace('%MESSAGE%', $title->getPrefixedText(), $value); } } // Return the URL or make one from the page if (isset($config['url'])) { return wfAppendQuery($config['url'], $params); } elseif (isset($config['page'])) { $page = Title::newFromText($config['page']); if (!$page) { throw new TranslationHelperException("Support page not configured properly"); } return $page->getFullUrl($params); } else { throw new TranslationHelperException("Support page not configured properly"); } }
/** * Only allow this content handler to be used in the Module namespace * @param Title $title * @return bool */ public function canBeUsedOn(Title $title) { if ($title->getNamespace() !== NS_MODULE) { return false; } return parent::canBeUsedOn($title); }
/** * @brief remove User:: from back link * * @author Tomek Odrobny * * @param Title $title * @param String $ptext * * @return Boolean */ public static function onSkinSubPageSubtitleAfterTitle($title, &$ptext) { if (!empty($title) && $title->getNamespace() == NS_USER) { $ptext = $title->getText(); } return true; }
protected function invalidateTitle(\Title $title) { global $wgParsoidCacheServers, $wgContentNamespaces; if (!in_array($title->getNamespace(), $wgContentNamespaces)) { return false; } # First request the new version $parsoidInfo = array(); $parsoidInfo['cacheID'] = $title->getPreviousRevisionID($title->getLatestRevID()); $parsoidInfo['changedTitle'] = $this->title->getPrefixedDBkey(); $requests = array(); foreach ($wgParsoidCacheServers as $server) { $singleUrl = $this->getParsoidURL($title); $requests[] = array('url' => $singleUrl, 'headers' => array('X-Parsoid: ' . json_encode($parsoidInfo), 'Cache-control: no-cache')); $this->wikiaLog(array("action" => "invalidateTitle", "get_url" => $singleUrl)); } $this->checkCurlResults(\CurlMultiClient::request($requests)); # And now purge the previous revision so that we make efficient use of # the Varnish cache space without relying on LRU. Since the URL # differs we can't use implicit refresh. $requests = array(); foreach ($wgParsoidCacheServers as $server) { // @TODO: this triggers a getPreviousRevisionID() query per server $singleUrl = $this->getParsoidURL($title, true); $requests[] = array('url' => $singleUrl); $this->wikiaLog(array("action" => "invalidateTitle", "purge_url" => $singleUrl)); } $options = \CurlMultiClient::getDefaultOptions(); $options[CURLOPT_CUSTOMREQUEST] = "PURGE"; return $this->checkCurlResults(\CurlMultiClient::request($requests, $options)); }
/** * @param Title $rootPage The root page under which all pages should be * created */ public function __construct(Title $rootPage) { if (!MWNamespace::hasSubpages($rootPage->getNamespace())) { throw new MWException("The root page you specified, {$rootPage}, is in a " . "namespace where subpages are not allowed"); } $this->rootPage = $rootPage; }
/** * Do some database updates after deletion * * @param int $id The page_id value of the page being deleted * @param Content|null $content Optional page content to be used when determining * the required updates. This may be needed because $this->getContent() * may already return null when the page proper was deleted. * @param Revision|null $revision The latest page revision */ public function doDeleteUpdates($id, Content $content = null, Revision $revision = null) { try { $countable = $this->isCountable(); } catch (Exception $ex) { // fallback for deleting broken pages for which we cannot load the content for // some reason. Note that doDeleteArticleReal() already logged this problem. $countable = false; } // Update site status DeferredUpdates::addUpdate(new SiteStatsUpdate(0, 1, -(int) $countable, -1)); // Delete pagelinks, update secondary indexes, etc $updates = $this->getDeletionUpdates($content); foreach ($updates as $update) { DeferredUpdates::addUpdate($update); } // Reparse any pages transcluding this page LinksUpdate::queueRecursiveJobsForTable($this->mTitle, 'templatelinks'); // Reparse any pages including this image if ($this->mTitle->getNamespace() == NS_FILE) { LinksUpdate::queueRecursiveJobsForTable($this->mTitle, 'imagelinks'); } // Clear caches WikiPage::onArticleDelete($this->mTitle); ResourceLoaderWikiModule::invalidateModuleCache($this->mTitle, $revision, null, wfWikiID()); // Reset this object and the Title object $this->loadFromRow(false, self::READ_LATEST); // Search engine DeferredUpdates::addUpdate(new SearchUpdate($id, $this->mTitle)); }
/** * Declares JSON as the code editor language for Schema: pages. * This hook only runs if the CodeEditor extension is enabled. * @param Title $title * @param string &$lang: Page language. * @return bool */ static function onCodeEditorGetPageLanguage($title, &$lang) { if ($title->getNamespace() === NS_SCHEMA) { $lang = 'json'; } return true; }
/** * Intercept pages in the Layer namespace to handle them correctly. * * @param $title: Title * @param $article: Article or null * * @return true */ public static function onArticleFromTitle(Title &$title, &$article) { if ($title->getNamespace() == Maps_NS_LAYER) { $article = new MapsLayerPage($title); } return true; }
/** * @param Title $Title * @param User $User * @param int $articleId * @param string $text */ public function __construct($Title, $User, $articleId = 0, $text = '') { global $wgEnableBlogArticles; /** * initialization */ $this->mPageNs = $Title->getNamespace(); if (empty($articleId)) { $this->mPageId = $Title->getArticleID(); if (empty($this->mPageId)) { $Title->getArticleID(Title::GAID_FOR_UPDATE); } } else { $this->setPageId($articleId); } if (is_object($User)) { $this->mUserId = intval($User->getID()); } else { $this->mUserId = intval($User); } $this->mIsContent = $Title->isContentPage() && ($wgEnableBlogArticles && !in_array($this->mPageNs, array(NS_BLOG_ARTICLE, NS_BLOG_ARTICLE_TALK, NS_BLOG_LISTING, NS_BLOG_LISTING_TALK))); $this->mDate = date('Y-m-d'); if ($text) { $this->mText = preg_replace('/\\[\\[[^\\:\\]]+\\:[^\\]]*\\]\\]/', '', $text); } }
function wfCOArticleCommentCheck(Title $title) { global $wgCommentsOnlyNamespaces; if (in_array($title->getNamespace(), $wgCommentsOnlyNamespaces) && ($title->getText() == 'Index' || $title->equals(Title::newMainPage()))) { return false; } return true; }
/** * If requested title doesn't exist, redirect to duplicate title (same name but different case) if exists. * NOTE: As of MediaWiki 1.18.0, $article is NULL * @param Title $title * @param type $article * @param type $output * @param type $user * @param type $request * @param type $mediaWiki * @return boolean */ public static function redirectDuplicate(&$title, $article, &$output, &$user, $request, $mediaWiki) { if ($title->getNamespace() != NS_SPECIAL && !$title->isKnown() && ($duplicate = TitleKey::exactMatchTitle($title))) { wfDebugLog('preventduplicate', "{$title->getPrefixedDBkey()} asked, doesn't exist, suggest to use {$duplicate->getPrefixedDBkey()} instead"); $title = $duplicate; } return true; }
/** * Prevent users from moving a stylometricanalysis page */ public function onAbortMove(Title $oldTitle, Title $newTitle, User $user, &$error, $reason) { if ($oldTitle->getNamespace() === NS_STYLOMETRICANALYSIS) { $error = $this->getMessage('stylometricanalysis-move'); return false; } return true; }
/** * @param $title Title of page to check * @return bool */ public function canBeUsedOn(Title $title) { global $wgCollaborationListAllowedNamespaces; if (in_array($title->getNamespace(), array_keys(array_filter($wgCollaborationListAllowedNamespaces)))) { return true; } return false; }
/** * Check if a title is marked as fuzzy. * @return bool If title is marked fuzzy. */ public function isFuzzy() { $dbr = wfGetDB(DB_SLAVE); $tables = array('page', 'revtag'); $field = 'rt_type'; $conds = array('page_namespace' => $this->title->getNamespace(), 'page_title' => $this->title->getDBkey(), 'rt_type' => RevTag::getType('fuzzy'), 'page_id=rt_page', 'page_latest=rt_revision'); $res = $dbr->selectField($tables, $field, $conds, __METHOD__); return $res !== false; }
/** * @param Title $title * @param WikiPage $article * @return bool */ public function onArticleFromTitle(Title &$title, &$article) { if ($title->exists() && $title->getNamespace() != NS_FILE && $title->getNamespace() != NS_CATEGORY) { $key = $this->generateCacheKey($title->getArticleId()); $this->switches = $this->app->wg->memc->get($key); if (empty($this->switches)) { $article = F::build('Article', array($title)); $this->switches = array(); foreach ($this->magicWords as $wordID) { $magicWord = MagicWord::get($wordID); $this->switches[$wordID] = 0 < $magicWord->match($article->getRawText()); } $this->app->wg->memc->set($key, $this->switches, self::CACHE_DURATION); } $this->process(); } return true; }
/** * return the page titles of the subpages in an array * @return array all titles * @private */ function getTitles() { wfProfileIn( __METHOD__ ); $dbr = wfGetDB( DB_SLAVE ); $conditions = array(); $options = array(); $order = strtoupper( $this->order ); if( $this->ordermethod == 'title' ) { $options['ORDER BY'] = 'page_title ' . $order; } elseif( $this->ordermethod == 'lastedit' ) { $options['ORDER BY'] = 'page_touched ' . $order; } if( $this->parent !== -1) { $this->ptitle = Title::newFromText( $this->parent ); # note that non-existent pages may nevertheless have valid subpages # on the other hand, not checking that the page exists can let input through which causes database errors if ( $this->ptitle instanceof Title && $this->ptitle->exists() && $this->ptitle->userCanRead() ) { $parent = $this->ptitle->getDBkey(); $this->parent = $parent; $this->namespace = $this->ptitle->getNsText(); $nsi = $this->ptitle->getNamespace(); } else { $this->error( wfMsg('spl3_debug','parent') ); return null; } } else { $this->ptitle = $this->title; $parent = $this->title->getDBkey(); $this->parent = $parent; $this->namespace = $this->title->getNsText(); $nsi = $this->title->getNamespace(); } // don't let list cross namespaces if ( strlen( $nsi ) > 0 ) { $conditions['page_namespace'] = $nsi; } $conditions['page_is_redirect'] = 0; $conditions[] = 'page_title ' . $dbr->buildLike( $parent . '/', $dbr->anyString() ); $fields = array(); $fields[] = 'page_title'; $fields[] = 'page_namespace'; $res = $dbr->select( 'page', $fields, $conditions, __METHOD__, $options ); $titles = array(); foreach ( $res as $row ) { $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title ); if( $title ) { $titles[] = $title; } } wfProfileOut( __METHOD__ ); return $titles; }
/** * @since 1.9 * * @return true */ public function process() { /** * @var Settings $settings */ $settings = $this->applicationFactory->getSettings(); $cache = $this->applicationFactory->newCacheFactory()->newMediaWikiCompositeCache(); // Delete all data for a non-enabled target NS if (!$this->applicationFactory->getNamespaceExaminer()->isSemanticEnabled($this->newTitle->getNamespace())) { $cache->delete(FactboxCache::newCacheId($this->oldId)->generateId()); $this->applicationFactory->getStore()->deleteSubject($this->oldTitle); } else { $cache->save(ArticlePurge::newCacheId($this->newId)->generateId(), $settings->get('smwgAutoRefreshOnPageMove')); $cache->save(ArticlePurge::newCacheId($this->oldId)->generateId(), $settings->get('smwgAutoRefreshOnPageMove')); $this->applicationFactory->getStore()->changeTitle($this->oldTitle, $this->newTitle, $this->oldId, $this->newId); } return true; }
/** * @param int $level * @param Title $target * @param int $limit * @param int $offset * @access private */ function wfShowIndirectLinks($level, $target, $limit, $offset = 0) { global $wgOut, $wgUser; $fname = 'wfShowIndirectLinks'; $dbr =& wfGetDB(DB_READ); // Read one extra row as an at-end check $queryLimit = $limit + 1; $limitSql = $level == 0 ? "{$offset},{$queryLimit}" : $queryLimit; $res = $dbr->select(array('pagelinks', 'page'), array('page_id', 'page_namespace', 'page_title', 'page_is_redirect'), array('pl_from=page_id', 'pl_namespace' => $target->getNamespace(), 'pl_title' => $target->getDbKey()), $fname, array('LIMIT' => $limitSql)); if (0 == $dbr->numRows($res)) { if (0 == $level) { $wgOut->addWikiText(wfMsg('nolinkshere')); } return; } if (0 == $level) { $wgOut->addWikiText(wfMsg('linkshere')); } $sk = $wgUser->getSkin(); $isredir = ' (' . wfMsg('isredirect') . ")\n"; if ($dbr->numRows($res) == 0) { return; } $atend = $dbr->numRows($res) <= $limit; if ($level == 0) { $specialTitle = Title::makeTitle(NS_SPECIAL, 'Whatlinkshere'); $prevnext = wfViewPrevNext($offset, $limit, $specialTitle, 'target=' . urlencode($target->getPrefixedDbKey()), $atend); $wgOut->addHTML($prevnext); } $wgOut->addHTML('<ul>'); $linksShown = 0; while ($row = $dbr->fetchObject($res)) { if (++$linksShown > $limit) { // Last row is for checks only; don't display it. break; } $nt = Title::makeTitle($row->page_namespace, $row->page_title); if ($row->page_is_redirect) { $extra = 'redirect=no'; } else { $extra = ''; } $link = $sk->makeKnownLinkObj($nt, '', $extra); $wgOut->addHTML('<li>' . $link); if ($row->page_is_redirect) { $wgOut->addHTML($isredir); if ($level < 2) { wfShowIndirectLinks($level + 1, $nt, 500); } } $wgOut->addHTML("</li>\n"); } $wgOut->addHTML("</ul>\n"); if ($level == 0) { $wgOut->addHTML($prevnext); } }
/** * @author Federico "Lox" Lucignano * * Factory method, usage of TopList::createItem is preferred * * @param Title $title a Title class instance for the article * * @return mixed a TopListItem instance, false in case $title is not in the NS_TOPLIST namespace */ public static function newFromTitle(Title $title) { if ($title->getNamespace() == NS_TOPLIST) { $list = new self(); $list->mTitle = $title; return $list; } return false; }
/** * @param $title Title of page to check * @return bool */ public function canBeUsedOn(Title $title) { global $wgCollaborationHubAllowedNamespaces; $namespace = $title->getNamespace(); if (in_array($namespace, array_keys(array_filter($wgCollaborationHubAllowedNamespaces))) && MWNamespace::hasSubpages($namespace)) { return true; } return false; }
/** * Hook: skip confirmation message in banner notification * when file page is deleted (set message to blank) * @param Title $title * @param string $message * @return true */ public static function onOasisAddPageDeletedConfirmationMessage(&$title, &$message) { $app = F::app(); $controller = $app->wg->Request->getVal('controller', ''); $method = $app->wg->Request->getVal('method', ''); if ($title instanceof Title && $title->getNamespace() == NS_FILE && $controller == 'LicensedVideoSwapSpecial' && $method == 'swapVideo') { $message = ''; } return true; }