/**
	 * This method will be called before an article is displayed or previewed.
	 * For display and preview we strip out the semantic properties and append them
	 * at the end of the article.
	 *
	 * @param Parser $parser
	 * @param string $text
	 */
	static public function onInternalParseBeforeLinks( &$parser, &$text ) {
		global $smwgStoreAnnotations, $smwgLinksInValues;

		SMWParseData::stripMagicWords( $text, $parser );

		// Store the results if enabled (we have to parse them in any case,
		// in order to clean the wiki source for further processing).
		$smwgStoreAnnotations = smwfIsSemanticsProcessed( $parser->getTitle()->getNamespace() );
		SMWParserExtensions::$mTempStoreAnnotations = true; // used for [[SMW::on]] and [[SMW:off]]

		// Process redirects, if any (it seems that there is indeed no more direct way of getting this info from MW)
		if ( $smwgStoreAnnotations ) {
			$rt = Title::newFromRedirect( $text );
			
			if ( !is_null( $rt ) ) {
				$p = new SMWDIProperty( '_REDI' );
				$di = SMWDIWikiPage::newFromTitle( $rt, '__red' );
				SMWParseData::getSMWData( $parser )->addPropertyObjectValue( $p, $di );
			}
		}

		// only used in subsequent callbacks, forgotten afterwards
		SMWParserExtensions::$mTempParser = $parser;

		// In the regexp matches below, leading ':' escapes the markup, as known for Categories.
		// Parse links to extract semantic properties.
		if ( $smwgLinksInValues ) { // More complex regexp -- lib PCRE may cause segfaults if text is long :-(
			$semanticLinkPattern = '/\[\[                 # Beginning of the link
			                        (?:([^:][^]]*):[=:])+ # Property name (or a list of those)
			                        (                     # After that:
			                          (?:[^|\[\]]         #   either normal text (without |, [ or ])
			                          |\[\[[^]]*\]\]      #   or a [[link]]
			                          |\[[^]]*\]          #   or an [external link]
			                        )*)                   # all this zero or more times
			                        (?:\|([^]]*))?        # Display text (like "text" in [[link|text]]), optional
			                        \]\]                  # End of link
			                        /xu';
			$text = preg_replace_callback( $semanticLinkPattern, array( 'SMWParserExtensions', 'parsePropertiesCallback' ), $text );
		} else { // Simpler regexps -- no segfaults found for those, but no links in values.
			$semanticLinkPattern = '/\[\[                 # Beginning of the link
			                        (?:([^:][^]]*):[=:])+ # Property name (or a list of those)
			                        ([^\[\]]*)            # content: anything but [, |, ]
			                        \]\]                  # End of link
			                        /xu';
			$text = preg_replace_callback( $semanticLinkPattern, array( 'SMWParserExtensions', 'simpleParsePropertiesCallback' ), $text );
		}

		// Add link to RDF to HTML header.
		// TODO: do escaping via Html or Xml class.
		SMWOutputs::requireHeadItem(
			'smw_rdf', '<link rel="alternate" type="application/rdf+xml" title="' .
			htmlspecialchars( $parser->getTitle()->getPrefixedText() ) . '" href="' .
			htmlspecialchars(
				SpecialPage::getTitleFor( 'ExportRDF', $parser->getTitle()->getPrefixedText() )->getLocalUrl( 'xmlmime=rdf' )
			) . "\" />"
		);

		SMWOutputs::commitToParser( $parser );
		return true; // always return true, in order not to stop MW's hook processing!
	}
function redircite_render($input, $args, &$parser) {
	// Generate HTML code and add it to the $redirciteMarkerList array
	// Add "xx-redircite-marker-NUMBER-redircite-xx" to the output,
	// which will be translated to the HTML stored in $redirciteMarkerList by
	// redircite_afterTidy()
	global $redirciteMarkerList;
	# Verify that $input is a valid title
	$inputTitle = Title::newFromText($input);
	if(!$inputTitle)
		return $input;
	$link1 = $parser->recursiveTagParse("[[$input]]");
	$title1 = Title::newFromText($input);
	if(!$title1->exists()) // Page doesn't exist
		// Just output a normal (red) link
		return $link1;
	$articleObj = new Article($title1);
	$title2 = Title::newFromRedirect($articleObj->fetchContent());
	if(!$title2) // Page is not a redirect
		// Just output a normal link
		return $link1;
	
	$link2 = $parser->recursiveTagParse("[[{$title2->getPrefixedText()}|$input]]");
	
	$marker = "xx-redircite-marker-" . count($redirciteMarkerList) . "-redircite-xx";
	$onmouseout = 'this.firstChild.innerHTML = "'. Xml::escapeJsString($input) . '";';
	$onmouseover = 'this.firstChild.innerHTML = "' . Xml::escapeJsString($title2->getPrefixedText()) . '";';
	return Xml::tags('span', array(
					'onmouseout' => $onmouseout,
					'onmouseover' => $onmouseover),
					$link2);
}
Example #3
0
 function getTopLevelCategories()
 {
     global $wgCategoriesArticle;
     wfLoadExtensionMessages('Sitemap');
     $results = array();
     $revision = Revision::newFromTitle(Title::newFromText(wfMsg('categories_article')));
     if (!$revision) {
         return $results;
     }
     // INTL: If there is a redirect to a localized page name, follow it
     if (strpos($revision->getText(), "#REDIRECT") !== false) {
         $revision = Revision::newFromTitle(Title::newFromRedirect($revision->getText()));
     }
     $lines = split("\n", $revision->getText());
     foreach ($lines as $line) {
         if (preg_match('/^\\*[^\\*]/', $line)) {
             $line = trim(substr($line, 1));
             switch ($line) {
                 case "Other":
                 case "wikiHow":
                     break;
                 default:
                     $results[] = $line;
             }
         }
     }
     return $results;
 }
 function formatResult($skin, $result)
 {
     global $wgContLang;
     # Make a link to the redirect itself
     $rd_title = Title::makeTitle($result->namespace, $result->title);
     $arr = $wgContLang->getArrow() . $wgContLang->getDirMark();
     $rd_link = $skin->makeKnownLinkObj($rd_title, '', 'redirect=no');
     # Find out where the redirect leads
     $revision = Revision::newFromTitle($rd_title);
     if ($revision) {
         # Make a link to the destination page
         $target = Title::newFromRedirect($revision->getText());
         if ($target) {
             $targetLink = $skin->makeLinkObj($target);
         } else {
             /** @todo Put in some decent error display here */
             $targetLink = '*';
         }
     } else {
         /** @todo Put in some decent error display here */
         $targetLink = '*';
     }
     # Format the whole thing and return it
     return "{$rd_link} {$arr} {$targetLink}";
 }
Example #5
0
 function formatResult($skin, $result)
 {
     global $wgContLang;
     # Make a link to the redirect itself
     $rd_title = Title::makeTitle($result->namespace, $result->title);
     $rd_link = $skin->makeKnownLinkObj($rd_title, '', 'redirect=no');
     # Find out where the redirect leads
     $revision = Revision::newFromTitle($rd_title);
     if ($revision) {
         # Make a link to the destination page
         $target = Title::newFromRedirect($revision->getText());
         if ($target) {
             $targetLink = $skin->makeLinkObj($target);
         } else {
             /** @todo Put in some decent error display here */
             $targetLink = '*';
         }
     } else {
         /** @todo Put in some decent error display here */
         $targetLink = '*';
     }
     # Check the language; RTL wikis need a &larr;
     $arr = $wgContLang->isRTL() ? ' &larr; ' : ' &rarr; ';
     # Format the whole thing and return it
     return $rd_link . $arr . $targetLink;
 }
 /**
  * @since 1.1
  *
  * @param EditPage $editor
  * @param OutputPage &$out
  *
  * @return true
  */
 public function onEditConflict(EditPage &$editor, OutputPage &$out)
 {
     $conctext = $editor->textbox1;
     $actualtext = $editor->textbox2;
     $initialtext = $editor->getBaseRevision()->mText;
     // TODO: WTF?!
     $editor->mArticle->doEdit($actualtext, $editor->summary, $editor->minoredit ? EDIT_MINOR : 0);
     $query = Title::newFromRedirect($actualtext) === null ? '' : 'redirect=no';
     $out->redirect($editor->mTitle->getFullURL($query));
     return true;
 }
Example #7
0
 public function addArticle($month, $day, $year, $page)
 {
     $lines = array();
     $temp = "";
     $head = array();
     $article = new Article(Title::newFromText($page));
     if (!$article->exists()) {
         return "";
     }
     $redirectCount = 0;
     if ($article->isRedirect() && $this->setting('disableredirects')) {
         return '';
     }
     while ($article->isRedirect() && $redirectCount < 10) {
         $redirectedArticleTitle = Title::newFromRedirect($article->getContent());
         $article = new Article($redirectedArticleTitle);
         $redirectCount += 1;
     }
     $body = $article->fetchContent(0, false, false);
     if (strlen(trim($body)) == 0) {
         return "";
     }
     $lines = split("\n", $body);
     $cntLines = count($lines);
     // dont use section events... only line 1 of the page
     if ($this->setting('disablesectionevents')) {
         $key = $lines[0];
         //initalize the key
         $head[$key] = "";
         $cntLines = 0;
     }
     for ($i = 0; $i < $cntLines; $i++) {
         $line = $lines[$i];
         if (substr($line, 0, 2) == '==') {
             $arr = split("==", $line);
             $key = $arr[1];
             $head[$key] = "";
             $temp = "";
         } else {
             if ($i == 0) {
                 // $i=0  means this is a one event page no (==event==) data
                 $key = $line;
                 //initalize the key
                 $head[$key] = "";
             } else {
                 $temp .= "{$line}\n";
                 $head[$key] = Common::cleanWiki($temp);
             }
         }
     }
     while (list($event, $body) = each($head)) {
         $this->buildEvent($month, $day, $year, trim($event), $page, $body);
     }
 }
Example #8
0
 function run()
 {
     if (!$this->redirTitle) {
         $this->setLastError('Invalid title');
         return false;
     }
     $targetRev = Revision::newFromTitle($this->title);
     if (!$targetRev) {
         wfDebug(__METHOD__ . ": target redirect already deleted, ignoring\n");
         return true;
     }
     $text = $targetRev->getText();
     $currentDest = Title::newFromRedirect($text);
     if (!$currentDest || !$currentDest->equals($this->redirTitle)) {
         wfDebug(__METHOD__ . ": Redirect has changed since the job was queued\n");
         return true;
     }
     # Check for a suppression tag (used e.g. in periodically archived discussions)
     $mw = MagicWord::get('staticredirect');
     if ($mw->match($text)) {
         wfDebug(__METHOD__ . ": skipping: suppressed with __STATICREDIRECT__\n");
         return true;
     }
     # Find the current final destination
     $newTitle = self::getFinalDestination($this->redirTitle);
     if (!$newTitle) {
         wfDebug(__METHOD__ . ": skipping: single redirect, circular redirect or invalid redirect destination\n");
         return true;
     }
     if ($newTitle->equals($this->redirTitle)) {
         # The redirect is already right, no need to change it
         # This can happen if the page was moved back (say after vandalism)
         wfDebug(__METHOD__ . ": skipping, already good\n");
     }
     # Preserve fragment (bug 14904)
     $newTitle = Title::makeTitle($newTitle->getNamespace(), $newTitle->getDBkey(), $currentDest->getFragment());
     # Fix the text
     # Remember that redirect pages can have categories, templates, etc.,
     # so the regex has to be fairly general
     $newText = preg_replace('/ \\[ \\[  [^\\]]*  \\] \\] /x', '[[' . $newTitle->getFullText() . ']]', $text, 1);
     if ($newText === $text) {
         $this->setLastError('Text unchanged???');
         return false;
     }
     # Save it
     global $wgUser;
     $oldUser = $wgUser;
     $wgUser = $this->getUser();
     $article = new Article($this->title);
     $reason = wfMsgForContent('double-redirect-fixed-' . $this->reason, $this->redirTitle->getPrefixedText(), $newTitle->getPrefixedText());
     $article->doEdit($newText, $reason, EDIT_UPDATE | EDIT_SUPPRESS_RC);
     $wgUser = $oldUser;
     return true;
 }
