/** * If there are revisions between the ones being compared, return a note saying so. * @return string */ function getMultiNotice() { if (!is_object($this->mOldRev) || !is_object($this->mNewRev)) { return ''; } elseif (!$this->mOldPage->equals($this->mNewPage)) { // Comparing two different pages? Count would be meaningless. return ''; } if ($this->mOldRev->getTimestamp() > $this->mNewRev->getTimestamp()) { $oldRev = $this->mNewRev; // flip $newRev = $this->mOldRev; // flip } else { // normal case $oldRev = $this->mOldRev; $newRev = $this->mNewRev; } $nEdits = $this->mNewPage->countRevisionsBetween($oldRev, $newRev); if ($nEdits > 0) { $limit = 100; // use diff-multi-manyusers if too many users $users = $this->mNewPage->getAuthorsBetween($oldRev, $newRev, $limit); $numUsers = count($users); if ($numUsers == 1 && $users[0] == $newRev->getRawUserText()) { $numUsers = 0; // special case to say "by the same user" instead of "by one other user" } return self::intermediateEditsMsg($nEdits, $numUsers, $limit); } return ''; // nothing }
/** * If there are revisions between the ones being compared, return a note saying so. * * @return string */ public function getMultiNotice() { if (!is_object($this->mOldRev) || !is_object($this->mNewRev)) { return ''; } elseif (!$this->mOldPage->equals($this->mNewPage)) { // Comparing two different pages? Count would be meaningless. return ''; } if ($this->mOldRev->getTimestamp() > $this->mNewRev->getTimestamp()) { $oldRev = $this->mNewRev; // flip $newRev = $this->mOldRev; // flip } else { // normal case $oldRev = $this->mOldRev; $newRev = $this->mNewRev; } // Sanity: don't show the notice if too many rows must be scanned // @todo show some special message for that case $nEdits = $this->mNewPage->countRevisionsBetween($oldRev, $newRev, 1000); if ($nEdits > 0 && $nEdits <= 1000) { $limit = 100; // use diff-multi-manyusers if too many users $users = $this->mNewPage->getAuthorsBetween($oldRev, $newRev, $limit); $numUsers = count($users); if ($numUsers == 1 && $users[0] == $newRev->getUserText(Revision::RAW)) { $numUsers = 0; // special case to say "by the same user" instead of "by one other user" } return self::intermediateEditsMsg($nEdits, $numUsers, $limit); } return ''; // nothing }
/** * Does various sanity checks that the move is * valid. Only things based on the two titles * should be checked here. * * @return Status */ public function isValidMove() { global $wgContentHandlerUseDB; $status = new Status(); if ($this->oldTitle->equals($this->newTitle)) { $status->fatal('selfmove'); } if (!$this->oldTitle->isMovable()) { $status->fatal('immobile-source-namespace', $this->oldTitle->getNsText()); } if ($this->newTitle->isExternal()) { $status->fatal('immobile-target-namespace-iw'); } if (!$this->newTitle->isMovable()) { $status->fatal('immobile-target-namespace', $this->newTitle->getNsText()); } $oldid = $this->oldTitle->getArticleID(); if (strlen($this->newTitle->getDBkey()) < 1) { $status->fatal('articleexists'); } if ($this->oldTitle->getDBkey() == '' || !$oldid || $this->newTitle->getDBkey() == '') { $status->fatal('badarticleerror'); } # The move is allowed only if (1) the target doesn't exist, or # (2) the target is a redirect to the source, and has no history # (so we can undo bad moves right after they're done). if ($this->newTitle->getArticleID() && !$this->isValidMoveTarget()) { $status->fatal('articleexists'); } // Content model checks if (!$wgContentHandlerUseDB && $this->oldTitle->getContentModel() !== $this->newTitle->getContentModel()) { // can't move a page if that would change the page's content model $status->fatal('bad-target-model', ContentHandler::getLocalizedName($this->oldTitle->getContentModel()), ContentHandler::getLocalizedName($this->newTitle->getContentModel())); } elseif (!ContentHandler::getForTitle($this->oldTitle)->canBeUsedOn($this->newTitle)) { $status->fatal('content-not-allowed-here', ContentHandler::getLocalizedName($this->oldTitle->getContentModel()), $this->newTitle->getPrefixedText()); } // Image-specific checks if ($this->oldTitle->inNamespace(NS_FILE)) { $status->merge($this->isValidFileMove()); } if ($this->newTitle->inNamespace(NS_FILE) && !$this->oldTitle->inNamespace(NS_FILE)) { $status->fatal('nonfile-cannot-move-to-file'); } // Hook for extensions to say a title can't be moved for technical reasons Hooks::run('MovePageIsValidMove', [$this->oldTitle, $this->newTitle, $status]); return $status; }
function wfCOArticleCommentCheck(Title $title) { global $wgCommentsOnlyNamespaces; if (in_array($title->getNamespace(), $wgCommentsOnlyNamespaces) && ($title->getText() == 'Index' || $title->equals(Title::newMainPage()))) { return false; } return true; }
/** * Does various sanity checks that the move is * valid. Only things based on the two titles * should be checked here. * * @return Status */ public function isValidMove() { global $wgContentHandlerUseDB; $status = new Status(); if ($this->oldTitle->equals($this->newTitle)) { $status->fatal('selfmove'); } if (!$this->oldTitle->isMovable()) { $status->fatal('immobile-source-namespace', $this->oldTitle->getNsText()); } if ($this->newTitle->isExternal()) { $status->fatal('immobile-target-namespace-iw'); } if (!$this->newTitle->isMovable()) { $status->fatal('immobile-target-namespace', $this->newTitle->getNsText()); } $oldid = $this->oldTitle->getArticleID(); if (strlen($this->newTitle->getDBkey()) < 1) { $status->fatal('articleexists'); } if ($this->oldTitle->getDBkey() == '' || !$oldid || $this->newTitle->getDBkey() == '') { $status->fatal('badarticleerror'); } // Content model checks if (!$wgContentHandlerUseDB && $this->oldTitle->getContentModel() !== $this->newTitle->getContentModel()) { // can't move a page if that would change the page's content model $status->fatal('bad-target-model', ContentHandler::getLocalizedName($this->oldTitle->getContentModel()), ContentHandler::getLocalizedName($this->newTitle->getContentModel())); } // Image-specific checks if ($this->oldTitle->inNamespace(NS_FILE)) { $status->merge($this->isValidFileMove()); } if ($this->newTitle->inNamespace(NS_FILE) && !$this->oldTitle->inNamespace(NS_FILE)) { $status->fatal('nonfile-cannot-move-to-file'); } // Hook for extensions to say a title can't be moved for technical reasons Hooks::run('MovePageIsValidMove', array($this->oldTitle, $this->newTitle, $status)); return $status; }
/** * Extract inexpensive information from a Title object for return to Lua * * @param $title Title Title to return * @return array Lua data */ private function getInexpensiveTitleData(Title $title) { $ns = $title->getNamespace(); $ret = array('isLocal' => (bool) $title->isLocal(), 'interwiki' => $title->getInterwiki(), 'namespace' => $ns, 'nsText' => $title->getNsText(), 'text' => $title->getText(), 'fragment' => $title->getFragment(), 'thePartialUrl' => $title->getPartialURL()); if ($ns === NS_SPECIAL) { // Core doesn't currently record special page links, but it may in the future. if ($this->getParser() && !$title->equals($this->getTitle())) { $this->getParser()->getOutput()->addLink($title); } $ret['exists'] = (bool) SpecialPageFactory::exists($title->getDBkey()); } if ($ns !== NS_FILE && $ns !== NS_MEDIA) { $ret['file'] = false; } return $ret; }
/** * Shows a normal (i.e. not deleted or moved) thread body * @param $thread Thread */ function showThreadBody($thread) { // Remove 'editsection', it won't work. $popts = $this->output->parserOptions(); $previous_editsection = $popts->getEditSection(); $popts->setEditSection(false); $this->output->parserOptions($popts); $post = $thread->root(); $divClass = $this->postDivClass($thread); $html = ''; // This is a bit of a hack to have individual histories work. // We can grab oldid either from lqt_oldid (which is a thread rev), // or from oldid (which is a page rev). But oldid only applies to the // thread being requested, not any replies. $page_rev = $this->request->getVal('oldid', null); if ($page_rev !== null && $this->title->equals($thread->root()->getTitle())) { $oldid = $page_rev; } else { $oldid = $thread->isHistorical() ? $thread->rootRevision() : null; } // If we're editing the thread, show the editing form. $showAnything = Hooks::run('LiquidThreadsShowThreadBody', array($thread)); if ($this->methodAppliesToThread('edit', $thread) && $showAnything) { $html = Xml::openElement('div', array('class' => $divClass)); $this->output->addHTML($html); $html = ''; // No way am I refactoring EditForm to return its output as HTML. // so I'm just flushing the HTML and displaying it as-is. $this->showPostEditingForm($thread); $html .= Xml::closeElement('div'); } elseif ($showAnything) { $html .= Xml::openElement('div', array('class' => $divClass)); $show = Hooks::run('LiquidThreadsShowPostContent', array($thread, &$post)); if ($show) { $html .= $this->showPostBody($post, $oldid); } $html .= Xml::closeElement('div'); Hooks::run('LiquidThreadsShowPostThreadBody', array($thread, $this->request, &$html)); $html .= $this->showThreadToolbar($thread); $html .= $this->threadSignature($thread); } $this->output->addHTML($html); $popts->setEditSection($previous_editsection); $this->output->parserOptions($popts); }
/** * Extract information from a Title object for return to Lua * * This also records a link to this title in the current ParserOutput * and caches the title for repeated lookups. The caller should call * incrementExpensiveFunctionCount() if necessary. * * @param $title Title Title to return * @return array Lua data */ private function returnTitleToLua(Title $title) { // Cache it $this->titleCache[$title->getPrefixedDBkey()] = $title; if ($title->getArticleID() > 0) { $this->idCache[$title->getArticleID()] = $title; } // Record a link if ($this->getParser() && !$title->equals($this->getTitle())) { $this->getParser()->getOutput()->addLink($title); } $ns = $title->getNamespace(); $ret = array('isLocal' => (bool) $title->isLocal(), 'isRedirect' => (bool) $title->isRedirect(), 'interwiki' => $title->getInterwiki(), 'namespace' => $ns, 'nsText' => $title->getNsText(), 'text' => $title->getText(), 'id' => $title->getArticleID(), 'fragment' => $title->getFragment(), 'thePartialUrl' => $title->getPartialURL()); if ($ns === NS_SPECIAL) { $ret['exists'] = (bool) SpecialPageFactory::exists($title->getDBkey()); } else { $ret['exists'] = $ret['id'] > 0; } if ($ns !== NS_FILE && $ns !== NS_MEDIA) { $ret['fileExists'] = false; } return $ret; }
public function execute($par) { $this->useTransactionalTimeLimit(); $this->checkPermissions(); $this->checkReadOnly(); $this->loadRequestParams(); $this->setHeaders(); $this->outputHeader(); if ($this->mTargetID && $this->mDestID && $this->mAction == 'submit' && $this->mMerge) { $this->merge(); return; } if (!$this->mSubmitted) { $this->showMergeForm(); return; } $errors = []; if (!$this->mTargetObj instanceof Title) { $errors[] = $this->msg('mergehistory-invalid-source')->parseAsBlock(); } elseif (!$this->mTargetObj->exists()) { $errors[] = $this->msg('mergehistory-no-source', wfEscapeWikiText($this->mTargetObj->getPrefixedText()))->parseAsBlock(); } if (!$this->mDestObj instanceof Title) { $errors[] = $this->msg('mergehistory-invalid-destination')->parseAsBlock(); } elseif (!$this->mDestObj->exists()) { $errors[] = $this->msg('mergehistory-no-destination', wfEscapeWikiText($this->mDestObj->getPrefixedText()))->parseAsBlock(); } if ($this->mTargetObj && $this->mDestObj && $this->mTargetObj->equals($this->mDestObj)) { $errors[] = $this->msg('mergehistory-same-destination')->parseAsBlock(); } if (count($errors)) { $this->showMergeForm(); $this->getOutput()->addHTML(implode("\n", $errors)); } else { $this->showHistory(); } }
/** * @dataProvider basicProvider */ public function testBasic(ForeignTitle $foreignTitle, Title $title) { $factory = new NaiveImportTitleFactory(); $testTitle = $factory->createTitleFromForeignTitle($foreignTitle); $this->assertTrue($title->equals($testTitle)); }
/** * Find the parent hub, if any. * Returns the first CollaborationHub Title found, even if more are higher up, or null if none * @param $title Title to start looking from * @return Title|null */ public static function getParentHub(Title $title) { global $wgCollaborationHubAllowedNamespaces; $namespace = $title->getNamespace(); if (MWNamespace::hasSubpages($namespace) && in_array($namespace, array_keys(array_filter($wgCollaborationHubAllowedNamespaces)))) { $parentTitle = $title->getBaseTitle(); while (!$title->equals($parentTitle)) { $parentRev = Revision::newFromTitle($parentTitle); if ($parentTitle->getContentModel() == 'CollaborationHubContent' && isset($parentRev)) { return $parentTitle; } // keep looking $title = $parentTitle; } } // Nothing was found return null; }
/** * Fills default widget list definition into user's config page * @param string $text * @param Title $title * @return boolean Always true to keep hook running */ public function onEditFormPreloadText(&$text, &$title) { if (!$title->equals(Title::makeTitle(NS_USER, $this->getUser()->getName() . '/Sidebar'))) { return true; } $aViews = array(); $this->getDefaultWidgets($aViews, $this->getUser(), $title); $aDefaultWidgetKeywords = array_keys($aViews); $text = '* ' . implode("\n* ", $aDefaultWidgetKeywords); return true; }
/** * Hook-Handle for MW hook EditFormPreloadText * @param string $sText * @param Title $oTitle * @return boolean - always true */ public function onEditFormPreloadText(&$sText, $oTitle) { $oTopBarMenuTitle = Title::makeTitle(NS_MEDIAWIKI, 'TopBarMenu'); if (!$oTopBarMenuTitle || !$oTitle->equals($oTopBarMenuTitle)) { return true; } $aNavigationSites = self::getNavigationSites(); if (empty($aNavigationSites)) { return true; } $sText = TopMenuBarCustomizerParser::toWikiText($aNavigationSites, $sText); return true; }
/** * Decide wheter a page is the ancestor of another given page or not. * * @param Title $ancestor The parent/ancestor page. * @param Title $descendant The child/descendant page. * * @return bool true if the given page really is the ancestor of the seccond page. */ static function isAncestorOf( Title $ancestor, Title $descendant ) { //in case of both pages beeing the same: if( $ancestor->equals( $descendant ) ) return false; //in case the ancestor is a part of the given descendant it is a parrent, except for ancestors //ending with "/": These could also be siblings and need further checking: $ancestorChildSlash = ( substr( $descendant->getText(), -1 ) != '/' ) ? '/' : ''; return preg_match( '%^' . preg_quote( $ancestor->getText() . $ancestorChildSlash, '%' ) . '%', $descendant->getText() ) != 0; }
/** * Checks if the subject of the remove and add properties is actually the * one this object is initialized with. If not, the return with a false, * else with a true. Also it notices if the subject of add is actually * empty, so that it used for *** kind of adds, i.e. nothing is being * removed. * * @param Title $remove The title that facts are meant to be removed from * @param Title $add The title that facts are meant to be added to * @return boolean true if everything is OK */ private function checkSubject( Title $remove, Title $add ) { // if ( !$add->equals($this->title) ) return false; // TODO Rethink! if ( $remove->exists() ) { if ( !$remove->equals( $this->title ) ) return false; } else { $this->nosubject = true; } return true; }