/**
  * 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
 }
Example #3
0
 /**
  * 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;
 }
Example #4
0
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;
 }
Example #6
0
 /**
  * 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;
 }
Example #7
0
 /**
  * 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);
 }
Example #8
0
 /**
  * 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;
	}