Example #9
0
 function getRS()
 {
     global $wgMemc;
     $key_rs = wfMemcKey("risingstar-feed3:" . date('YmdG') . ":" . number_format(date('i') / 10, 0, '', ''));
     $rsOut = $wgMemc->get($key_rs);
     if (!empty($rsOut)) {
         return $rsOut;
     }
     $t = Title::newFromText('wikiHow:Rising-star-feed');
     if ($t->getArticleId() > 0) {
         $r = Revision::newFromTitle($t);
         $text = $r->getText();
     } else {
         return false;
     }
     //NOTE: temporary patch to handle archives.  the authoritative source for RS needs to be moved to the DB versus the feed article. add archive to array.
     $archives = array('wikiHow:Rising-star-feed/archive1');
     foreach ($archives as $archive) {
         $tarch = Title::newFromText($archive);
         if ($tarch->getArticleId() > 0) {
             $r = Revision::newFromTitle($tarch);
             $text = $r->getText() . "\n" . $text;
         }
     }
     $rsout = array();
     $rs = $text;
     $rs = preg_replace("/==\n/", ',', $rs);
     $rs = preg_replace("/^==/", "", $rs);
     $lines = preg_split("/\r|\n/", $rs, null, PREG_SPLIT_NO_EMPTY);
     $count = 0;
     foreach ($lines as $line) {
         if (preg_match('/^==(.*?),(.*?)$/', $line, $matches)) {
             $dt = $matches[1];
             $pattern = "/{$wgServer}/";
             $title = preg_replace("/http:\\/\\/www\\.wikihow\\.com\\//", "", $matches[2]);
             $title = preg_replace("/http:\\/\\/.*?\\.com\\//", "", $matches[2]);
             $t = Title::newFromText($title);
             if (!isset($t)) {
                 continue;
             }
             $a = new Article($t);
             if ($a->isRedirect()) {
                 $t = Title::newFromRedirect($a->fetchContent());
                 $a = new Article($t);
             }
             $rsout[$t->getPartialURL()] = $dt;
         }
     }
     // sort by most recent first
     $rsout = array_reverse($rsout);
     $wgMemc->set($key_rs, $rsout);
     return $rsout;
 }
Example #10
0
 public function hUnknownAction($action, &$article)
 {
     // check if request 'action=formsubmit'
     if ($action != 'formsubmit') {
         return true;
     }
     // continue hook-chain.
     $article->loadContent();
     // follow redirects
     if ($article->mIsRedirect == true) {
         $title = Title::newFromRedirect($article->getContent());
         $article = new Article($title);
         $article->loadContent();
     }
     // Extract the code
     // Use our runphpClass helper
     $runphp = new runphpClass();
     $runphp->initFromContent($article->getContent());
     // Execute Code
     $code = $runphp->getCode(true);
     if (!empty($code)) {
         $callback = eval($code);
     }
     // we might implement functionality around a callback method in the future
     // Was there an expected class defined?
     $name = $article->mTitle->getDBkey();
     // the page name might actually be a sub-page; extract the basename without the full path.
     $pn = explode('/', $name);
     if (!empty($pn)) {
         $rn = array_reverse($pn);
         $name = $rn[0];
     }
     $name .= 'Class';
     if (class_exists($name)) {
         $class = new $name();
         if (is_object($class)) {
             if (method_exists($class, 'submit')) {
                 $class->submit();
             }
         }
     }
     // ... then it was a page built from ground up; nothing more to do here.
     return false;
 }
Example #11
0
 public function execute()
 {
     $this->output("Fetching redirects...\n");
     $dbr = wfGetDB(DB_SLAVE);
     $result = $dbr->select(array('page'), array('page_namespace', 'page_title', 'page_latest'), array('page_is_redirect' => 1));
     $count = $result->numRows();
     $this->output("Found {$count} total redirects.\n" . "Looking for bad redirects:\n\n");
     foreach ($result as $row) {
         $title = Title::makeTitle($row->page_namespace, $row->page_title);
         $rev = Revision::newFromId($row->page_latest);
         if ($rev) {
             $target = Title::newFromRedirect($rev->getText());
             if (!$target) {
                 $this->output($title->getPrefixedText() . "\n");
             }
         }
     }
     $this->output("\ndone.\n");
 }
 function formatResult($skin, $result)
 {
     global $wgContLang;
     # Make a link to the redirect itself
     $rd_title = Title::makeTitle($result->namespace, $result->title);
     $rd_link = $skin->makeLinkObj($rd_title, '', 'redirect=no');
     # Find out where the redirect leads
     $revision = Revision::newFromTitle($rd_title);
     if ($revision) {
         # Make a link to the destination page
         $target = Title::newFromRedirect($revision->getText());
         if ($target) {
             $arr = $wgContLang->getArrow() . $wgContLang->getDirMark();
             $targetLink = $skin->makeLinkObj($target);
             return "{$rd_link} {$arr} {$targetLink}";
         } else {
             return "<s>{$rd_link}</s>";
         }
     } else {
         return "<s>{$rd_link}</s>";
     }
 }
Example #13
0
 function redirectThread()
 {
     $rev = Revision::newFromId($this->root()->getLatest());
     $rtitle = Title::newFromRedirect($rev->getRawText());
     if (!$rtitle) {
         return null;
     }
     $this->dieIfHistorical();
     $rthread = Threads::withRoot(new Article($rtitle));
     return $rthread;
 }
Example #14
0
 /**
  * Static function to get a template
  * Can be overridden via ParserOptions::setTemplateCallback().
  */
 static function statelessFetchTemplate($title, $parser = false)
 {
     $text = $skip = false;
     $finalTitle = $title;
     $deps = array();
     // Loop to fetch the article, with up to 1 redirect
     for ($i = 0; $i < 2 && is_object($title); $i++) {
         # Give extensions a chance to select the revision instead
         $id = false;
         // Assume current
         wfRunHooks('BeforeParserFetchTemplateAndtitle', array($parser, &$title, &$skip, &$id));
         if ($skip) {
             $text = false;
             $deps[] = array('title' => $title, 'page_id' => $title->getArticleID(), 'rev_id' => null);
             break;
         }
         $rev = $id ? Revision::newFromId($id) : Revision::newFromTitle($title);
         $rev_id = $rev ? $rev->getId() : 0;
         // If there is no current revision, there is no page
         if ($id === false && !$rev) {
             $linkCache = LinkCache::singleton();
             $linkCache->addBadLinkObj($title);
         }
         $deps[] = array('title' => $title, 'page_id' => $title->getArticleID(), 'rev_id' => $rev_id);
         if ($rev) {
             $text = $rev->getText();
         } elseif ($title->getNamespace() == NS_MEDIAWIKI) {
             global $wgContLang;
             $message = $wgContLang->lcfirst($title->getText());
             $text = wfMsgForContentNoTrans($message);
             if (wfEmptyMsg($message, $text)) {
                 $text = false;
                 break;
             }
         } else {
             break;
         }
         if ($text === false) {
             break;
         }
         // Redirect?
         $finalTitle = $title;
         $title = Title::newFromRedirect($text);
     }
     return array('text' => $text, 'finalTitle' => $finalTitle, 'deps' => $deps);
 }
Example #15
0
 /**
  * Static function to get a template
  * Can be overridden via ParserOptions::setTemplateCallback().
  *
  * @param $title  Title
  * @param $parser Parser
  *
  * @return array
  */
 static function statelessFetchTemplate($title, $parser = false)
 {
     $text = $skip = false;
     $finalTitle = $title;
     $deps = array();
     # Loop to fetch the article, with up to 1 redirect
     for ($i = 0; $i < 2 && is_object($title); $i++) {
         # Give extensions a chance to select the revision instead
         $id = false;
         # Assume current
         wfRunHooks('BeforeParserFetchTemplateAndtitle', array($parser, $title, &$skip, &$id));
         if ($skip) {
             $text = false;
             $deps[] = array('title' => $title, 'page_id' => $title->getArticleID(), 'rev_id' => null);
             break;
         }
         # Get the revision
         $rev = $id ? Revision::newFromId($id) : Revision::newFromTitle($title, false, Revision::READ_NORMAL);
         $rev_id = $rev ? $rev->getId() : 0;
         # If there is no current revision, there is no page
         if ($id === false && !$rev) {
             $linkCache = LinkCache::singleton();
             $linkCache->addBadLinkObj($title);
         }
         $deps[] = array('title' => $title, 'page_id' => $title->getArticleID(), 'rev_id' => $rev_id);
         if ($rev && !$title->equals($rev->getTitle())) {
             # We fetched a rev from a different title; register it too...
             $deps[] = array('title' => $rev->getTitle(), 'page_id' => $rev->getPage(), 'rev_id' => $rev_id);
         }
         if ($rev) {
             $text = $rev->getText();
         } elseif ($title->getNamespace() == NS_MEDIAWIKI) {
             global $wgContLang;
             $message = wfMessage($wgContLang->lcfirst($title->getText()))->inContentLanguage();
             if (!$message->exists()) {
                 $text = false;
                 break;
             }
             $text = $message->plain();
         } else {
             break;
         }
         if ($text === false) {
             break;
         }
         # Redirect?
         $finalTitle = $title;
         $title = Title::newFromRedirect($text);
     }
     return array('text' => $text, 'finalTitle' => $finalTitle, 'deps' => $deps);
 }
Example #16
0
 /**
  * Return an applicable autosummary if one exists for the given edit.
  * @param $oldtext String: the previous text of the page.
  * @param $newtext String: The submitted text of the page.
  * @param $flags Bitmask: a bitmask of flags submitted for the edit.
  * @return string An appropriate autosummary, or an empty string.
  */
 public static function getAutosummary($oldtext, $newtext, $flags)
 {
     global $wgContLang;
     # Decide what kind of autosummary is needed.
     # Redirect autosummaries
     $ot = Title::newFromRedirect($oldtext);
     $rt = Title::newFromRedirect($newtext);
     if (is_object($rt) && (!is_object($ot) || !$rt->equals($ot) || $ot->getFragment() != $rt->getFragment())) {
         return wfMsgForContent('autoredircomment', $rt->getFullText());
     }
     # New page autosummaries
     if ($flags & EDIT_NEW && strlen($newtext)) {
         # If they're making a new article, give its text, truncated, in the summary.
         $truncatedtext = $wgContLang->truncate(str_replace("\n", ' ', $newtext), max(0, 200 - strlen(wfMsgForContent('autosumm-new'))));
         return wfMsgForContent('autosumm-new', $truncatedtext);
     }
     # Blanking autosummaries
     if ($oldtext != '' && $newtext == '') {
         return wfMsgForContent('autosumm-blank');
     } elseif (strlen($oldtext) > 10 * strlen($newtext) && strlen($newtext) < 500) {
         # Removing more than 90% of the article
         $truncatedtext = $wgContLang->truncate($newtext, max(0, 200 - strlen(wfMsgForContent('autosumm-replace'))));
         return wfMsgForContent('autosumm-replace', $truncatedtext);
     }
     # If we reach this point, there's no applicable autosummary for our case, so our
     # autosummary is empty.
     return '';
 }
Example #17
0
<?php

require "commandLine.inc";
echo "Fetching redirects...\n";
$dbr = wfGetDB(DB_SLAVE);
$result = $dbr->select(array('page'), array('page_namespace', 'page_title', 'page_latest'), array('page_is_redirect' => 1));
$count = $result->numRows();
echo "Found {$count} total redirects.\n";
echo "Looking for bad redirects:\n";
echo "\n";
foreach ($result as $row) {
    $title = Title::makeTitle($row->page_namespace, $row->page_title);
    $rev = Revision::newFromId($row->page_latest);
    if ($rev) {
        $target = Title::newFromRedirect($rev->getText());
        if (!$target) {
            echo $title->getPrefixedText();
            echo "\n";
        }
    }
}
echo "\n";
echo "done.\n";
Example #18
0
 /**
  * This is the default action of the script: just view the page of
  * the given title.
  */
 function view()
 {
     global $wgUser, $wgOut, $wgRequest, $wgContLang;
     global $wgEnableParserCache, $wgStylePath, $wgUseRCPatrol, $wgParser;
     global $wgUseTrackbacks, $wgNamespaceRobotPolicies;
     $sk = $wgUser->getSkin();
     wfProfileIn(__METHOD__);
     $parserCache =& ParserCache::singleton();
     $ns = $this->mTitle->getNamespace();
     # shortcut
     # Get variables from query string
     $oldid = $this->getOldID();
     # getOldID may want us to redirect somewhere else
     if ($this->mRedirectUrl) {
         $wgOut->redirect($this->mRedirectUrl);
         wfProfileOut(__METHOD__);
         return;
     }
     $diff = $wgRequest->getVal('diff');
     $rcid = $wgRequest->getVal('rcid');
     $rdfrom = $wgRequest->getVal('rdfrom');
     $wgOut->setArticleFlag(true);
     if (isset($wgNamespaceRobotPolicies[$ns])) {
         $policy = $wgNamespaceRobotPolicies[$ns];
     } else {
         $policy = 'index,follow';
     }
     $wgOut->setRobotpolicy($policy);
     # If we got diff and oldid in the query, we want to see a
     # diff page instead of the article.
     if (!is_null($diff)) {
         require_once 'DifferenceEngine.php';
         $wgOut->setPageTitle($this->mTitle->getPrefixedText());
         $de = new DifferenceEngine($this->mTitle, $oldid, $diff, $rcid);
         // DifferenceEngine directly fetched the revision:
         $this->mRevIdFetched = $de->mNewid;
         $de->showDiffPage();
         if ($diff == 0) {
             # Run view updates for current revision only
             $this->viewUpdates();
         }
         wfProfileOut(__METHOD__);
         return;
     }
     if (empty($oldid) && $this->checkTouched()) {
         $wgOut->setETag($parserCache->getETag($this, $wgUser));
         if ($wgOut->checkLastModified($this->mTouched)) {
             // WERELATE: add viewUpdates call just in case
             $this->viewUpdates();
             wfProfileOut(__METHOD__);
             return;
         } else {
             if ($this->tryFileCache()) {
                 # tell wgOut that output is taken care of
                 $wgOut->disable();
                 $this->viewUpdates();
                 wfProfileOut(__METHOD__);
                 return;
             }
         }
     }
     # Should the parser cache be used?
     $pcache = $wgEnableParserCache && intval($wgUser->getOption('stubthreshold')) == 0 && $this->exists() && empty($oldid);
     wfDebug('Article::view using parser cache: ' . ($pcache ? 'yes' : 'no') . "\n");
     if ($wgUser->getOption('stubthreshold')) {
         wfIncrStats('pcache_miss_stub');
     }
     $wasRedirected = false;
     if (isset($this->mRedirectedFrom)) {
         // This is an internally redirected page view.
         // We'll need a backlink to the source page for navigation.
         if (wfRunHooks('ArticleViewRedirect', array(&$this))) {
             $sk = $wgUser->getSkin();
             $redir = $sk->makeKnownLinkObj($this->mRedirectedFrom, '', 'redirect=no');
             $s = wfMsg('redirectedfrom', $redir);
             $wgOut->setSubtitle($s);
             $wasRedirected = true;
         }
     } elseif (!empty($rdfrom)) {
         // This is an externally redirected view, from some other wiki.
         // If it was reported from a trusted site, supply a backlink.
         global $wgRedirectSources;
         if ($wgRedirectSources && preg_match($wgRedirectSources, $rdfrom)) {
             $sk = $wgUser->getSkin();
             $redir = $sk->makeExternalLink($rdfrom, $rdfrom);
             $s = wfMsg('redirectedfrom', $redir);
             $wgOut->setSubtitle($s);
             $wasRedirected = true;
         }
     }
     $outputDone = false;
     if ($pcache) {
         if ($wgOut->tryParserCache($this, $wgUser)) {
             $outputDone = true;
         }
     }
     if (!$outputDone) {
         $text = $this->getContent();
         if ($text === false) {
             # Failed to load, replace text with error message
             $t = $this->mTitle->getPrefixedText();
             if ($oldid) {
                 $t .= ',oldid=' . $oldid;
                 $text = wfMsg('missingarticle', $t);
             } else {
                 $text = wfMsg('noarticletext', $t);
             }
         }
         # Another whitelist check in case oldid is altering the title
         if (!$this->mTitle->userCanRead()) {
             $wgOut->loginToUse();
             $wgOut->output();
             exit;
         }
         # We're looking at an old revision
         if (!empty($oldid)) {
             $wgOut->setRobotpolicy('noindex,nofollow');
             if (is_null($this->mRevision)) {
                 // FIXME: This would be a nice place to load the 'no such page' text.
             } else {
                 $this->setOldSubtitle(isset($this->mOldId) ? $this->mOldId : $oldid);
                 if ($this->mRevision->isDeleted(Revision::DELETED_TEXT)) {
                     if (!$this->mRevision->userCan(Revision::DELETED_TEXT)) {
                         $wgOut->addWikiText(wfMsg('rev-deleted-text-permission'));
                         $wgOut->setPageTitle($this->mTitle->getPrefixedText());
                         return;
                     } else {
                         $wgOut->addWikiText(wfMsg('rev-deleted-text-view'));
                         // and we are allowed to see...
                     }
                 }
             }
         }
     }
     if (!$outputDone) {
         /**
          * @fixme: this hook doesn't work most of the time, as it doesn't
          * trigger when the parser cache is used.
          */
         wfRunHooks('ArticleViewHeader', array(&$this));
         $wgOut->setRevisionId($this->getRevIdFetched());
         # wrap user css and user js in pre and don't parse
         # XXX: use $this->mTitle->usCssJsSubpage() when php is fixed/ a workaround is found
         if ($ns == NS_USER && preg_match('/\\/[\\w]+\\.(css|js)$/', $this->mTitle->getDBkey())) {
             $wgOut->addWikiText(wfMsg('clearyourcache'));
             $wgOut->addHTML('<pre>' . htmlspecialchars($this->mContent) . "\n</pre>");
         } else {
             if ($rt = Title::newFromRedirect($text)) {
                 # Display redirect
                 $imageDir = $wgContLang->isRTL() ? 'rtl' : 'ltr';
                 $imageUrl = $wgStylePath . '/common/images/redirect' . $imageDir . '.png';
                 # Don't overwrite the subtitle if this was an old revision
                 if (!$wasRedirected && $this->isCurrent()) {
                     $wgOut->setSubtitle(wfMsgHtml('redirectpagesub'));
                 }
                 $targetUrl = $rt->escapeLocalURL();
                 # fixme unused $titleText :
                 $titleText = htmlspecialchars($rt->getPrefixedText());
                 $link = $sk->makeLinkObj($rt);
                 $wgOut->addHTML('<img src="' . $imageUrl . '" alt="#REDIRECT" />' . '<span class="redirectText">' . $link . '</span>');
                 $parseout = $wgParser->parse($text, $this->mTitle, ParserOptions::newFromUser($wgUser));
                 $wgOut->addParserOutputNoText($parseout);
             } else {
                 if ($pcache) {
                     # Display content and save to parser cache
                     $wgOut->addPrimaryWikiText($text, $this);
                 } else {
                     # Display content, don't attempt to save to parser cache
                     # Don't show section-edit links on old revisions... this way lies madness.
                     if (!$this->isCurrent()) {
                         $oldEditSectionSetting = $wgOut->mParserOptions->setEditSection(false);
                     }
                     # Display content and don't save to parser cache
                     $wgOut->addPrimaryWikiText($text, $this, false);
                     if (!$this->isCurrent()) {
                         $wgOut->mParserOptions->setEditSection($oldEditSectionSetting);
                     }
                 }
             }
         }
     }
     /* title may have been set from the cache */
     $t = $wgOut->getPageTitle();
     if (empty($t)) {
         $wgOut->setPageTitle($this->mTitle->getPrefixedText());
     }
     # check if we're displaying a [[User talk:x.x.x.x]] anonymous talk page
     if ($ns == NS_USER_TALK && User::isIP($this->mTitle->getText())) {
         $wgOut->addWikiText(wfMsg('anontalkpagetext'));
     }
     # If we have been passed an &rcid= parameter, we want to give the user a
     # chance to mark this new article as patrolled.
     if ($wgUseRCPatrol && !is_null($rcid) && $rcid != 0 && $wgUser->isAllowed('patrol')) {
         $wgOut->addHTML("<div class='patrollink'>" . wfMsg('markaspatrolledlink', $sk->makeKnownLinkObj($this->mTitle, wfMsg('markaspatrolledtext'), "action=markpatrolled&rcid={$rcid}")) . '</div>');
     }
     # Trackbacks
     if ($wgUseTrackbacks) {
         $this->addTrackbacks();
     }
     $this->viewUpdates();
     wfProfileOut(__METHOD__);
 }
Example #19
0
 /**
  * Attempt submission (no UI)
  *
  * @param $result
  * @param $bot bool
  *
  * @return Status object, possibly with a message, but always with one of the AS_* constants in $status->value,
  *
  * FIXME: This interface is TERRIBLE, but hard to get rid of due to various error display idiosyncrasies. There are
  * also lots of cases where error metadata is set in the object and retrieved later instead of being returned, e.g.
  * AS_CONTENT_TOO_BIG and AS_BLOCKED_PAGE_FOR_USER. All that stuff needs to be cleaned up some time.
  */
 function internalAttemptSave(&$result, $bot = false)
 {
     global $wgFilterCallback, $wgUser, $wgRequest, $wgParser;
     global $wgMaxArticleSize;
     $status = Status::newGood();
     wfProfileIn(__METHOD__);
     wfProfileIn(__METHOD__ . '-checks');
     if (!wfRunHooks('EditPage::attemptSave', array($this))) {
         wfDebug("Hook 'EditPage::attemptSave' aborted article saving\n");
         $status->fatal('hookaborted');
         $status->value = self::AS_HOOK_ERROR;
         wfProfileOut(__METHOD__ . '-checks');
         wfProfileOut(__METHOD__);
         return $status;
     }
     # Check image redirect
     if ($this->mTitle->getNamespace() == NS_FILE && Title::newFromRedirect($this->textbox1) instanceof Title && !$wgUser->isAllowed('upload')) {
         $code = $wgUser->isAnon() ? self::AS_IMAGE_REDIRECT_ANON : self::AS_IMAGE_REDIRECT_LOGGED;
         $status->setResult(false, $code);
         wfProfileOut(__METHOD__ . '-checks');
         wfProfileOut(__METHOD__);
         return $status;
     }
     # Check for spam
     $match = self::matchSummarySpamRegex($this->summary);
     if ($match === false) {
         $match = self::matchSpamRegex($this->textbox1);
     }
     if ($match !== false) {
         $result['spam'] = $match;
         $ip = $wgRequest->getIP();
         $pdbk = $this->mTitle->getPrefixedDBkey();
         $match = str_replace("\n", '', $match);
         wfDebugLog('SpamRegex', "{$ip} spam regex hit [[{$pdbk}]]: \"{$match}\"");
         $status->fatal('spamprotectionmatch', $match);
         $status->value = self::AS_SPAM_ERROR;
         wfProfileOut(__METHOD__ . '-checks');
         wfProfileOut(__METHOD__);
         return $status;
     }
     if ($wgFilterCallback && is_callable($wgFilterCallback) && $wgFilterCallback($this->mTitle, $this->textbox1, $this->section, $this->hookError, $this->summary)) {
         # Error messages or other handling should be performed by the filter function
         $status->setResult(false, self::AS_FILTERING);
         wfProfileOut(__METHOD__ . '-checks');
         wfProfileOut(__METHOD__);
         return $status;
     }
     if (!wfRunHooks('EditFilter', array($this, $this->textbox1, $this->section, &$this->hookError, $this->summary))) {
         # Error messages etc. could be handled within the hook...
         $status->fatal('hookaborted');
         $status->value = self::AS_HOOK_ERROR;
         wfProfileOut(__METHOD__ . '-checks');
         wfProfileOut(__METHOD__);
         return $status;
     } elseif ($this->hookError != '') {
         # ...or the hook could be expecting us to produce an error
         $status->fatal('hookaborted');
         $status->value = self::AS_HOOK_ERROR_EXPECTED;
         wfProfileOut(__METHOD__ . '-checks');
         wfProfileOut(__METHOD__);
         return $status;
     }
     if ($wgUser->isBlockedFrom($this->mTitle, false)) {
         // Auto-block user's IP if the account was "hard" blocked
         $wgUser->spreadAnyEditBlock();
         # Check block state against master, thus 'false'.
         $status->setResult(false, self::AS_BLOCKED_PAGE_FOR_USER);
         wfProfileOut(__METHOD__ . '-checks');
         wfProfileOut(__METHOD__);
         return $status;
     }
     $this->kblength = (int) (strlen($this->textbox1) / 1024);
     if ($this->kblength > $wgMaxArticleSize) {
         // Error will be displayed by showEditForm()
         $this->tooBig = true;
         $status->setResult(false, self::AS_CONTENT_TOO_BIG);
         wfProfileOut(__METHOD__ . '-checks');
         wfProfileOut(__METHOD__);
         return $status;
     }
     if (!$wgUser->isAllowed('edit')) {
         if ($wgUser->isAnon()) {
             $status->setResult(false, self::AS_READ_ONLY_PAGE_ANON);
             wfProfileOut(__METHOD__ . '-checks');
             wfProfileOut(__METHOD__);
             return $status;
         } else {
             $status->fatal('readonlytext');
             $status->value = self::AS_READ_ONLY_PAGE_LOGGED;
             wfProfileOut(__METHOD__ . '-checks');
             wfProfileOut(__METHOD__);
             return $status;
         }
     }
     if (wfReadOnly()) {
         $status->fatal('readonlytext');
         $status->value = self::AS_READ_ONLY_PAGE;
         wfProfileOut(__METHOD__ . '-checks');
         wfProfileOut(__METHOD__);
         return $status;
     }
     if ($wgUser->pingLimiter()) {
         $status->fatal('actionthrottledtext');
         $status->value = self::AS_RATE_LIMITED;
         wfProfileOut(__METHOD__ . '-checks');
         wfProfileOut(__METHOD__);
         return $status;
     }
     # If the article has been deleted while editing, don't save it without
     # confirmation
     if ($this->wasDeletedSinceLastEdit() && !$this->recreate) {
         $status->setResult(false, self::AS_ARTICLE_WAS_DELETED);
         wfProfileOut(__METHOD__ . '-checks');
         wfProfileOut(__METHOD__);
         return $status;
     }
     wfProfileOut(__METHOD__ . '-checks');
     # If article is new, insert it.
     $aid = $this->mTitle->getArticleID(Title::GAID_FOR_UPDATE);
     $new = $aid == 0;
     if ($new) {
         // Late check for create permission, just in case *PARANOIA*
         if (!$this->mTitle->userCan('create')) {
             $status->fatal('nocreatetext');
             $status->value = self::AS_NO_CREATE_PERMISSION;
             wfDebug(__METHOD__ . ": no create permission\n");
             wfProfileOut(__METHOD__);
             return $status;
         }
         # Don't save a new article if it's blank.
         if ($this->textbox1 == '') {
             $status->setResult(false, self::AS_BLANK_ARTICLE);
             wfProfileOut(__METHOD__);
             return $status;
         }
         // Run post-section-merge edit filter
         if (!wfRunHooks('EditFilterMerged', array($this, $this->textbox1, &$this->hookError, $this->summary))) {
             # Error messages etc. could be handled within the hook...
             $status->fatal('hookaborted');
             $status->value = self::AS_HOOK_ERROR;
             wfProfileOut(__METHOD__);
             return $status;
         } elseif ($this->hookError != '') {
             # ...or the hook could be expecting us to produce an error
             $status->fatal('hookaborted');
             $status->value = self::AS_HOOK_ERROR_EXPECTED;
             wfProfileOut(__METHOD__);
             return $status;
         }
         # Handle the user preference to force summaries here. Check if it's not a redirect.
         if (!$this->allowBlankSummary && !Title::newFromRedirect($this->textbox1)) {
             if (md5($this->summary) == $this->autoSumm) {
                 $this->missingSummary = true;
                 $status->fatal('missingsummary');
                 // or 'missingcommentheader' if $section == 'new'. Blegh
                 $status->value = self::AS_SUMMARY_NEEDED;
                 wfProfileOut(__METHOD__);
                 return $status;
             }
         }
         $text = $this->textbox1;
         $result['sectionanchor'] = '';
         if ($this->section == 'new') {
             if ($this->sectiontitle !== '') {
                 // Insert the section title above the content.
                 $text = wfMsgForContent('newsectionheaderdefaultlevel', $this->sectiontitle) . "\n\n" . $text;
                 // Jump to the new section
                 $result['sectionanchor'] = $wgParser->guessLegacySectionNameFromWikiText($this->sectiontitle);
                 // If no edit summary was specified, create one automatically from the section
                 // title and have it link to the new section. Otherwise, respect the summary as
                 // passed.
                 if ($this->summary === '') {
                     $cleanSectionTitle = $wgParser->stripSectionName($this->sectiontitle);
                     $this->summary = wfMsgForContent('newsectionsummary', $cleanSectionTitle);
                 }
             } elseif ($this->summary !== '') {
                 // Insert the section title above the content.
                 $text = wfMsgForContent('newsectionheaderdefaultlevel', $this->summary) . "\n\n" . $text;
                 // Jump to the new section
                 $result['sectionanchor'] = $wgParser->guessLegacySectionNameFromWikiText($this->summary);
                 // Create a link to the new section from the edit summary.
                 $cleanSummary = $wgParser->stripSectionName($this->summary);
                 $this->summary = wfMsgForContent('newsectionsummary', $cleanSummary);
             }
         }
         $status->value = self::AS_SUCCESS_NEW_ARTICLE;
     } else {
         # Article exists. Check for edit conflict.
         $this->mArticle->clear();
         # Force reload of dates, etc.
         $timestamp = $this->mArticle->getTimestamp();
         wfDebug("timestamp: {$timestamp}, edittime: {$this->edittime}\n");
         if ($timestamp != $this->edittime) {
             $this->isConflict = true;
             if ($this->section == 'new') {
                 if ($this->mArticle->getUserText() == $wgUser->getName() && $this->mArticle->getComment() == $this->summary) {
                     // Probably a duplicate submission of a new comment.
                     // This can happen when squid resends a request after
                     // a timeout but the first one actually went through.
                     wfDebug(__METHOD__ . ": duplicate new section submission; trigger edit conflict!\n");
                 } else {
                     // New comment; suppress conflict.
                     $this->isConflict = false;
                     wfDebug(__METHOD__ . ": conflict suppressed; new section\n");
                 }
             } elseif ($this->section == '' && $this->userWasLastToEdit($wgUser->getId(), $this->edittime)) {
                 # Suppress edit conflict with self, except for section edits where merging is required.
                 wfDebug(__METHOD__ . ": Suppressing edit conflict, same user.\n");
                 $this->isConflict = false;
             }
         }
         // If sectiontitle is set, use it, otherwise use the summary as the section title (for
         // backwards compatibility with old forms/bots).
         if ($this->sectiontitle !== '') {
             $sectionTitle = $this->sectiontitle;
         } else {
             $sectionTitle = $this->summary;
         }
         if ($this->isConflict) {
             wfDebug(__METHOD__ . ": conflict! getting section '{$this->section}' for time '{$this->edittime}' (article time '{$timestamp}')\n");
             $text = $this->mArticle->replaceSection($this->section, $this->textbox1, $sectionTitle, $this->edittime);
         } else {
             wfDebug(__METHOD__ . ": getting section '{$this->section}'\n");
             $text = $this->mArticle->replaceSection($this->section, $this->textbox1, $sectionTitle);
         }
         if (is_null($text)) {
             wfDebug(__METHOD__ . ": activating conflict; section replace failed.\n");
             $this->isConflict = true;
             $text = $this->textbox1;
             // do not try to merge here!
         } elseif ($this->isConflict) {
             # Attempt merge
             if ($this->mergeChangesInto($text)) {
                 // Successful merge! Maybe we should tell the user the good news?
                 $this->isConflict = false;
                 wfDebug(__METHOD__ . ": Suppressing edit conflict, successful merge.\n");
             } else {
                 $this->section = '';
                 $this->textbox1 = $text;
                 wfDebug(__METHOD__ . ": Keeping edit conflict, failed merge.\n");
             }
         }
         if ($this->isConflict) {
             $status->setResult(false, self::AS_CONFLICT_DETECTED);
             wfProfileOut(__METHOD__);
             return $status;
         }
         // Run post-section-merge edit filter
         if (!wfRunHooks('EditFilterMerged', array($this, $text, &$this->hookError, $this->summary))) {
             # Error messages etc. could be handled within the hook...
             $status->fatal('hookaborted');
             $status->value = self::AS_HOOK_ERROR;
             wfProfileOut(__METHOD__);
             return $status;
         } elseif ($this->hookError != '') {
             # ...or the hook could be expecting us to produce an error
             $status->fatal('hookaborted');
             $status->value = self::AS_HOOK_ERROR_EXPECTED;
             wfProfileOut(__METHOD__);
             return $status;
         }
         # Handle the user preference to force summaries here, but not for null edits
         if ($this->section != 'new' && !$this->allowBlankSummary && $this->getOriginalContent() != $text && !Title::newFromRedirect($text)) {
             if (md5($this->summary) == $this->autoSumm) {
                 $this->missingSummary = true;
                 $status->fatal('missingsummary');
                 $status->value = self::AS_SUMMARY_NEEDED;
                 wfProfileOut(__METHOD__);
                 return $status;
             }
         }
         # And a similar thing for new sections
         if ($this->section == 'new' && !$this->allowBlankSummary) {
             if (trim($this->summary) == '') {
                 $this->missingSummary = true;
                 $status->fatal('missingsummary');
                 // or 'missingcommentheader' if $section == 'new'. Blegh
                 $status->value = self::AS_SUMMARY_NEEDED;
                 wfProfileOut(__METHOD__);
                 return $status;
             }
         }
         # All's well
         wfProfileIn(__METHOD__ . '-sectionanchor');
         $sectionanchor = '';
         if ($this->section == 'new') {
             if ($this->textbox1 == '') {
                 $this->missingComment = true;
                 $status->fatal('missingcommenttext');
                 $status->value = self::AS_TEXTBOX_EMPTY;
                 wfProfileOut(__METHOD__ . '-sectionanchor');
                 wfProfileOut(__METHOD__);
                 return $status;
             }
             if ($this->sectiontitle !== '') {
                 $sectionanchor = $wgParser->guessLegacySectionNameFromWikiText($this->sectiontitle);
                 // If no edit summary was specified, create one automatically from the section
                 // title and have it link to the new section. Otherwise, respect the summary as
                 // passed.
                 if ($this->summary === '') {
                     $cleanSectionTitle = $wgParser->stripSectionName($this->sectiontitle);
                     $this->summary = wfMsgForContent('newsectionsummary', $cleanSectionTitle);
                 }
             } elseif ($this->summary !== '') {
                 $sectionanchor = $wgParser->guessLegacySectionNameFromWikiText($this->summary);
                 # This is a new section, so create a link to the new section
                 # in the revision summary.
                 $cleanSummary = $wgParser->stripSectionName($this->summary);
                 $this->summary = wfMsgForContent('newsectionsummary', $cleanSummary);
             }
         } elseif ($this->section != '') {
             # Try to get a section anchor from the section source, redirect to edited section if header found
             # XXX: might be better to integrate this into Article::replaceSection
             # for duplicate heading checking and maybe parsing
             $hasmatch = preg_match("/^ *([=]{1,6})(.*?)(\\1) *\\n/i", $this->textbox1, $matches);
             # we can't deal with anchors, includes, html etc in the header for now,
             # headline would need to be parsed to improve this
             if ($hasmatch && strlen($matches[2]) > 0) {
                 $sectionanchor = $wgParser->guessLegacySectionNameFromWikiText($matches[2]);
             }
         }
         $result['sectionanchor'] = $sectionanchor;
         wfProfileOut(__METHOD__ . '-sectionanchor');
         // Save errors may fall down to the edit form, but we've now
         // merged the section into full text. Clear the section field
         // so that later submission of conflict forms won't try to
         // replace that into a duplicated mess.
         $this->textbox1 = $text;
         $this->section = '';
         $status->value = self::AS_SUCCESS_UPDATE;
     }
     // Check for length errors again now that the section is merged in
     $this->kblength = (int) (strlen($text) / 1024);
     if ($this->kblength > $wgMaxArticleSize) {
         $this->tooBig = true;
         $status->setResult(false, self::AS_MAX_ARTICLE_SIZE_EXCEEDED);
         wfProfileOut(__METHOD__);
         return $status;
     }
     $flags = EDIT_DEFER_UPDATES | EDIT_AUTOSUMMARY | ($new ? EDIT_NEW : EDIT_UPDATE) | ($this->minoredit && !$this->isNew ? EDIT_MINOR : 0) | ($bot ? EDIT_FORCE_BOT : 0);
     $doEditStatus = $this->mArticle->doEdit($text, $this->summary, $flags);
     if ($doEditStatus->isOK()) {
         $result['redirect'] = Title::newFromRedirect($text) !== null;
         $this->commitWatch();
         wfProfileOut(__METHOD__);
         return $status;
     } else {
         $this->isConflict = true;
         $doEditStatus->value = self::AS_END;
         // Destroys data doEdit() put in $status->value but who cares
         wfProfileOut(__METHOD__);
         return $doEditStatus;
     }
 }
Example #20
0
 /**
  * Attempt submission
  * @return bool false if output is done, true if the rest of the form should be displayed
  */
 function attemptSave()
 {
     global $wgSpamRegex, $wgFilterCallback, $wgUser, $wgOut;
     global $wgMaxArticleSize;
     $fname = 'EditPage::attemptSave';
     wfProfileIn($fname);
     wfProfileIn("{$fname}-checks");
     # Reintegrate metadata
     if ($this->mMetaData != '') {
         $this->textbox1 .= "\n" . $this->mMetaData;
     }
     $this->mMetaData = '';
     # Check for spam
     if ($wgSpamRegex && preg_match($wgSpamRegex, $this->textbox1, $matches)) {
         $this->spamPage($matches[0]);
         wfProfileOut("{$fname}-checks");
         wfProfileOut($fname);
         return false;
     }
     if ($wgFilterCallback && $wgFilterCallback($this->mTitle, $this->textbox1, $this->section)) {
         # Error messages or other handling should be performed by the filter function
         wfProfileOut($fname);
         wfProfileOut("{$fname}-checks");
         return false;
     }
     if (!wfRunHooks('EditFilter', array($this, $this->textbox1, $this->section, &$this->hookError))) {
         # Error messages etc. could be handled within the hook...
         wfProfileOut($fname);
         wfProfileOut("{$fname}-checks");
         return false;
     } elseif ($this->hookError != '') {
         # ...or the hook could be expecting us to produce an error
         wfProfileOut("{$fname}-checks ");
         wfProfileOut($fname);
         return true;
     }
     if ($wgUser->isBlockedFrom($this->mTitle, false)) {
         # Check block state against master, thus 'false'.
         $this->blockedPage();
         wfProfileOut("{$fname}-checks");
         wfProfileOut($fname);
         return false;
     }
     $this->kblength = (int) (strlen($this->textbox1) / 1024);
     if ($this->kblength > $wgMaxArticleSize) {
         // Error will be displayed by showEditForm()
         $this->tooBig = true;
         wfProfileOut("{$fname}-checks");
         wfProfileOut($fname);
         return true;
     }
     if (!$wgUser->isAllowed('edit')) {
         if ($wgUser->isAnon()) {
             $this->userNotLoggedInPage();
             wfProfileOut("{$fname}-checks");
             wfProfileOut($fname);
             return false;
         } else {
             $wgOut->readOnlyPage();
             wfProfileOut("{$fname}-checks");
             wfProfileOut($fname);
             return false;
         }
     }
     if (wfReadOnly()) {
         $wgOut->readOnlyPage();
         wfProfileOut("{$fname}-checks");
         wfProfileOut($fname);
         return false;
     }
     if ($wgUser->pingLimiter()) {
         $wgOut->rateLimited();
         wfProfileOut("{$fname}-checks");
         wfProfileOut($fname);
         return false;
     }
     # If the article has been deleted while editing, don't save it without
     # confirmation
     if ($this->deletedSinceEdit && !$this->recreate) {
         wfProfileOut("{$fname}-checks");
         wfProfileOut($fname);
         return true;
     }
     wfProfileOut("{$fname}-checks");
     # If article is new, insert it.
     $aid = $this->mTitle->getArticleID(GAID_FOR_UPDATE);
     if (0 == $aid) {
         // Late check for create permission, just in case *PARANOIA*
         if (!$this->mTitle->userCanCreate()) {
             wfDebug("{$fname}: no create permission\n");
             $this->noCreatePermission();
             wfProfileOut($fname);
             return;
         }
         # Don't save a new article if it's blank.
         if ('' == $this->textbox1) {
             $wgOut->redirect($this->mTitle->getFullURL());
             wfProfileOut($fname);
             return false;
         }
         # If no edit comment was given when creating a new page, and what's being
         # created is a redirect, be smart and fill in a neat auto-comment
         if ($this->summary == '') {
             $rt = Title::newFromRedirect($this->textbox1);
             if (is_object($rt)) {
                 $this->summary = wfMsgForContent('autoredircomment', $rt->getPrefixedText());
             }
         }
         $isComment = $this->section == 'new';
         $this->mArticle->insertNewArticle($this->textbox1, $this->summary, $this->minoredit, $this->watchthis, false, $isComment);
         wfProfileOut($fname);
         return false;
     }
     # Article exists. Check for edit conflict.
     $this->mArticle->clear();
     # Force reload of dates, etc.
     $this->mArticle->forUpdate(true);
     # Lock the article
     if ($this->mArticle->getTimestamp() != $this->edittime) {
         $this->isConflict = true;
         if ($this->section == 'new') {
             if ($this->mArticle->getUserText() == $wgUser->getName() && $this->mArticle->getComment() == $this->summary) {
                 // Probably a duplicate submission of a new comment.
                 // This can happen when squid resends a request after
                 // a timeout but the first one actually went through.
                 wfDebug("EditPage::editForm duplicate new section submission; trigger edit conflict!\n");
             } else {
                 // New comment; suppress conflict.
                 $this->isConflict = false;
                 wfDebug("EditPage::editForm conflict suppressed; new section\n");
             }
         }
     }
     $userid = $wgUser->getID();
     if ($this->isConflict) {
         wfDebug("EditPage::editForm conflict! getting section '{$this->section}' for time '{$this->edittime}' (article time '" . $this->mArticle->getTimestamp() . "'\n");
         $text = $this->mArticle->replaceSection($this->section, $this->textbox1, $this->summary, $this->edittime);
     } else {
         wfDebug("EditPage::editForm getting section '{$this->section}'\n");
         $text = $this->mArticle->replaceSection($this->section, $this->textbox1, $this->summary);
     }
     if (is_null($text)) {
         wfDebug("EditPage::editForm activating conflict; section replace failed.\n");
         $this->isConflict = true;
         $text = $this->textbox1;
     }
     # Suppress edit conflict with self, except for section edits where merging is required.
     if ($this->section == '' && 0 != $userid && $this->mArticle->getUser() == $userid) {
         wfDebug("Suppressing edit conflict, same user.\n");
         $this->isConflict = false;
     } else {
         # switch from section editing to normal editing in edit conflict
         if ($this->isConflict) {
             # Attempt merge
             if ($this->mergeChangesInto($text)) {
                 // Successful merge! Maybe we should tell the user the good news?
                 $this->isConflict = false;
                 wfDebug("Suppressing edit conflict, successful merge.\n");
             } else {
                 $this->section = '';
                 $this->textbox1 = $text;
                 wfDebug("Keeping edit conflict, failed merge.\n");
             }
         }
     }
     if ($this->isConflict) {
         wfProfileOut($fname);
         return true;
     }
     # If no edit comment was given when turning a page into a redirect, be smart
     # and fill in a neat auto-comment
     if ($this->summary == '') {
         $rt = Title::newFromRedirect($this->textbox1);
         if (is_object($rt)) {
             $this->summary = wfMsgForContent('autoredircomment', $rt->getPrefixedText());
         }
     }
     # Handle the user preference to force summaries here
     if ($this->section != 'new' && !$this->allowBlankSummary && $wgUser->getOption('forceeditsummary')) {
         if (md5($this->summary) == $this->autoSumm) {
             $this->missingSummary = true;
             wfProfileOut($fname);
             return true;
         }
     }
     # All's well
     wfProfileIn("{$fname}-sectionanchor");
     $sectionanchor = '';
     if ($this->section == 'new') {
         if ($this->textbox1 == '') {
             $this->missingComment = true;
             return true;
         }
         if ($this->summary != '') {
             $sectionanchor = $this->sectionAnchor($this->summary);
         }
     } elseif ($this->section != '') {
         # Try to get a section anchor from the section source, redirect to edited section if header found
         # XXX: might be better to integrate this into Article::replaceSection
         # for duplicate heading checking and maybe parsing
         $hasmatch = preg_match("/^ *([=]{1,6})(.*?)(\\1) *\\n/i", $this->textbox1, $matches);
         # we can't deal with anchors, includes, html etc in the header for now,
         # headline would need to be parsed to improve this
         if ($hasmatch and strlen($matches[2]) > 0) {
             $sectionanchor = $this->sectionAnchor($matches[2]);
         }
     }
     wfProfileOut("{$fname}-sectionanchor");
     // Save errors may fall down to the edit form, but we've now
     // merged the section into full text. Clear the section field
     // so that later submission of conflict forms won't try to
     // replace that into a duplicated mess.
     $this->textbox1 = $text;
     $this->section = '';
     // Check for length errors again now that the section is merged in
     $this->kblength = (int) (strlen($text) / 1024);
     if ($this->kblength > $wgMaxArticleSize) {
         $this->tooBig = true;
         wfProfileOut($fname);
         return true;
     }
     # update the article here
     if ($this->mArticle->updateArticle($text, $this->summary, $this->minoredit, $this->watchthis, '', $sectionanchor)) {
         wfProfileOut($fname);
         return false;
     } else {
         $this->isConflict = true;
     }
     wfProfileOut($fname);
     return true;
 }
	$unbrokenTitle = Title::makeTitleSafe(
		$brokenTitle->getNamespace(),
		preg_replace( '/^Broken\//', '', $brokenTitle->getDBkey() ) );

	# Check that the broken title is a redirect
	$revision = Revision::newFromTitle( $brokenTitle );
	if ( !$revision ) {
		echo "Does not exist: $line\n";
		continue;
	}
	$text = $revision->getText();
	if ( $text === false ) {
		echo "Cannot load text: $line\n";
		continue;
	}
	$redir = Title::newFromRedirect( $text );
	if ( !$redir ) {
		echo "Not a redirect: $line\n";
		continue;
	}


	if ( $unbrokenTitle->exists() ) {
		# Exists already, just delete this redirect
		$article = new Article( $brokenTitle );
		$success = $article->doDeleteArticle( 'Redundant redirect' );
		if ( $success ) {
			echo "Deleted: $line\n";
		} else {
			echo "Failed to delete: $line\n";
		}
 public function hArticleViewHeader(&$article)
 {
     // check if we are dealing with a redirect page.
     $this->found = Title::newFromRedirect($article->getContent());
     return true;
 }
Example #23
0
 private function getAttrs($titleString, $ns)
 {
     $result = '';
     $t = Title::newFromText($titleString, $ns);
     $revision = null;
     $nt = $t;
     while ($nt) {
         // follow redirects
         $t = $nt;
         $nt = null;
         $revision = Revision::newFromTitle($t);
         if ($revision) {
             $text =& $revision->getText();
             $nt = Title::newFromRedirect($text);
         }
     }
     if ($t) {
         $result .= ' title="' . $this->escapeXml($t->getText()) . '"';
     }
     if ($revision) {
         // get attributes from text
         if ($ns == NS_PERSON) {
             $xml = $this->getXml('person', $text);
             if (isset($xml)) {
                 $name = $xml->name;
                 if (isset($name)) {
                     if ((string) $name['given']) {
                         $result .= ' given="' . $this->escapeXml((string) $name['given']) . '"';
                     }
                     if ((string) $name['surname']) {
                         $result .= ' surname="' . $this->escapeXml((string) $name['surname']) . '"';
                     }
                     if ((string) $name['title_prefix']) {
                         $result .= ' title_prefix="' . $this->escapeXml((string) $name['title_prefix']) . '"';
                     }
                     if ((string) $name['title_suffix']) {
                         $result .= ' title_suffix="' . $this->escapeXml((string) $name['title_suffix']) . '"';
                     }
                 }
                 if (isset($xml->event_fact)) {
                     foreach ($xml->event_fact as $ef) {
                         if ($ef['type'] == 'Birth') {
                             $result .= $this->getEventAttrs('birth', $ef);
                         } else {
                             if ($ef['type'] == 'Death') {
                                 $result .= $this->getEventAttrs('death', $ef);
                             } else {
                                 if ($ef['type'] == 'Christening' || $ef['type'] == 'Baptism') {
                                     $result .= $this->getEventAttrs('chr', $ef);
                                 } else {
                                     if ($ef['type'] == 'Burial') {
                                         $result .= $this->getEventAttrs('burial', $ef);
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     return $result;
 }
Example #24
0
 /**
  * Propagate data in xml property to other articles if necessary
  * @param string $oldText contains text being replaced
  * @param String $text which we never touch when propagating places
  * @param bool $textChanged which we never touch when propagating places
  * @return bool true if propagation was successful
  */
 protected function propagateEditData($oldText, &$text, &$textChanged)
 {
     global $wrIsGedcomUpload, $wgESINHandler;
     $result = true;
     // cache new xml - it's used right away to generate family badges on the related person pages,
     // if you don't cache it, the badges pick up the old html
     $this->cachePageXml();
     // update people that link to this family, because the family-badge contents could have changed
     // TODO this could be made more efficient by only invalidating if names, birthdates, or deathdates have changed
     $u = new HTMLCacheUpdate($this->title, 'pagelinks');
     $u->doUpdate();
     // get current info
     $propagatedData = Family::getPropagatedData($this->xml);
     $redirTitle = Title::newFromRedirect($text);
     // get original info
     $origPropagatedData = Family::getPropagatedData(null);
     // don't bother construction page text from WLH in a gedcom upload because nothing will link to this new page
     if (!@$wrIsGedcomUpload && (!$oldText || mb_strpos($oldText, '<family>') === false)) {
         // oldText contains MediaWiki:noarticletext if the article is being created
         // construct <family> text from What Links Here
         $oldText = $this->getPageTextFromWLH(false);
     }
     $origXml = null;
     if ($oldText) {
         $origXml = StructuredData::getXml('family', $oldText);
         if (isset($origXml)) {
             $origPropagatedData = Family::getPropagatedData($origXml);
         }
     }
     // TODO!!!
     // Revert, Unmerge, and eventually Undo should be getting the current attrs for existing people from origPropagatedData
     // and getting the current attrs and redirect-titles for newly-added people from the Person pages when adding the family title to them
     // then unmerge wouldn't need to get them in unmerge, and revert wouldn't be broken, and undo won't break things.
     // This duplicates the functionality found in fromEditFields, but it allows us to update the pages without going through fromEditFields
     // and it doesn't require reading any pages that we weren't reading already.
     // Also, instead of isMerging, if this Family page is on the propagation manager blacklist, then you can't trust the prior version
     // and we should get the person attrs from the Person pages for _all_ family members.
     // Finally, make sure that after redirects we don't have 2 links to the same Person (and also two links to the same Family on Person pages).
     // ignore changes of the husband <-> wife role for the same person
     $temp = array_diff($propagatedData['husbands'], $origPropagatedData['wives']);
     $origPropagatedData['wives'] = array_diff($origPropagatedData['wives'], $propagatedData['husbands']);
     $propagatedData['husbands'] = $temp;
     $temp = array_diff($propagatedData['wives'], $origPropagatedData['husbands']);
     $origPropagatedData['husbands'] = array_diff($origPropagatedData['husbands'], $propagatedData['wives']);
     $propagatedData['wives'] = $temp;
     $result = $result && $this->propagateFamilyMemberEditData($propagatedData['husbands'], $origPropagatedData['husbands'], 'husband', 'spouse_of_family', $text, $textChanged);
     $result = $result && $this->propagateFamilyMemberEditData($propagatedData['wives'], $origPropagatedData['wives'], 'wife', 'spouse_of_family', $text, $textChanged);
     $result = $result && $this->propagateFamilyMemberEditData($propagatedData['children'], $origPropagatedData['children'], 'child', 'child_of_family', $text, $textChanged);
     if (StructuredData::removeDuplicateLinks('husband|wife|child', $text)) {
         $textChanged = true;
     }
     $result = $result && $wgESINHandler->propagateSINEdit($this->title, 'family', $this->titleString, $propagatedData, $origPropagatedData, $text, $textChanged);
     // ensure footer tag is still there (might have been removed by editing the last section)
     if ($redirTitle == null && strpos($text, ESINHandler::ESIN_FOOTER_TAG) === false) {
         if (strlen($text) > 0 && substr($text, strlen($text) - 1) != "\n") {
             $text .= "\n";
         }
         $text .= ESINHandler::ESIN_FOOTER_TAG;
         $textChanged = true;
     }
     // update watchlist summary if changed
     $summary = Family::getSummary($this->xml, $this->title);
     $origSummary = Family::getSummary($origXml, $this->title);
     if ($summary != $origSummary) {
         StructuredData::updateWatchlistSummary($this->title, $summary);
     }
     // if it's a redirect, add the people, families, and images that were on this page to the redirect target
     // but don't bother updating the redir target during a merge
     if ($redirTitle != null && PropagationManager::isPropagatablePage($redirTitle)) {
         // get the text of the redir page
         $article = StructuredData::getArticle($redirTitle, true);
         if ($article) {
             $content =& $article->fetchContent();
             $updated = false;
             // add husbands from this page to the redir page
             foreach ($origPropagatedData['husbands'] as $p) {
                 // get propagated data for p
                 $pd = Person::getPropagatedData(StructuredData::getXmlForTitle('person', Title::newFromText($p, NS_PERSON)));
                 Family::updatePersonLink('husband', $p, $p, $pd, 'spouse_of_family', $content, $updated);
             }
             // add wives from this page to the redir page
             foreach ($origPropagatedData['wives'] as $p) {
                 $pd = Person::getPropagatedData(StructuredData::getXmlForTitle('person', Title::newFromText($p, NS_PERSON)));
                 Family::updatePersonLink('wife', $p, $p, $pd, 'spouse_of_family', $content, $updated);
             }
             // add children from this page to the redir page
             foreach ($origPropagatedData['children'] as $p) {
                 $pd = Person::getPropagatedData(StructuredData::getXmlForTitle('person', Title::newFromText($p, NS_PERSON)));
                 Family::updatePersonLink('child', $p, $p, $pd, 'child_of_family', $content, $updated);
             }
             // add images from this page to the redir page
             foreach ($origPropagatedData['images'] as $i) {
                 ESINHandler::updateImageLink('family', $i['filename'], $i['filename'], $i['caption'], $content, $updated);
             }
             // update the redir page if necessary
             if ($updated) {
                 $result = $result && $article->doEdit($content, 'Copy data from [[' . $this->title->getPrefixedText() . ']]', PROPAGATE_EDIT_FLAGS);
             }
         }
     }
     if (!$result) {
         error_log("ERROR! Family edit/rollback not propagated: {$this->titleString}\n");
     }
     return $result;
 }
Example #25
0
 /**
  * Return an auto-generated summary if the text provided is a redirect.
  *
  * @param  string $text The wikitext to check
  * @return string '' or an appropriate summary
  */
 public static function getRedirectAutosummary($text)
 {
     $rt = Title::newFromRedirect($text);
     if (is_object($rt)) {
         return wfMsgForContent('autoredircomment', $rt->getFullText());
     } else {
         return '';
     }
 }
Example #26
0
 /**
  * Attempt submission (no UI)
  * @return one of the constants describing the result
  */
 function internalAttemptSave(&$result, $bot = false)
 {
     global $wgFilterCallback, $wgUser, $wgOut, $wgParser;
     global $wgMaxArticleSize;
     $fname = 'EditPage::attemptSave';
     wfProfileIn($fname);
     wfProfileIn("{$fname}-checks");
     if (!wfRunHooks('EditPage::attemptSave', array(&$this))) {
         wfDebug("Hook 'EditPage::attemptSave' aborted article saving\n");
         return self::AS_HOOK_ERROR;
     }
     # Check image redirect
     if ($this->mTitle->getNamespace() == NS_FILE && Title::newFromRedirect($this->textbox1) instanceof Title && !$wgUser->isAllowed('upload')) {
         if ($wgUser->isAnon()) {
             return self::AS_IMAGE_REDIRECT_ANON;
         } else {
             return self::AS_IMAGE_REDIRECT_LOGGED;
         }
     }
     # Reintegrate metadata
     if ($this->mMetaData != '') {
         $this->textbox1 .= "\n" . $this->mMetaData;
     }
     $this->mMetaData = '';
     # Check for spam
     $match = self::matchSummarySpamRegex($this->summary);
     if ($match === false) {
         $match = self::matchSpamRegex($this->textbox1);
     }
     if ($match !== false) {
         $result['spam'] = $match;
         $ip = wfGetIP();
         $pdbk = $this->mTitle->getPrefixedDBkey();
         $match = str_replace("\n", '', $match);
         wfDebugLog('SpamRegex', "{$ip} spam regex hit [[{$pdbk}]]: \"{$match}\"");
         wfProfileOut("{$fname}-checks");
         wfProfileOut($fname);
         return self::AS_SPAM_ERROR;
     }
     if ($wgFilterCallback && $wgFilterCallback($this->mTitle, $this->textbox1, $this->section, $this->hookError, $this->summary)) {
         # Error messages or other handling should be performed by the filter function
         wfProfileOut("{$fname}-checks");
         wfProfileOut($fname);
         return self::AS_FILTERING;
     }
     if (!wfRunHooks('EditFilter', array($this, $this->textbox1, $this->section, &$this->hookError, $this->summary))) {
         # Error messages etc. could be handled within the hook...
         wfProfileOut("{$fname}-checks");
         wfProfileOut($fname);
         return self::AS_HOOK_ERROR;
     } elseif ($this->hookError != '') {
         # ...or the hook could be expecting us to produce an error
         wfProfileOut("{$fname}-checks");
         wfProfileOut($fname);
         return self::AS_HOOK_ERROR_EXPECTED;
     }
     if ($wgUser->isBlockedFrom($this->mTitle, false)) {
         # Check block state against master, thus 'false'.
         wfProfileOut("{$fname}-checks");
         wfProfileOut($fname);
         return self::AS_BLOCKED_PAGE_FOR_USER;
     }
     $this->kblength = (int) (strlen($this->textbox1) / 1024);
     if ($this->kblength > $wgMaxArticleSize) {
         // Error will be displayed by showEditForm()
         $this->tooBig = true;
         wfProfileOut("{$fname}-checks");
         wfProfileOut($fname);
         return self::AS_CONTENT_TOO_BIG;
     }
     if (!$wgUser->isAllowed('edit')) {
         if ($wgUser->isAnon()) {
             wfProfileOut("{$fname}-checks");
             wfProfileOut($fname);
             return self::AS_READ_ONLY_PAGE_ANON;
         } else {
             wfProfileOut("{$fname}-checks");
             wfProfileOut($fname);
             return self::AS_READ_ONLY_PAGE_LOGGED;
         }
     }
     if (wfReadOnly()) {
         wfProfileOut("{$fname}-checks");
         wfProfileOut($fname);
         return self::AS_READ_ONLY_PAGE;
     }
     if ($wgUser->pingLimiter()) {
         wfProfileOut("{$fname}-checks");
         wfProfileOut($fname);
         return self::AS_RATE_LIMITED;
     }
     # If the article has been deleted while editing, don't save it without
     # confirmation
     if ($this->wasDeletedSinceLastEdit() && !$this->recreate) {
         wfProfileOut("{$fname}-checks");
         wfProfileOut($fname);
         return self::AS_ARTICLE_WAS_DELETED;
     }
     wfProfileOut("{$fname}-checks");
     # If article is new, insert it.
     $aid = $this->mTitle->getArticleID(GAID_FOR_UPDATE);
     if (0 == $aid) {
         // Late check for create permission, just in case *PARANOIA*
         if (!$this->mTitle->userCan('create')) {
             wfDebug("{$fname}: no create permission\n");
             wfProfileOut($fname);
             return self::AS_NO_CREATE_PERMISSION;
         }
         # Don't save a new article if it's blank.
         if ('' == $this->textbox1) {
             wfProfileOut($fname);
             return self::AS_BLANK_ARTICLE;
         }
         // Run post-section-merge edit filter
         if (!wfRunHooks('EditFilterMerged', array($this, $this->textbox1, &$this->hookError, $this->summary))) {
             # Error messages etc. could be handled within the hook...
             wfProfileOut($fname);
             return self::AS_HOOK_ERROR;
         }
         # Handle the user preference to force summaries here. Check if it's not a redirect.
         if (!$this->allowBlankSummary && !Title::newFromRedirect($this->textbox1)) {
             if (md5($this->summary) == $this->autoSumm) {
                 $this->missingSummary = true;
                 wfProfileOut($fname);
                 return self::AS_SUMMARY_NEEDED;
             }
         }
         $isComment = $this->section == 'new';
         $this->mArticle->insertNewArticle($this->textbox1, $this->summary, $this->minoredit, $this->watchthis, false, $isComment, $bot);
         wfProfileOut($fname);
         return self::AS_SUCCESS_NEW_ARTICLE;
     }
     # Article exists. Check for edit conflict.
     $this->mArticle->clear();
     # Force reload of dates, etc.
     $this->mArticle->forUpdate(true);
     # Lock the article
     wfDebug("timestamp: {$this->mArticle->getTimestamp()}, edittime: {$this->edittime}\n");
     if ($this->mArticle->getTimestamp() != $this->edittime) {
         $this->isConflict = true;
         if ($this->section == 'new') {
             if ($this->mArticle->getUserText() == $wgUser->getName() && $this->mArticle->getComment() == $this->summary) {
                 // Probably a duplicate submission of a new comment.
                 // This can happen when squid resends a request after
                 // a timeout but the first one actually went through.
                 wfDebug("EditPage::editForm duplicate new section submission; trigger edit conflict!\n");
             } else {
                 // New comment; suppress conflict.
                 $this->isConflict = false;
                 wfDebug("EditPage::editForm conflict suppressed; new section\n");
             }
         }
     }
     $userid = $wgUser->getId();
     # Suppress edit conflict with self, except for section edits where merging is required.
     if ($this->isConflict && $this->section == '' && $this->userWasLastToEdit($userid, $this->edittime)) {
         wfDebug("EditPage::editForm Suppressing edit conflict, same user.\n");
         $this->isConflict = false;
     }
     if ($this->isConflict) {
         wfDebug("EditPage::editForm conflict! getting section '{$this->section}' for time '{$this->edittime}' (article time '" . $this->mArticle->getTimestamp() . "')\n");
         $text = $this->mArticle->replaceSection($this->section, $this->textbox1, $this->summary, $this->edittime);
     } else {
         wfDebug("EditPage::editForm getting section '{$this->section}'\n");
         $text = $this->mArticle->replaceSection($this->section, $this->textbox1, $this->summary);
     }
     if (is_null($text)) {
         wfDebug("EditPage::editForm activating conflict; section replace failed.\n");
         $this->isConflict = true;
         $text = $this->textbox1;
         // do not try to merge here!
     } else {
         if ($this->isConflict) {
             # Attempt merge
             if ($this->mergeChangesInto($text)) {
                 // Successful merge! Maybe we should tell the user the good news?
                 $this->isConflict = false;
                 wfDebug("EditPage::editForm Suppressing edit conflict, successful merge.\n");
             } else {
                 $this->section = '';
                 $this->textbox1 = $text;
                 wfDebug("EditPage::editForm Keeping edit conflict, failed merge.\n");
             }
         }
     }
     if ($this->isConflict) {
         wfProfileOut($fname);
         return self::AS_CONFLICT_DETECTED;
     }
     $oldtext = $this->mArticle->getContent();
     // Run post-section-merge edit filter
     if (!wfRunHooks('EditFilterMerged', array($this, $text, &$this->hookError, $this->summary))) {
         # Error messages etc. could be handled within the hook...
         wfProfileOut($fname);
         return self::AS_HOOK_ERROR;
     }
     # Handle the user preference to force summaries here, but not for null edits
     if ($this->section != 'new' && !$this->allowBlankSummary && 0 != strcmp($oldtext, $text) && !Title::newFromRedirect($text)) {
         if (md5($this->summary) == $this->autoSumm) {
             $this->missingSummary = true;
             wfProfileOut($fname);
             return self::AS_SUMMARY_NEEDED;
         }
     }
     # And a similar thing for new sections
     if ($this->section == 'new' && !$this->allowBlankSummary) {
         if (trim($this->summary) == '') {
             $this->missingSummary = true;
             wfProfileOut($fname);
             return self::AS_SUMMARY_NEEDED;
         }
     }
     # All's well
     wfProfileIn("{$fname}-sectionanchor");
     $sectionanchor = '';
     if ($this->section == 'new') {
         if ($this->textbox1 == '') {
             $this->missingComment = true;
             return self::AS_TEXTBOX_EMPTY;
         }
         if ($this->summary != '') {
             $sectionanchor = $wgParser->guessSectionNameFromWikiText($this->summary);
             # This is a new section, so create a link to the new section
             # in the revision summary.
             $cleanSummary = $wgParser->stripSectionName($this->summary);
             $this->summary = wfMsgForContent('newsectionsummary', $cleanSummary);
         }
     } elseif ($this->section != '') {
         # Try to get a section anchor from the section source, redirect to edited section if header found
         # XXX: might be better to integrate this into Article::replaceSection
         # for duplicate heading checking and maybe parsing
         $hasmatch = preg_match("/^ *([=]{1,6})(.*?)(\\1) *\\n/i", $this->textbox1, $matches);
         # we can't deal with anchors, includes, html etc in the header for now,
         # headline would need to be parsed to improve this
         if ($hasmatch and strlen($matches[2]) > 0) {
             $sectionanchor = $wgParser->guessSectionNameFromWikiText($matches[2]);
         }
     }
     wfProfileOut("{$fname}-sectionanchor");
     // Save errors may fall down to the edit form, but we've now
     // merged the section into full text. Clear the section field
     // so that later submission of conflict forms won't try to
     // replace that into a duplicated mess.
     $this->textbox1 = $text;
     $this->section = '';
     // Check for length errors again now that the section is merged in
     $this->kblength = (int) (strlen($text) / 1024);
     if ($this->kblength > $wgMaxArticleSize) {
         $this->tooBig = true;
         wfProfileOut($fname);
         return self::AS_MAX_ARTICLE_SIZE_EXCEEDED;
     }
     # update the article here
     if ($this->mArticle->updateArticle($text, $this->summary, $this->minoredit, $this->watchthis, $bot, $sectionanchor)) {
         wfProfileOut($fname);
         return self::AS_SUCCESS_UPDATE;
     } else {
         $this->isConflict = true;
     }
     wfProfileOut($fname);
     return self::AS_END;
 }
 function buildCurrentSlide($page, $notoc)
 {
     global $wgScript, $wgParser;
     if (trim($page) == "") {
         return "";
     }
     $link = $wgScript . "?title={$page}";
     $article = new Article(Title::newFromText($page));
     while ($article->isRedirect()) {
         $redirectedArticleTitle = Title::newFromRedirect($article->getContent());
         $article = new Article($redirectedArticleTitle);
     }
     if ($article->exists()) {
         $slideBody = $article->getContent() . $notoc . " __NOEDITSECTION__";
     } else {
         $slideBody = "The [[{$page}]] slide does not exist. Did you want to <b>[[{$page} | create]]</b> it?";
     }
     $this->currentPageLink = "<a href='{$link}'>{$page}</a>";
     //html
     $this->slideBody = $wgParser->recursiveTagParse($slideBody);
     //wiki markup converted to html
 }
Example #28
0
 function ProcessContractorEditChanges($doit)
 {
     global $wgOut, $wgUser, $wgRequest;
     global $wgServer, $wgArticlePath;
     $debug = 1;
     $dbr = wfGetDB(DB_SLAVE);
     # first lets process the changes to the existing entries
     $contractorId = $wgRequest->getInt('contractor', 0);
     $modify_array = $wgRequest->getArray('cb_modify', array());
     $NewExpiryDate = $wgRequest->getVal('NewExpiryDate', '');
     $action = $wgRequest->getVal('action', '');
     if (!$doit) {
         # create the form for submitting the same data after review
         $wgOut->addHTML("<form name='mainform' method='post'>");
         $wgOut->addHTML("<input type='hidden' name='contractor' value='{$contractorId}'>");
         foreach ($modify_array as $modify) {
             $wgOut->addHTML("<input type='hidden' name='cb_modify[]' value='{$modify}'>");
         }
         $wgOut->addHTML("<input type='hidden' name='NewExpiryDate' value='{$NewExpiryDate}'>");
         $wgOut->addHTML("<input type='hidden' name='action' value='{$action}'>");
         $ContractorUser = WhiteListUserFromID($contractorId);
         $wgOut->addWikiText(wfMsg('whitelistoverview', $ContractorUser->getRealName()));
     }
     if ($action == 'ChangeDate') {
         $date = $NewExpiryDate == '' ? "" : date("Y-m-d H:i:s", strtotime($NewExpiryDate));
         foreach ($modify_array as $entry => $rowid) {
             $dbr->begin();
             if ($doit) {
                 $dbr->update('whitelist', array('wl_expires_on' => $date, 'wl_updated_by_user_id' => $wgUser->getId()), array('wl_id' => $rowid), __METHOD__);
             } else {
                 $pagename = $dbr->selectField('whitelist', 'wl_page_title', array('wl_id' => $rowid), __METHOD__);
                 $wgOut->addWikiText(wfMsg('whitelistoverviewcd', $date, $pagename));
             }
             $dbr->commit();
         }
     } else {
         if ($action == 'SetEdit' || $action == 'SetView') {
             foreach ($modify_array as $entry => $rowid) {
                 $dbr->begin();
                 if ($doit) {
                     $dbr->update('whitelist', array('wl_allow_edit' => $action == 'SetEdit' ? 1 : 0, 'wl_updated_by_user_id' => $wgUser->getId()), array('wl_id' => $rowid), __METHOD__);
                 } else {
                     $pagename = $dbr->selectField('whitelist', 'wl_page_title', array('wl_id' => $rowid), __METHOD__);
                     $wgOut->addWikiText(wfMsg('whitelistoverviewsa', $action == 'SetEdit' ? wfMsg('whitelisttablesetedit') : wfMsg('whitelisttablesetview'), $pagename));
                 }
                 $dbr->commit();
             }
         } else {
             if ($action == 'Remove') {
                 foreach ($modify_array as $entry => $rowid) {
                     $dbr->begin();
                     if ($doit) {
                         $dbr->delete('whitelist', array('wl_id' => $rowid), __METHOD__);
                     } else {
                         $pagename = $dbr->selectField('whitelist', 'wl_page_title', array('wl_id' => $rowid), __METHOD__);
                         self::DisplayWildCardMatches($pagename, wfMsg('whitelistoverviewrm', $pagename), -1);
                     }
                     $dbr->commit();
                 }
             }
         }
     }
     # now process the new additions, but make sure not to add duplicates
     $newPages = $wgRequest->getVal('newPages', '');
     $expiryDate = $wgRequest->getVal('ExpiryDate', '');
     $newAction = $wgRequest->getVal('newAction', '');
     if (!$doit) {
         $wgOut->addHTML("<input type='hidden' name='newPages' value='{$newPages}'>");
         $wgOut->addHTML("<input type='hidden' name='ExpiryDate' value='{$expiryDate}'>");
         $wgOut->addHTML("<input type='hidden' name='newAction' value='{$newAction}'>");
     }
     $pages = preg_split('/\\n/', $newPages, -1, PREG_SPLIT_NO_EMPTY);
     foreach ($pages as $entry => $pagename) {
         $pagename = trim($pagename);
         if ($pagename == '') {
             continue;
         }
         # If the input is a URL, then convert it back to a title
         $myArticlePath = str_replace("\$1", '', $wgArticlePath);
         $myArticlePath = str_replace("/", '\\/', $myArticlePath);
         $myServer = str_replace("/", '\\/', $wgServer);
         if (preg_match("/^{$myServer}{$myArticlePath}(.*)\$/", $pagename, $matches)) {
             $pagename = preg_replace('/_/', ' ', $matches[1]);
         }
         # ensure we have a wildcard of %
         $pagename = str_replace('*', '%', $pagename);
         if ($doit) {
             self::insertNewPage($dbr, $contractorId, $pagename, $newAction, $expiryDate);
         } else {
             self::DisplayWildCardMatches($pagename, wfMsg('whitelistoverviewna', $pagename, $newAction == 'SetEdit' ? wfMsg('whitelisttablesetedit') : wfMsg('whitelisttablesetview'), $expiryDate == '' ? wfMsg('whitelistnever') : $expiryDate), -1);
         }
         # check to see if the page is a redirect and if so, add the redirected-to page also
         $title = Title::newFromText($pagename);
         if ($title) {
             $article = new Article($title);
             $pagetext = $article->getContent();
             $redirecttitle = Title::newFromRedirect($pagetext);
             if ($redirecttitle) {
                 if ($doit) {
                     self::insertNewPage($dbr, $contractorId, $redirecttitle->getPrefixedText(), $newAction, $expiryDate);
                 } else {
                     $wgOut->addWikiText(wfMsg('whitelistoverviewna', $redirecttitle->getPrefixedText(), $newAction == 'SetEdit' ? wfMsg('whitelisttablesetedit') : wfMsg('whitelisttablesetview'), $expiryDate));
                 }
             }
         }
     }
     if (!$doit) {
         $wgOut->addHTML("<p><input type='submit' value='" . wfMsg('whitelistnewtableprocess') . "' />");
         $wgOut->addHTML("</form>");
     }
     return;
 }
Example #29
0
 /**
  * Display a moved thread
  *
  * @param $thread Thread
  * @throws Exception
  */
 function showMovedThread($thread)
 {
     global $wgLang;
     // Grab target thread
     if (!$thread->title()) {
         return;
         // Odd case: moved thread with no title?
     }
     $article = new Article($thread->title(), 0);
     $target = Title::newFromRedirect($article->getContent());
     if (!$target) {
         throw new Exception("Thread " . $thread->id() . ' purports to be moved, ' . 'but no redirect found in text (' . $article->getContent() . ') of ' . $thread->root()->getTitle()->getPrefixedText() . '. Dying.');
     }
     $t_thread = Threads::withRoot(new Article($target, 0));
     // Grab data about the new post.
     $author = $thread->author();
     $sig = Linker::userLink($author->getID(), $author->getName()) . Linker::userToolLinks($author->getID(), $author->getName());
     $newTalkpage = is_object($t_thread) ? $t_thread->getTitle() : '';
     $html = wfMessage('lqt_move_placeholder')->rawParams(Linker::link($target), $sig)->params($wgLang->date($thread->modified()), $wgLang->time($thread->modified()))->rawParams(Linker::link($newTalkpage))->parse();
     $this->output->addHTML($html);
 }
 private function getRedirectTargets()
 {
     $linkBatch = new LinkBatch();
     $db = $this->getDB();
     // find redirect targets for all redirect pages
     $this->profileDBIn();
     $res = $db->select('pagelinks', array('pl_from', 'pl_namespace', 'pl_title'), array('pl_from' => array_keys($this->mPendingRedirectIDs)), __METHOD__);
     $this->profileDBOut();
     while ($row = $db->fetchObject($res)) {
         $plfrom = intval($row->pl_from);
         // Bug 7304 workaround
         // ( http://bugzilla.wikipedia.org/show_bug.cgi?id=7304 )
         // A redirect page may have more than one link.
         // This code will only use the first link returned.
         if (isset($this->mPendingRedirectIDs[$plfrom])) {
             // remove line when bug 7304 is fixed
             $titleStrFrom = $this->mPendingRedirectIDs[$plfrom]->getPrefixedText();
             $titleStrTo = Title::makeTitle($row->pl_namespace, $row->pl_title)->getPrefixedText();
             unset($this->mPendingRedirectIDs[$plfrom]);
             // remove line when bug 7304 is fixed
             // Avoid an infinite loop by checking if we have already processed this target
             if (!isset($this->mAllPages[$row->pl_namespace][$row->pl_title])) {
                 $linkBatch->add($row->pl_namespace, $row->pl_title);
             }
         } else {
             // This redirect page has more than one link.
             // This is very slow, but safer until bug 7304 is resolved
             $title = Title::newFromID($plfrom);
             $titleStrFrom = $title->getPrefixedText();
             $article = new Article($title);
             $text = $article->getContent();
             $titleTo = Title::newFromRedirect($text);
             $titleStrTo = $titleTo->getPrefixedText();
             if (is_null($titleStrTo)) {
                 ApiBase::dieDebug(__METHOD__, 'Bug7304 workaround: redir target from {$title->getPrefixedText()} not found');
             }
             // Avoid an infinite loop by checking if we have already processed this target
             if (!isset($this->mAllPages[$titleTo->getNamespace()][$titleTo->getDBkey()])) {
                 $linkBatch->addObj($titleTo);
             }
         }
         $this->mRedirectTitles[$titleStrFrom] = $titleStrTo;
     }
     $db->freeResult($res);
     // All IDs must exist in the page table
     if (!empty($this->mPendingRedirectIDs[$plfrom])) {
         ApiBase::dieDebug(__METHOD__, 'Invalid redirect IDs were found');
     }
     return $linkBatch;
 }