function getFacebookHTML($showimages = false)
    {
        global $wgParser, $wgServer;
        $feeds = FeaturedArticles::getFeaturedArticles(1);
        $html = "<fb:title>The How-to Article of the Day</fb:title>\n\t\t\t\t<fb:subtitle><a href='http://www.wikihow.com'>from wikiHow</a></fb:subtitle>\n\t\t";
        $now = time();
        $dbr = wfGetDB(DB_SLAVE);
        foreach ($feeds as $f) {
            $url = $f[0];
            $d = $f[1];
            if ($d > $now) {
                continue;
            }
            $url = str_replace("http://www.wikihow.com/", "", $url);
            $url = str_replace("{$wgServer}/", "", $url);
            $title = Title::newFromURL(urldecode($url));
            // get last safe id
            $res = $dbr->select('revision', array('rev_user', 'rev_id', 'rev_user_text'), array('rev_page' => $title->getArticleId(), 'rev_user>0'), "wfGetFacebookHTML", array('ORDER BY' => 'rev_id desc'));
            $rev_id = 0;
            while ($row = $dbr->fetchObject($res)) {
                $num_edits = $dbr->selectField('revision', 'count(*)', array("rev_user={$row->rev_user}"));
                if ($num_edits > 300) {
                    $rev_id = $row->rev_id;
                    break;
                }
            }
            $dbr->freeResult($res);
            $revision = null;
            if ($rev_id > 0) {
                $revision = Revision::newFromID($rev_id);
            } else {
                $revision = Revision::newFromTitle($title);
            }
            $summary = Article::getSection($revision->getText(), 0);
            $summary = ereg_replace("\\{\\{.*\\}\\}", "", $summary);
            if (!$showimages) {
                $summary = preg_replace("/\\[\\[Image[^\\]]*\\]\\]/", "", $summary);
            }
            // strip images
            $output = $wgParser->parse($summary, $title, new ParserOptions());
            $summary = strip_tags($output->getText(), '<img>');
            $img = "";
            $style = 'style="float:right;margin-left:10px;margin-bottom:10px;"';
            if (strpos($summary, "<img") !== false && $showimages) {
                $re = '/<img[^>]*>/';
                preg_match_all($re, $summary, $matches);
                $summary = preg_replace($re, '', $summary);
                $img = $matches[0][0];
                preg_match_all('/width="[0-9]*"/', $img, $matches);
                $width = 200;
                if (sizeof($matches[0]) > 0) {
                    $s_width = str_replace('width=', '', $matches[0][0]);
                    $s_width = str_replace('"', '', $s_width);
                    $s_width = intval($s_width);
                    if ($s_width < $width) {
                        $width = $s_width;
                    }
                }
                $src = "";
                preg_match_all('/src="[^"]*"/', $img, $matches);
                if (sizeof($matches[0]) > 0) {
                    $src = str_replace("src=", "", $matches[0][0]);
                    $src = str_replace('"', "", $src);
                    if (strpos($src, "http://www.wikihow.com") === false) {
                        $src = "http://www.wikihow.com" . $src;
                    }
                }
                $img = "<img src=\"{$src}\" {$style} width=\"{$width}\">";
            } else {
                $img = "<img src=\"http://www.wikihow.com/skins/WikiHow/wikiHow.gif\" {$style} width=\"100\"/>";
            }
            $html .= "<p style=\"font-size:1.2em;margin:2px 0;\"><a href='{$title->getFullURL()}' style=\"font-weight:bold\">" . wfMsg('howto', $title->getText()) . '</a></p>';
            $html .= "<p>\n\t\t\t\t{$img} \n\t\t\t\t{$summary}\n\t\t\t\t</p>\n\t\t\t\t<p><a href='{$title->getFullURL()}'>Read more...</a></p>";
            $html .= '<table style="clear:both;margin:0 auto;"><tr><td>Do you want to do this? |&nbsp;
				</td><td >' . "<fb:share-button class='url' href='{$title->getFullURL()}'/> </td></tr></table>";
            break;
        }
        $html .= '<fb:if-is-own-profile>&nbsp;<fb:else><br/><div style="text-align:right;"><a href="http://apps.facebook.com/howtooftheday">Put this on my profile</a></div></fb:else></fb:if-is-own-profile>';
        return $html;
    }
Esempio n. 2
0
 public function execute()
 {
     // The data is hot but user-dependent, like page views, so we set vary cookies
     $this->getMain()->setCacheMode('anon-public-user-private');
     // Get parameters
     $params = $this->extractRequestParams();
     $text = $params['text'];
     $title = $params['title'];
     $page = $params['page'];
     $pageid = $params['pageid'];
     $oldid = $params['oldid'];
     $model = $params['contentmodel'];
     $format = $params['contentformat'];
     if (!is_null($page) && (!is_null($text) || $title != 'API')) {
         $this->dieUsage('The page parameter cannot be used together with the text and title parameters', 'params');
     }
     $prop = array_flip($params['prop']);
     if (isset($params['section'])) {
         $this->section = $params['section'];
     } else {
         $this->section = false;
     }
     // The parser needs $wgTitle to be set, apparently the
     // $title parameter in Parser::parse isn't enough *sigh*
     // TODO: Does this still need $wgTitle?
     global $wgParser, $wgTitle;
     // Currently unnecessary, code to act as a safeguard against any change in current behaviour of uselang breaks
     $oldLang = null;
     if (isset($params['uselang']) && $params['uselang'] != $this->getContext()->getLanguage()->getCode()) {
         $oldLang = $this->getContext()->getLanguage();
         // Backup language
         $this->getContext()->setLanguage(Language::factory($params['uselang']));
     }
     $redirValues = null;
     // Return result
     $result = $this->getResult();
     if (!is_null($oldid) || !is_null($pageid) || !is_null($page)) {
         if (!is_null($oldid)) {
             // Don't use the parser cache
             $rev = Revision::newFromID($oldid);
             if (!$rev) {
                 $this->dieUsage("There is no revision ID {$oldid}", 'missingrev');
             }
             if (!$rev->userCan(Revision::DELETED_TEXT, $this->getUser())) {
                 $this->dieUsage("You don't have permission to view deleted revisions", 'permissiondenied');
             }
             $titleObj = $rev->getTitle();
             $wgTitle = $titleObj;
             $pageObj = WikiPage::factory($titleObj);
             $popts = $pageObj->makeParserOptions($this->getContext());
             $popts->enableLimitReport(!$params['disablepp']);
             // If for some reason the "oldid" is actually the current revision, it may be cached
             if ($rev->isCurrent()) {
                 // May get from/save to parser cache
                 $p_result = $this->getParsedContent($pageObj, $popts, $pageid, isset($prop['wikitext']));
             } else {
                 // This is an old revision, so get the text differently
                 $this->content = $rev->getContent(Revision::FOR_THIS_USER, $this->getUser());
                 if ($this->section !== false) {
                     $this->content = $this->getSectionContent($this->content, 'r' . $rev->getId());
                 }
                 // Should we save old revision parses to the parser cache?
                 $p_result = $this->content->getParserOutput($titleObj, $rev->getId(), $popts);
             }
         } else {
             // Not $oldid, but $pageid or $page
             if ($params['redirects']) {
                 $reqParams = array('action' => 'query', 'redirects' => '');
                 if (!is_null($pageid)) {
                     $reqParams['pageids'] = $pageid;
                 } else {
                     // $page
                     $reqParams['titles'] = $page;
                 }
                 $req = new FauxRequest($reqParams);
                 $main = new ApiMain($req);
                 $main->execute();
                 $data = $main->getResultData();
                 $redirValues = isset($data['query']['redirects']) ? $data['query']['redirects'] : array();
                 $to = $page;
                 foreach ((array) $redirValues as $r) {
                     $to = $r['to'];
                 }
                 $pageParams = array('title' => $to);
             } elseif (!is_null($pageid)) {
                 $pageParams = array('pageid' => $pageid);
             } else {
                 // $page
                 $pageParams = array('title' => $page);
             }
             $pageObj = $this->getTitleOrPageId($pageParams, 'fromdb');
             $titleObj = $pageObj->getTitle();
             if (!$titleObj || !$titleObj->exists()) {
                 $this->dieUsage("The page you specified doesn't exist", 'missingtitle');
             }
             $wgTitle = $titleObj;
             if (isset($prop['revid'])) {
                 $oldid = $pageObj->getLatest();
             }
             $popts = $pageObj->makeParserOptions($this->getContext());
             $popts->enableLimitReport(!$params['disablepp']);
             // Potentially cached
             $p_result = $this->getParsedContent($pageObj, $popts, $pageid, isset($prop['wikitext']));
         }
     } else {
         // Not $oldid, $pageid, $page. Hence based on $text
         $titleObj = Title::newFromText($title);
         if (!$titleObj) {
             $this->dieUsageMsg(array('invalidtitle', $title));
         }
         if (!$titleObj->canExist()) {
             $this->dieUsage("Namespace doesn't allow actual pages", 'pagecannotexist');
         }
         $wgTitle = $titleObj;
         $pageObj = WikiPage::factory($titleObj);
         $popts = $pageObj->makeParserOptions($this->getContext());
         $popts->enableLimitReport(!$params['disablepp']);
         if (is_null($text)) {
             $this->dieUsage('The text parameter should be passed with the title parameter. Should you be using the "page" parameter instead?', 'params');
         }
         try {
             $this->content = ContentHandler::makeContent($text, $titleObj, $model, $format);
         } catch (MWContentSerializationException $ex) {
             $this->dieUsage($ex->getMessage(), 'parseerror');
         }
         if ($this->section !== false) {
             $this->content = $this->getSectionContent($this->content, $titleObj->getText());
         }
         if ($params['pst'] || $params['onlypst']) {
             $this->pstContent = $this->content->preSaveTransform($titleObj, $this->getUser(), $popts);
         }
         if ($params['onlypst']) {
             // Build a result and bail out
             $result_array = array();
             $result_array['text'] = array();
             $result->setContent($result_array['text'], $this->pstContent->serialize($format));
             if (isset($prop['wikitext'])) {
                 $result_array['wikitext'] = array();
                 $result->setContent($result_array['wikitext'], $this->content->serialize($format));
             }
             $result->addValue(null, $this->getModuleName(), $result_array);
             return;
         }
         // Not cached (save or load)
         if ($params['pst']) {
             $p_result = $this->pstContent->getParserOutput($titleObj, null, $popts);
         } else {
             $p_result = $this->content->getParserOutput($titleObj, null, $popts);
         }
     }
     $result_array = array();
     $result_array['title'] = $titleObj->getPrefixedText();
     if (!is_null($oldid)) {
         $result_array['revid'] = intval($oldid);
     }
     if ($params['redirects'] && !is_null($redirValues)) {
         $result_array['redirects'] = $redirValues;
     }
     if (isset($prop['text'])) {
         $result_array['text'] = array();
         $result->setContent($result_array['text'], $p_result->getText());
     }
     if (!is_null($params['summary'])) {
         $result_array['parsedsummary'] = array();
         $result->setContent($result_array['parsedsummary'], Linker::formatComment($params['summary'], $titleObj));
     }
     if (isset($prop['langlinks'])) {
         $result_array['langlinks'] = $this->formatLangLinks($p_result->getLanguageLinks());
     }
     if (isset($prop['languageshtml'])) {
         $languagesHtml = $this->languagesHtml($p_result->getLanguageLinks());
         $result_array['languageshtml'] = array();
         $result->setContent($result_array['languageshtml'], $languagesHtml);
     }
     if (isset($prop['categories'])) {
         $result_array['categories'] = $this->formatCategoryLinks($p_result->getCategories());
     }
     if (isset($prop['categorieshtml'])) {
         $categoriesHtml = $this->categoriesHtml($p_result->getCategories());
         $result_array['categorieshtml'] = array();
         $result->setContent($result_array['categorieshtml'], $categoriesHtml);
     }
     if (isset($prop['links'])) {
         $result_array['links'] = $this->formatLinks($p_result->getLinks());
     }
     if (isset($prop['templates'])) {
         $result_array['templates'] = $this->formatLinks($p_result->getTemplates());
     }
     if (isset($prop['images'])) {
         $result_array['images'] = array_keys($p_result->getImages());
     }
     if (isset($prop['externallinks'])) {
         $result_array['externallinks'] = array_keys($p_result->getExternalLinks());
     }
     if (isset($prop['sections'])) {
         $result_array['sections'] = $p_result->getSections();
     }
     if (isset($prop['displaytitle'])) {
         $result_array['displaytitle'] = $p_result->getDisplayTitle() ? $p_result->getDisplayTitle() : $titleObj->getPrefixedText();
     }
     if (isset($prop['headitems']) || isset($prop['headhtml'])) {
         $context = $this->getContext();
         $context->setTitle($titleObj);
         $context->getOutput()->addParserOutputNoText($p_result);
         if (isset($prop['headitems'])) {
             $headItems = $this->formatHeadItems($p_result->getHeadItems());
             $css = $this->formatCss($context->getOutput()->buildCssLinksArray());
             $scripts = array($context->getOutput()->getHeadScripts());
             $result_array['headitems'] = array_merge($headItems, $css, $scripts);
         }
         if (isset($prop['headhtml'])) {
             $result_array['headhtml'] = array();
             $result->setContent($result_array['headhtml'], $context->getOutput()->headElement($context->getSkin()));
         }
     }
     if (isset($prop['iwlinks'])) {
         $result_array['iwlinks'] = $this->formatIWLinks($p_result->getInterwikiLinks());
     }
     if (isset($prop['wikitext'])) {
         $result_array['wikitext'] = array();
         $result->setContent($result_array['wikitext'], $this->content->serialize($format));
         if (!is_null($this->pstContent)) {
             $result_array['psttext'] = array();
             $result->setContent($result_array['psttext'], $this->pstContent->serialize($format));
         }
     }
     if (isset($prop['properties'])) {
         $result_array['properties'] = $this->formatProperties($p_result->getProperties());
     }
     if ($params['generatexml']) {
         if ($this->content->getModel() != CONTENT_MODEL_WIKITEXT) {
             $this->dieUsage("generatexml is only supported for wikitext content", "notwikitext");
         }
         $wgParser->startExternalParse($titleObj, $popts, OT_PREPROCESS);
         $dom = $wgParser->preprocessToDom($this->content->getNativeData());
         if (is_callable(array($dom, 'saveXML'))) {
             $xml = $dom->saveXML();
         } else {
             $xml = $dom->__toString();
         }
         $result_array['parsetree'] = array();
         $result->setContent($result_array['parsetree'], $xml);
     }
     $result_mapping = array('redirects' => 'r', 'langlinks' => 'll', 'categories' => 'cl', 'links' => 'pl', 'templates' => 'tl', 'images' => 'img', 'externallinks' => 'el', 'iwlinks' => 'iw', 'sections' => 's', 'headitems' => 'hi', 'properties' => 'pp');
     $this->setIndexedTagNames($result_array, $result_mapping);
     $result->addValue(null, $this->getModuleName(), $result_array);
     if (!is_null($oldLang)) {
         $this->getContext()->setLanguage($oldLang);
         // Reset language to $oldLang
     }
 }
Esempio n. 3
0
 public function execute()
 {
     global $wgUser;
     $params = $this->extractRequestParams();
     if (is_null($params['text']) && is_null($params['appendtext']) && is_null($params['prependtext']) && $params['undo'] == 0) {
         $this->dieUsageMsg(array('missingtext'));
     }
     $titleObj = Title::newFromText($params['title']);
     if (!$titleObj || $titleObj->isExternal()) {
         $this->dieUsageMsg(array('invalidtitle', $params['title']));
     }
     if ($params['redirect']) {
         if ($titleObj->isRedirect()) {
             $oldTitle = $titleObj;
             $titles = Title::newFromRedirectArray(Revision::newFromTitle($oldTitle)->getText(Revision::FOR_THIS_USER));
             $redirValues = array();
             foreach ($titles as $id => $newTitle) {
                 if (!isset($titles[$id - 1])) {
                     $titles[$id - 1] = $oldTitle;
                 }
                 $redirValues[] = array('from' => $titles[$id - 1]->getPrefixedText(), 'to' => $newTitle->getPrefixedText());
                 $titleObj = $newTitle;
             }
             $this->getResult()->setIndexedTagName($redirValues, 'r');
             $this->getResult()->addValue(null, 'redirects', $redirValues);
         }
     }
     // Some functions depend on $wgTitle == $ep->mTitle
     global $wgTitle;
     $wgTitle = $titleObj;
     if ($params['createonly'] && $titleObj->exists()) {
         $this->dieUsageMsg(array('createonly-exists'));
     }
     if ($params['nocreate'] && !$titleObj->exists()) {
         $this->dieUsageMsg(array('nocreate-missing'));
     }
     // Now let's check whether we're even allowed to do this
     $errors = $titleObj->getUserPermissionsErrors('edit', $wgUser);
     if (!$titleObj->exists()) {
         $errors = array_merge($errors, $titleObj->getUserPermissionsErrors('create', $wgUser));
     }
     if (count($errors)) {
         $this->dieUsageMsg($errors[0]);
     }
     $articleObj = new Article($titleObj);
     $toMD5 = $params['text'];
     if (!is_null($params['appendtext']) || !is_null($params['prependtext'])) {
         // For non-existent pages, Article::getContent()
         // returns an interface message rather than ''
         // We do want getContent()'s behavior for non-existent
         // MediaWiki: pages, though
         if ($articleObj->getID() == 0 && $titleObj->getNamespace() != NS_MEDIAWIKI) {
             $content = '';
         } else {
             $content = $articleObj->getContent();
         }
         if (!is_null($params['section'])) {
             // Process the content for section edits
             global $wgParser;
             $section = intval($params['section']);
             $content = $wgParser->getSection($content, $section, false);
             if ($content === false) {
                 $this->dieUsage("There is no section {$section}.", 'nosuchsection');
             }
         }
         $params['text'] = $params['prependtext'] . $content . $params['appendtext'];
         $toMD5 = $params['prependtext'] . $params['appendtext'];
     }
     if ($params['undo'] > 0) {
         if ($params['undoafter'] > 0) {
             if ($params['undo'] < $params['undoafter']) {
                 list($params['undo'], $params['undoafter']) = array($params['undoafter'], $params['undo']);
             }
             $undoafterRev = Revision::newFromID($params['undoafter']);
         }
         $undoRev = Revision::newFromID($params['undo']);
         if (is_null($undoRev) || $undoRev->isDeleted(Revision::DELETED_TEXT)) {
             $this->dieUsageMsg(array('nosuchrevid', $params['undo']));
         }
         if ($params['undoafter'] == 0) {
             $undoafterRev = $undoRev->getPrevious();
         }
         if (is_null($undoafterRev) || $undoafterRev->isDeleted(Revision::DELETED_TEXT)) {
             $this->dieUsageMsg(array('nosuchrevid', $params['undoafter']));
         }
         if ($undoRev->getPage() != $articleObj->getID()) {
             $this->dieUsageMsg(array('revwrongpage', $undoRev->getID(), $titleObj->getPrefixedText()));
         }
         if ($undoafterRev->getPage() != $articleObj->getID()) {
             $this->dieUsageMsg(array('revwrongpage', $undoafterRev->getID(), $titleObj->getPrefixedText()));
         }
         $newtext = $articleObj->getUndoText($undoRev, $undoafterRev);
         if ($newtext === false) {
             $this->dieUsageMsg(array('undo-failure'));
         }
         $params['text'] = $newtext;
         // If no summary was given and we only undid one rev,
         // use an autosummary
         if (is_null($params['summary']) && $titleObj->getNextRevisionID($undoafterRev->getID()) == $params['undo']) {
             $params['summary'] = wfMsgForContent('undo-summary', $params['undo'], $undoRev->getUserText());
         }
     }
     // See if the MD5 hash checks out
     if (!is_null($params['md5']) && md5($toMD5) !== $params['md5']) {
         $this->dieUsageMsg(array('hashcheckfailed'));
     }
     $ep = new EditPage($articleObj);
     // EditPage wants to parse its stuff from a WebRequest
     // That interface kind of sucks, but it's workable
     $reqArr = array('wpTextbox1' => $params['text'], 'wpEditToken' => $params['token'], 'wpIgnoreBlankSummary' => '');
     if (!is_null($params['summary'])) {
         $reqArr['wpSummary'] = $params['summary'];
     }
     // Watch out for basetimestamp == ''
     // wfTimestamp() treats it as NOW, almost certainly causing an edit conflict
     if (!is_null($params['basetimestamp']) && $params['basetimestamp'] != '') {
         $reqArr['wpEdittime'] = wfTimestamp(TS_MW, $params['basetimestamp']);
     } else {
         $reqArr['wpEdittime'] = $articleObj->getTimestamp();
     }
     if (!is_null($params['starttimestamp']) && $params['starttimestamp'] != '') {
         $reqArr['wpStarttime'] = wfTimestamp(TS_MW, $params['starttimestamp']);
     } else {
         $reqArr['wpStarttime'] = wfTimestampNow();
         // Fake wpStartime
     }
     if ($params['minor'] || !$params['notminor'] && $wgUser->getOption('minordefault')) {
         $reqArr['wpMinoredit'] = '';
     }
     if ($params['recreate']) {
         $reqArr['wpRecreate'] = '';
     }
     if (!is_null($params['section'])) {
         $section = intval($params['section']);
         if ($section == 0 && $params['section'] != '0' && $params['section'] != 'new') {
             $this->dieUsage("The section parameter must be set to an integer or 'new'", "invalidsection");
         }
         $reqArr['wpSection'] = $params['section'];
     } else {
         $reqArr['wpSection'] = '';
     }
     $watch = $this->getWatchlistValue($params['watchlist'], $titleObj);
     // Deprecated parameters
     if ($params['watch']) {
         $watch = true;
     } elseif ($params['unwatch']) {
         $watch = false;
     }
     if ($watch) {
         $reqArr['wpWatchthis'] = '';
     }
     $req = new FauxRequest($reqArr, true);
     $ep->importFormData($req);
     // Run hooks
     // Handle CAPTCHA parameters
     global $wgRequest;
     if (!is_null($params['captchaid'])) {
         $wgRequest->setVal('wpCaptchaId', $params['captchaid']);
     }
     if (!is_null($params['captchaword'])) {
         $wgRequest->setVal('wpCaptchaWord', $params['captchaword']);
     }
     $r = array();
     if (!wfRunHooks('APIEditBeforeSave', array($ep, $ep->textbox1, &$r))) {
         if (count($r)) {
             $r['result'] = 'Failure';
             $this->getResult()->addValue(null, $this->getModuleName(), $r);
             return;
         } else {
             $this->dieUsageMsg(array('hookaborted'));
         }
     }
     // Do the actual save
     $oldRevId = $articleObj->getRevIdFetched();
     $result = null;
     // Fake $wgRequest for some hooks inside EditPage
     // FIXME: This interface SUCKS
     $oldRequest = $wgRequest;
     $wgRequest = $req;
     $retval = $ep->internalAttemptSave($result, $wgUser->isAllowed('bot') && $params['bot']);
     $wgRequest = $oldRequest;
     global $wgMaxArticleSize;
     switch ($retval) {
         case EditPage::AS_HOOK_ERROR:
         case EditPage::AS_HOOK_ERROR_EXPECTED:
             $this->dieUsageMsg(array('hookaborted'));
         case EditPage::AS_IMAGE_REDIRECT_ANON:
             $this->dieUsageMsg(array('noimageredirect-anon'));
         case EditPage::AS_IMAGE_REDIRECT_LOGGED:
             $this->dieUsageMsg(array('noimageredirect-logged'));
         case EditPage::AS_SPAM_ERROR:
             $this->dieUsageMsg(array('spamdetected', $result['spam']));
         case EditPage::AS_FILTERING:
             $this->dieUsageMsg(array('filtered'));
         case EditPage::AS_BLOCKED_PAGE_FOR_USER:
             $this->dieUsageMsg(array('blockedtext'));
         case EditPage::AS_MAX_ARTICLE_SIZE_EXCEEDED:
         case EditPage::AS_CONTENT_TOO_BIG:
             $this->dieUsageMsg(array('contenttoobig', $wgMaxArticleSize));
         case EditPage::AS_READ_ONLY_PAGE_ANON:
             $this->dieUsageMsg(array('noedit-anon'));
         case EditPage::AS_READ_ONLY_PAGE_LOGGED:
             $this->dieUsageMsg(array('noedit'));
         case EditPage::AS_READ_ONLY_PAGE:
             $this->dieReadOnly();
         case EditPage::AS_RATE_LIMITED:
             $this->dieUsageMsg(array('actionthrottledtext'));
         case EditPage::AS_ARTICLE_WAS_DELETED:
             $this->dieUsageMsg(array('wasdeleted'));
         case EditPage::AS_NO_CREATE_PERMISSION:
             $this->dieUsageMsg(array('nocreate-loggedin'));
         case EditPage::AS_BLANK_ARTICLE:
             $this->dieUsageMsg(array('blankpage'));
         case EditPage::AS_CONFLICT_DETECTED:
             $this->dieUsageMsg(array('editconflict'));
             // case EditPage::AS_SUMMARY_NEEDED: Can't happen since we set wpIgnoreBlankSummary
         // case EditPage::AS_SUMMARY_NEEDED: Can't happen since we set wpIgnoreBlankSummary
         case EditPage::AS_TEXTBOX_EMPTY:
             $this->dieUsageMsg(array('emptynewsection'));
         case EditPage::AS_SUCCESS_NEW_ARTICLE:
             $r['new'] = '';
         case EditPage::AS_SUCCESS_UPDATE:
             $r['result'] = 'Success';
             $r['pageid'] = intval($titleObj->getArticleID());
             $r['title'] = $titleObj->getPrefixedText();
             // HACK: We create a new Article object here because getRevIdFetched()
             // refuses to be run twice, and because Title::getLatestRevId()
             // won't fetch from the master unless we select for update, which we
             // don't want to do.
             $newArticle = new Article($titleObj);
             $newRevId = $newArticle->getRevIdFetched();
             if ($newRevId == $oldRevId) {
                 $r['nochange'] = '';
             } else {
                 $r['oldrevid'] = intval($oldRevId);
                 $r['newrevid'] = intval($newRevId);
                 $r['newtimestamp'] = wfTimestamp(TS_ISO_8601, $newArticle->getTimestamp());
             }
             break;
         case EditPage::AS_SUMMARY_NEEDED:
             $this->dieUsageMsg(array('summaryrequired'));
         case EditPage::AS_END:
             // This usually means some kind of race condition
             // or DB weirdness occurred. Fall through to throw an unknown
             // error.
             // This needs fixing higher up, as Article::doEdit should be
             // used rather than Article::updateArticle, so that specific
             // error conditions can be returned
         // This usually means some kind of race condition
         // or DB weirdness occurred. Fall through to throw an unknown
         // error.
         // This needs fixing higher up, as Article::doEdit should be
         // used rather than Article::updateArticle, so that specific
         // error conditions can be returned
         default:
             $this->dieUsageMsg(array('unknownerror', $retval));
     }
     $this->getResult()->addValue(null, $this->getModuleName(), $r);
 }
Esempio n. 4
0
 public function execute()
 {
     // The data is hot but user-dependent, like page views, so we set vary cookies
     $this->getMain()->setCacheMode('anon-public-user-private');
     // Get parameters
     $params = $this->extractRequestParams();
     $text = $params['text'];
     $title = $params['title'];
     $page = $params['page'];
     $oldid = $params['oldid'];
     if (!is_null($page) && (!is_null($text) || $title != "API")) {
         $this->dieUsage("The page parameter cannot be used together with the text and title parameters", 'params');
     }
     $prop = array_flip($params['prop']);
     $revid = false;
     // The parser needs $wgTitle to be set, apparently the
     // $title parameter in Parser::parse isn't enough *sigh*
     global $wgParser, $wgUser, $wgTitle, $wgEnableParserCache;
     $popts = new ParserOptions();
     $popts->setTidy(true);
     $popts->enableLimitReport();
     $redirValues = null;
     if (!is_null($oldid) || !is_null($page)) {
         if (!is_null($oldid)) {
             // Don't use the parser cache
             $rev = Revision::newFromID($oldid);
             if (!$rev) {
                 $this->dieUsage("There is no revision ID {$oldid}", 'missingrev');
             }
             if (!$rev->userCan(Revision::DELETED_TEXT)) {
                 $this->dieUsage("You don't have permission to view deleted revisions", 'permissiondenied');
             }
             $text = $rev->getText(Revision::FOR_THIS_USER);
             $titleObj = $rev->getTitle();
             $wgTitle = $titleObj;
             $p_result = $wgParser->parse($text, $titleObj, $popts);
         } else {
             if ($params['redirects']) {
                 $req = new FauxRequest(array('action' => 'query', 'redirects' => '', 'titles' => $page));
                 $main = new ApiMain($req);
                 $main->execute();
                 $data = $main->getResultData();
                 $redirValues = @$data['query']['redirects'];
                 $to = $page;
                 foreach ((array) $redirValues as $r) {
                     $to = $r['to'];
                 }
             } else {
                 $to = $page;
             }
             $titleObj = Title::newFromText($to);
             if (!$titleObj) {
                 $this->dieUsage("The page you specified doesn't exist", 'missingtitle');
             }
             $articleObj = new Article($titleObj);
             if (isset($prop['revid'])) {
                 $oldid = $articleObj->getRevIdFetched();
             }
             // Try the parser cache first
             $p_result = false;
             $pcache = ParserCache::singleton();
             if ($wgEnableParserCache) {
                 $p_result = $pcache->get($articleObj, $wgUser);
             }
             if (!$p_result) {
                 $p_result = $wgParser->parse($articleObj->getContent(), $titleObj, $popts);
                 if ($wgEnableParserCache) {
                     $pcache->save($p_result, $articleObj, $popts);
                 }
             }
         }
     } else {
         $titleObj = Title::newFromText($title);
         if (!$titleObj) {
             $titleObj = Title::newFromText("API");
         }
         $wgTitle = $titleObj;
         if ($params['pst'] || $params['onlypst']) {
             $text = $wgParser->preSaveTransform($text, $titleObj, $wgUser, $popts);
         }
         if ($params['onlypst']) {
             // Build a result and bail out
             $result_array['text'] = array();
             $this->getResult()->setContent($result_array['text'], $text);
             $this->getResult()->addValue(null, $this->getModuleName(), $result_array);
             return;
         }
         $p_result = $wgParser->parse($text, $titleObj, $popts);
     }
     // Return result
     $result = $this->getResult();
     $result_array = array();
     if ($params['redirects'] && !is_null($redirValues)) {
         $result_array['redirects'] = $redirValues;
     }
     if (isset($prop['text'])) {
         $result_array['text'] = array();
         $result->setContent($result_array['text'], $p_result->getText());
     }
     if (!is_null($params['summary'])) {
         $result_array['parsedsummary'] = array();
         $result->setContent($result_array['parsedsummary'], $wgUser->getSkin()->formatComment($params['summary'], $titleObj));
     }
     if (isset($prop['langlinks'])) {
         $result_array['langlinks'] = $this->formatLangLinks($p_result->getLanguageLinks());
     }
     if (isset($prop['categories'])) {
         $result_array['categories'] = $this->formatCategoryLinks($p_result->getCategories());
     }
     if (isset($prop['links'])) {
         $result_array['links'] = $this->formatLinks($p_result->getLinks());
     }
     if (isset($prop['templates'])) {
         $result_array['templates'] = $this->formatLinks($p_result->getTemplates());
     }
     if (isset($prop['images'])) {
         $result_array['images'] = array_keys($p_result->getImages());
     }
     if (isset($prop['externallinks'])) {
         $result_array['externallinks'] = array_keys($p_result->getExternalLinks());
     }
     if (isset($prop['sections'])) {
         $result_array['sections'] = $p_result->getSections();
     }
     if (isset($prop['displaytitle'])) {
         $result_array['displaytitle'] = $p_result->getDisplayTitle() ? $p_result->getDisplayTitle() : $titleObj->getPrefixedText();
     }
     if (isset($prop['headitems'])) {
         $result_array['headitems'] = $this->formatHeadItems($p_result->getHeadItems());
     }
     if (isset($prop['headhtml'])) {
         $out = new OutputPage();
         $out->addParserOutputNoText($p_result);
         $result_array['headhtml'] = array();
         $result->setContent($result_array['headhtml'], $out->headElement($wgUser->getSkin()));
     }
     if (!is_null($oldid)) {
         $result_array['revid'] = intval($oldid);
     }
     $result_mapping = array('redirects' => 'r', 'langlinks' => 'll', 'categories' => 'cl', 'links' => 'pl', 'templates' => 'tl', 'images' => 'img', 'externallinks' => 'el', 'sections' => 's', 'headitems' => 'hi');
     $this->setIndexedTagNames($result_array, $result_mapping);
     $result->addValue(null, $this->getModuleName(), $result_array);
 }
 /**
  * Parse what can be a revision ID or an article name
  * @param $str Mixed: revision ID or an article name
  * @return Title or Revision object, or NULL
  */
 private function parseTitleOrRevID($str)
 {
     $retval = false;
     if (is_numeric($str)) {
         $retval = Revision::newFromID($str);
     }
     if (!$retval) {
         $retval = Title::newFromURL($str);
     }
     return $retval;
 }
Esempio n. 6
0
 public function execute()
 {
     $params = $this->extractRequestParams(false);
     // If any of those parameters are used, work in 'enumeration' mode.
     // Enum mode can only be used when exactly one page is provided.
     // Enumerating revisions on multiple pages make it extremely
     // difficult to manage continuations and require additional SQL indexes
     $enumRevMode = !is_null($params['user']) || !is_null($params['excludeuser']) || !is_null($params['limit']) || !is_null($params['startid']) || !is_null($params['endid']) || $params['dir'] === 'newer' || !is_null($params['start']) || !is_null($params['end']);
     $pageSet = $this->getPageSet();
     $pageCount = $pageSet->getGoodTitleCount();
     $revCount = $pageSet->getRevisionCount();
     // Optimization -- nothing to do
     if ($revCount === 0 && $pageCount === 0) {
         return;
     }
     if ($revCount > 0 && $enumRevMode) {
         $this->dieUsage('The revids= parameter may not be used with the list options (limit, startid, endid, dirNewer, start, end).', 'revids');
     }
     if ($pageCount > 1 && $enumRevMode) {
         $this->dieUsage('titles, pageids or a generator was used to supply multiple pages, but the limit, startid, endid, dirNewer, user, excludeuser, start and end parameters may only be used on a single page.', 'multpages');
     }
     if (!is_null($params['difftotext'])) {
         $this->difftotext = $params['difftotext'];
     } elseif (!is_null($params['diffto'])) {
         if ($params['diffto'] == 'cur') {
             $params['diffto'] = 0;
         }
         if ((!ctype_digit($params['diffto']) || $params['diffto'] < 0) && $params['diffto'] != 'prev' && $params['diffto'] != 'next') {
             $this->dieUsage('rvdiffto must be set to a non-negative number, "prev", "next" or "cur"', 'diffto');
         }
         // Check whether the revision exists and is readable,
         // DifferenceEngine returns a rather ambiguous empty
         // string if that's not the case
         if ($params['diffto'] != 0) {
             $difftoRev = Revision::newFromID($params['diffto']);
             if (!$difftoRev) {
                 $this->dieUsageMsg(array('nosuchrevid', $params['diffto']));
             }
             if ($difftoRev->isDeleted(Revision::DELETED_TEXT)) {
                 $this->setWarning("Couldn't diff to r{$difftoRev->getID()}: content is hidden");
                 $params['diffto'] = null;
             }
         }
         $this->diffto = $params['diffto'];
     }
     $db = $this->getDB();
     $this->addTables('page');
     $this->addFields(Revision::selectFields());
     $this->addWhere('page_id = rev_page');
     $prop = array_flip($params['prop']);
     // Optional fields
     $this->fld_ids = isset($prop['ids']);
     // $this->addFieldsIf('rev_text_id', $this->fld_ids); // should this be exposed?
     $this->fld_flags = isset($prop['flags']);
     $this->fld_timestamp = isset($prop['timestamp']);
     $this->fld_comment = isset($prop['comment']);
     $this->fld_parsedcomment = isset($prop['parsedcomment']);
     $this->fld_size = isset($prop['size']);
     $this->fld_sha1 = isset($prop['sha1']);
     $this->fld_userid = isset($prop['userid']);
     $this->fld_user = isset($prop['user']);
     $this->token = $params['token'];
     // Possible indexes used
     $index = array();
     $userMax = $this->fld_content ? ApiBase::LIMIT_SML1 : ApiBase::LIMIT_BIG1;
     $botMax = $this->fld_content ? ApiBase::LIMIT_SML2 : ApiBase::LIMIT_BIG2;
     $limit = $params['limit'];
     if ($limit == 'max') {
         $limit = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
         $this->getResult()->setParsedLimit($this->getModuleName(), $limit);
     }
     if (!is_null($this->token) || $pageCount > 0) {
         $this->addFields(Revision::selectPageFields());
     }
     if (isset($prop['tags'])) {
         $this->fld_tags = true;
         $this->addTables('tag_summary');
         $this->addJoinConds(array('tag_summary' => array('LEFT JOIN', array('rev_id=ts_rev_id'))));
         $this->addFields('ts_tags');
     }
     if (!is_null($params['tag'])) {
         $this->addTables('change_tag');
         $this->addJoinConds(array('change_tag' => array('INNER JOIN', array('rev_id=ct_rev_id'))));
         $this->addWhereFld('ct_tag', $params['tag']);
         global $wgOldChangeTagsIndex;
         $index['change_tag'] = $wgOldChangeTagsIndex ? 'ct_tag' : 'change_tag_tag_id';
     }
     if (isset($prop['content']) || !is_null($this->difftotext)) {
         // For each page we will request, the user must have read rights for that page
         foreach ($pageSet->getGoodTitles() as $title) {
             if (!$title->userCan('read')) {
                 $this->dieUsage('The current user is not allowed to read ' . $title->getPrefixedText(), 'accessdenied');
             }
         }
         $this->addTables('text');
         $this->addWhere('rev_text_id=old_id');
         $this->addFields('old_id');
         $this->addFields(Revision::selectTextFields());
         $this->fld_content = isset($prop['content']);
         $this->expandTemplates = $params['expandtemplates'];
         $this->generateXML = $params['generatexml'];
         $this->parseContent = $params['parse'];
         if ($this->parseContent) {
             // Must manually initialize unset limit
             if (is_null($limit)) {
                 $limit = 1;
             }
             // We are only going to parse 1 revision per request
             $this->validateLimit('limit', $limit, 1, 1, 1);
         }
         if (isset($params['section'])) {
             $this->section = $params['section'];
         } else {
             $this->section = false;
         }
     }
     // add user name, if needed
     if ($this->fld_user) {
         $this->addTables('user');
         $this->addJoinConds(array('user' => Revision::userJoinCond()));
         $this->addFields(Revision::selectUserFields());
     }
     // Bug 24166 - API error when using rvprop=tags
     $this->addTables('revision');
     if ($enumRevMode) {
         // This is mostly to prevent parameter errors (and optimize SQL?)
         if (!is_null($params['startid']) && !is_null($params['start'])) {
             $this->dieUsage('start and startid cannot be used together', 'badparams');
         }
         if (!is_null($params['endid']) && !is_null($params['end'])) {
             $this->dieUsage('end and endid cannot be used together', 'badparams');
         }
         if (!is_null($params['user']) && !is_null($params['excludeuser'])) {
             $this->dieUsage('user and excludeuser cannot be used together', 'badparams');
         }
         // Continuing effectively uses startid. But we can't use rvstartid
         // directly, because there is no way to tell the client to ''not''
         // send rvstart if it sent it in the original query. So instead we
         // send the continuation startid as rvcontinue, and ignore both
         // rvstart and rvstartid when that is supplied.
         if (!is_null($params['continue'])) {
             $params['startid'] = $params['continue'];
             unset($params['start']);
         }
         // This code makes an assumption that sorting by rev_id and rev_timestamp produces
         // the same result. This way users may request revisions starting at a given time,
         // but to page through results use the rev_id returned after each page.
         // Switching to rev_id removes the potential problem of having more than
         // one row with the same timestamp for the same page.
         // The order needs to be the same as start parameter to avoid SQL filesort.
         if (is_null($params['startid']) && is_null($params['endid'])) {
             $this->addTimestampWhereRange('rev_timestamp', $params['dir'], $params['start'], $params['end']);
         } else {
             $this->addWhereRange('rev_id', $params['dir'], $params['startid'], $params['endid']);
             // One of start and end can be set
             // If neither is set, this does nothing
             $this->addTimestampWhereRange('rev_timestamp', $params['dir'], $params['start'], $params['end'], false);
         }
         // must manually initialize unset limit
         if (is_null($limit)) {
             $limit = 10;
         }
         $this->validateLimit('limit', $limit, 1, $userMax, $botMax);
         // There is only one ID, use it
         $ids = array_keys($pageSet->getGoodTitles());
         $this->addWhereFld('rev_page', reset($ids));
         if (!is_null($params['user'])) {
             $this->addWhereFld('rev_user_text', $params['user']);
         } elseif (!is_null($params['excludeuser'])) {
             $this->addWhere('rev_user_text != ' . $db->addQuotes($params['excludeuser']));
         }
         if (!is_null($params['user']) || !is_null($params['excludeuser'])) {
             // Paranoia: avoid brute force searches (bug 17342)
             $this->addWhere($db->bitAnd('rev_deleted', Revision::DELETED_USER) . ' = 0');
         }
     } elseif ($revCount > 0) {
         $max = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
         $revs = $pageSet->getRevisionIDs();
         if (self::truncateArray($revs, $max)) {
             $this->setWarning("Too many values supplied for parameter 'revids': the limit is {$max}");
         }
         // Get all revision IDs
         $this->addWhereFld('rev_id', array_keys($revs));
         if (!is_null($params['continue'])) {
             $this->addWhere('rev_id >= ' . intval($params['continue']));
         }
         $this->addOption('ORDER BY', 'rev_id');
         // assumption testing -- we should never get more then $revCount rows.
         $limit = $revCount;
     } elseif ($pageCount > 0) {
         $max = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
         $titles = $pageSet->getGoodTitles();
         if (self::truncateArray($titles, $max)) {
             $this->setWarning("Too many values supplied for parameter 'titles': the limit is {$max}");
         }
         // When working in multi-page non-enumeration mode,
         // limit to the latest revision only
         $this->addWhere('page_id=rev_page');
         $this->addWhere('page_latest=rev_id');
         // Get all page IDs
         $this->addWhereFld('page_id', array_keys($titles));
         // Every time someone relies on equality propagation, god kills a kitten :)
         $this->addWhereFld('rev_page', array_keys($titles));
         if (!is_null($params['continue'])) {
             $cont = explode('|', $params['continue']);
             if (count($cont) != 2) {
                 $this->dieUsage('Invalid continue param. You should pass the original ' . 'value returned by the previous query', '_badcontinue');
             }
             $pageid = intval($cont[0]);
             $revid = intval($cont[1]);
             $this->addWhere("rev_page > {$pageid} OR " . "(rev_page = {$pageid} AND " . "rev_id >= {$revid})");
         }
         $this->addOption('ORDER BY', array('rev_page', 'rev_id'));
         // assumption testing -- we should never get more then $pageCount rows.
         $limit = $pageCount;
     } else {
         ApiBase::dieDebug(__METHOD__, 'param validation?');
     }
     $this->addOption('LIMIT', $limit + 1);
     $this->addOption('USE INDEX', $index);
     $count = 0;
     $res = $this->select(__METHOD__);
     foreach ($res as $row) {
         if (++$count > $limit) {
             // We've reached the one extra which shows that there are additional pages to be had. Stop here...
             if (!$enumRevMode) {
                 ApiBase::dieDebug(__METHOD__, 'Got more rows then expected');
                 // bug report
             }
             $this->setContinueEnumParameter('continue', intval($row->rev_id));
             break;
         }
         $fit = $this->addPageSubItem($row->rev_page, $this->extractRowInfo($row), 'rev');
         if (!$fit) {
             if ($enumRevMode) {
                 $this->setContinueEnumParameter('continue', intval($row->rev_id));
             } elseif ($revCount > 0) {
                 $this->setContinueEnumParameter('continue', intval($row->rev_id));
             } else {
                 $this->setContinueEnumParameter('continue', intval($row->rev_page) . '|' . intval($row->rev_id));
             }
             break;
         }
     }
 }
Esempio n. 7
0
 function execute($par)
 {
     global $wgRequest, $wgOut, $wgUser;
     $target = isset($par) ? $par : $wgRequest->getVal('target');
     if (!in_array('sysop', $wgUser->getGroups())) {
         $wgOut->setArticleRelated(false);
         $wgOut->setRobotpolicy('noindex,nofollow');
         $wgOut->showErrorPage('nosuchspecialpage', 'nospecialpagetext');
         return;
     }
     if ($target) {
         if (preg_match("@[^0-9]@", $target)) {
             $t = Title::newFromURL($target);
         } else {
             $r = Revision::newFromID($target);
             if ($wgRequest->getVal('popup')) {
                 $wgOut->setArticleBodyOnly(true);
                 $wgOut->addHTML("<style type='text/css'>\n\t\t\t\t\t\ttable.diff  {\n\t\t\t\t\t\t\tmargin-left: auto; margin-right: auto;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttable.diff td {\n\t\t\t\t\t\t\tmax-width: 400px;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t</style>");
             }
             $wgOut->addHTML("Revid: {$r->mId}\n");
             $d = self::getDiffToMeasure($r);
             $de = new DifferenceEngine($r->mTitle, $d['revlo']->mId, $d['revhi']->mId);
             self::getPoints($r, $d, $de, true);
             if (!$d['revlo']) {
                 $de->mOldRev = null;
                 $de->mOldid = null;
             }
             $de->showDiffPage();
             return;
         }
     } else {
         $rp = new RandomPage();
         $t = $rp->getRandomTitle();
     }
     $wgOut->addHTML("<script type='text/javascript'>\nfunction getPoints(rev) {\n\t\$('#img-box').load('/Special:Points/' + rev + '?popup=true', function() {\n\t\t\t\$('#img-box').dialog({\n\t\t\t   width: 750,\n\t\t\t   modal: true,\n\t\t\t\ttitle: 'Points', \n\t\t\t   show: 'slide',\n\t\t\t\tcloseOnEscape: true,\n\t\t\t\tposition: 'center'\n\t\t\t});\n\t});\n\treturn false;\n}\n</script>\n");
     // get the groups of edits
     $group = self::getEditGroups($t);
     $wgOut->addHTML("Title: <a href='{$t->getFullURL()}?action=history' target='new'>{$t->getFullText()}</a><br/><br/>");
     $wgOut->addHTML("<table width='100%'><tr><td><u>User</u></td><td><u># Edits</u></td>");
     $wgOut->addHTML("<td><u>Date</u></td><td><u>Points</u></td></tr>");
     foreach ($group as $g) {
         $r = Revision::newFromID($g['max_revid']);
         $d = self::getDiffToMeasure($r);
         $de = new DifferenceEngine($r->mTitle, $d['revlo']->mId, $d['revhi']->mId);
         $points = self::getPoints($r, $d, $de);
         $date = date("Y-m-d", wfTimestamp(TS_UNIX, $g['max_revtimestamp']));
         $wgOut->addHTML("<tr><td>{$g['user_text']}</td><td>{$g['edits']}</td><td>{$date}</td>");
         $wgOut->addHTML("<td><a href='#' onclick='return getPoints({$g['max_revid']});'>{$points}</a></td></tr>");
     }
     $wgOut->addHTML("</table>");
 }
Esempio n. 8
0
 public function execute()
 {
     // The data is hot but user-dependent, like page views, so we set vary cookies
     $this->getMain()->setCacheMode('anon-public-user-private');
     // Get parameters
     $params = $this->extractRequestParams();
     $text = $params['text'];
     $title = $params['title'];
     $page = $params['page'];
     $pageid = $params['pageid'];
     $oldid = $params['oldid'];
     if (!is_null($page) && (!is_null($text) || $title != 'API')) {
         $this->dieUsage('The page parameter cannot be used together with the text and title parameters', 'params');
     }
     $prop = array_flip($params['prop']);
     if (isset($params['section'])) {
         $this->section = $params['section'];
     } else {
         $this->section = false;
     }
     // The parser needs $wgTitle to be set, apparently the
     // $title parameter in Parser::parse isn't enough *sigh*
     // TODO: Does this still need $wgTitle?
     global $wgParser, $wgTitle, $wgLang;
     // Currently unnecessary, code to act as a safeguard against any change in current behaviour of uselang breaks
     $oldLang = null;
     if (isset($params['uselang']) && $params['uselang'] != $wgLang->getCode()) {
         $oldLang = $wgLang;
         // Backup wgLang
         $wgLang = Language::factory($params['uselang']);
     }
     $popts = ParserOptions::newFromContext($this->getContext());
     $popts->setTidy(true);
     $popts->enableLimitReport(!$params['disablepp']);
     $redirValues = null;
     // Return result
     $result = $this->getResult();
     if (!is_null($oldid) || !is_null($pageid) || !is_null($page)) {
         if (!is_null($oldid)) {
             // Don't use the parser cache
             $rev = Revision::newFromID($oldid);
             if (!$rev) {
                 $this->dieUsage("There is no revision ID {$oldid}", 'missingrev');
             }
             if (!$rev->userCan(Revision::DELETED_TEXT, $this->getUser())) {
                 $this->dieUsage("You don't have permission to view deleted revisions", 'permissiondenied');
             }
             $titleObj = $rev->getTitle();
             $wgTitle = $titleObj;
             // If for some reason the "oldid" is actually the current revision, it may be cached
             if ($titleObj->getLatestRevID() === intval($oldid)) {
                 // May get from/save to parser cache
                 $p_result = $this->getParsedSectionOrText($titleObj, $popts, $pageid, isset($prop['wikitext']));
             } else {
                 // This is an old revision, so get the text differently
                 $this->text = $rev->getText(Revision::FOR_THIS_USER, $this->getUser());
                 if ($this->section !== false) {
                     $this->text = $this->getSectionText($this->text, 'r' . $rev->getId());
                 }
                 // Should we save old revision parses to the parser cache?
                 $p_result = $wgParser->parse($this->text, $titleObj, $popts);
             }
         } else {
             // Not $oldid, but $pageid or $page
             if ($params['redirects']) {
                 $reqParams = array('action' => 'query', 'redirects' => '');
                 if (!is_null($pageid)) {
                     $reqParams['pageids'] = $pageid;
                 } else {
                     // $page
                     $reqParams['titles'] = $page;
                 }
                 $req = new FauxRequest($reqParams);
                 $main = new ApiMain($req);
                 $main->execute();
                 $data = $main->getResultData();
                 $redirValues = isset($data['query']['redirects']) ? $data['query']['redirects'] : array();
                 $to = $page;
                 foreach ((array) $redirValues as $r) {
                     $to = $r['to'];
                 }
                 $titleObj = Title::newFromText($to);
             } else {
                 if (!is_null($pageid)) {
                     $reqParams['pageids'] = $pageid;
                     $titleObj = Title::newFromID($pageid);
                 } else {
                     // $page
                     $to = $page;
                     $titleObj = Title::newFromText($to);
                 }
             }
             if (!is_null($pageid)) {
                 if (!$titleObj) {
                     // Still throw nosuchpageid error if pageid was provided
                     $this->dieUsageMsg(array('nosuchpageid', $pageid));
                 }
             } elseif (!$titleObj || !$titleObj->exists()) {
                 $this->dieUsage("The page you specified doesn't exist", 'missingtitle');
             }
             $wgTitle = $titleObj;
             if (isset($prop['revid'])) {
                 $oldid = $titleObj->getLatestRevID();
             }
             // Potentially cached
             $p_result = $this->getParsedSectionOrText($titleObj, $popts, $pageid, isset($prop['wikitext']));
         }
     } else {
         // Not $oldid, $pageid, $page. Hence based on $text
         if (is_null($text)) {
             $this->dieUsage('The text parameter should be passed with the title parameter. Should you be using the "page" parameter instead?', 'params');
         }
         $this->text = $text;
         $titleObj = Title::newFromText($title);
         if (!$titleObj) {
             $this->dieUsageMsg(array('invalidtitle', $title));
         }
         $wgTitle = $titleObj;
         if ($this->section !== false) {
             $this->text = $this->getSectionText($this->text, $titleObj->getText());
         }
         if ($params['pst'] || $params['onlypst']) {
             $this->pstText = $wgParser->preSaveTransform($this->text, $titleObj, $this->getUser(), $popts);
         }
         if ($params['onlypst']) {
             // Build a result and bail out
             $result_array = array();
             $result_array['text'] = array();
             $result->setContent($result_array['text'], $this->pstText);
             if (isset($prop['wikitext'])) {
                 $result_array['wikitext'] = array();
                 $result->setContent($result_array['wikitext'], $this->text);
             }
             $result->addValue(null, $this->getModuleName(), $result_array);
             return;
         }
         // Not cached (save or load)
         $p_result = $wgParser->parse($params['pst'] ? $this->pstText : $this->text, $titleObj, $popts);
     }
     $result_array = array();
     $result_array['title'] = $titleObj->getPrefixedText();
     if (!is_null($oldid)) {
         $result_array['revid'] = intval($oldid);
     }
     if ($params['redirects'] && !is_null($redirValues)) {
         $result_array['redirects'] = $redirValues;
     }
     if (isset($prop['text'])) {
         $result_array['text'] = array();
         $result->setContent($result_array['text'], $p_result->getText());
     }
     if (!is_null($params['summary'])) {
         $result_array['parsedsummary'] = array();
         $result->setContent($result_array['parsedsummary'], Linker::formatComment($params['summary'], $titleObj));
     }
     if (isset($prop['langlinks'])) {
         $result_array['langlinks'] = $this->formatLangLinks($p_result->getLanguageLinks());
     }
     if (isset($prop['languageshtml'])) {
         $languagesHtml = $this->languagesHtml($p_result->getLanguageLinks());
         $result_array['languageshtml'] = array();
         $result->setContent($result_array['languageshtml'], $languagesHtml);
     }
     if (isset($prop['categories'])) {
         $result_array['categories'] = $this->formatCategoryLinks($p_result->getCategories());
     }
     if (isset($prop['categorieshtml'])) {
         $categoriesHtml = $this->categoriesHtml($p_result->getCategories());
         $result_array['categorieshtml'] = array();
         $result->setContent($result_array['categorieshtml'], $categoriesHtml);
     }
     if (isset($prop['links'])) {
         $result_array['links'] = $this->formatLinks($p_result->getLinks());
     }
     if (isset($prop['templates'])) {
         $result_array['templates'] = $this->formatLinks($p_result->getTemplates());
     }
     if (isset($prop['images'])) {
         $result_array['images'] = array_keys($p_result->getImages());
     }
     if (isset($prop['externallinks'])) {
         $result_array['externallinks'] = array_keys($p_result->getExternalLinks());
     }
     if (isset($prop['sections'])) {
         $result_array['sections'] = $p_result->getSections();
     }
     if (isset($prop['displaytitle'])) {
         $result_array['displaytitle'] = $p_result->getDisplayTitle() ? $p_result->getDisplayTitle() : $titleObj->getPrefixedText();
     }
     if (isset($prop['headitems']) || isset($prop['headhtml'])) {
         $context = $this->getContext();
         $context->setTitle($titleObj);
         $context->getOutput()->addParserOutputNoText($p_result);
         if (isset($prop['headitems'])) {
             $headItems = $this->formatHeadItems($p_result->getHeadItems());
             $css = $this->formatCss($context->getOutput()->buildCssLinksArray());
             $scripts = array($context->getOutput()->getHeadScripts());
             $result_array['headitems'] = array_merge($headItems, $css, $scripts);
         }
         if (isset($prop['headhtml'])) {
             $result_array['headhtml'] = array();
             $result->setContent($result_array['headhtml'], $context->getOutput()->headElement($context->getSkin()));
         }
     }
     if (isset($prop['iwlinks'])) {
         $result_array['iwlinks'] = $this->formatIWLinks($p_result->getInterwikiLinks());
     }
     if (isset($prop['wikitext'])) {
         $result_array['wikitext'] = array();
         $result->setContent($result_array['wikitext'], $this->text);
         if (!is_null($this->pstText)) {
             $result_array['psttext'] = array();
             $result->setContent($result_array['psttext'], $this->pstText);
         }
     }
     $result_mapping = array('redirects' => 'r', 'langlinks' => 'll', 'categories' => 'cl', 'links' => 'pl', 'templates' => 'tl', 'images' => 'img', 'externallinks' => 'el', 'iwlinks' => 'iw', 'sections' => 's', 'headitems' => 'hi');
     $this->setIndexedTagNames($result_array, $result_mapping);
     $result->addValue(null, $this->getModuleName(), $result_array);
     if (!is_null($oldLang)) {
         $wgLang = $oldLang;
         // Reset $wgLang to $oldLang
     }
 }
 private function parseTitleOrRevID($str)
 {
     // Parse what can be a revision ID or an article name
     // Returns: Title or Revision object, or NULL
     $retval = false;
     if (is_numeric($str)) {
         $retval = Revision::newFromID($str);
     }
     if (!$retval) {
         $retval = Title::newFromURL($str);
     }
     return $retval;
 }
 public function execute()
 {
     $user = $this->getUser();
     $params = $this->extractRequestParams();
     if (is_null($params['text']) && is_null($params['appendtext']) && is_null($params['prependtext']) && $params['undo'] == 0) {
         $this->dieUsageMsg('missingtext');
     }
     $pageObj = $this->getTitleOrPageId($params);
     $titleObj = $pageObj->getTitle();
     $apiResult = $this->getResult();
     if ($params['redirect']) {
         if ($params['prependtext'] === null && $params['appendtext'] === null && $params['section'] !== 'new') {
             $this->dieUsage('You have attempted to edit using the "redirect"-following mode, which must be used in conjuction with section=new, prependtext, or appendtext.', 'redirect-appendonly');
         }
         if ($titleObj->isRedirect()) {
             $oldTitle = $titleObj;
             $titles = Revision::newFromTitle($oldTitle, false, Revision::READ_LATEST)->getContent(Revision::FOR_THIS_USER, $user)->getRedirectChain();
             // array_shift( $titles );
             $redirValues = array();
             /** @var $newTitle Title */
             foreach ($titles as $id => $newTitle) {
                 if (!isset($titles[$id - 1])) {
                     $titles[$id - 1] = $oldTitle;
                 }
                 $redirValues[] = array('from' => $titles[$id - 1]->getPrefixedText(), 'to' => $newTitle->getPrefixedText());
                 $titleObj = $newTitle;
             }
             $apiResult->setIndexedTagName($redirValues, 'r');
             $apiResult->addValue(null, 'redirects', $redirValues);
             // Since the page changed, update $pageObj
             $pageObj = WikiPage::factory($titleObj);
         }
     }
     if (!isset($params['contentmodel']) || $params['contentmodel'] == '') {
         $contentHandler = $pageObj->getContentHandler();
     } else {
         $contentHandler = ContentHandler::getForModelID($params['contentmodel']);
     }
     // @todo Ask handler whether direct editing is supported at all! make
     // allowFlatEdit() method or some such
     if (!isset($params['contentformat']) || $params['contentformat'] == '') {
         $params['contentformat'] = $contentHandler->getDefaultFormat();
     }
     $contentFormat = $params['contentformat'];
     if (!$contentHandler->isSupportedFormat($contentFormat)) {
         $name = $titleObj->getPrefixedDBkey();
         $model = $contentHandler->getModelID();
         $this->dieUsage("The requested format {$contentFormat} is not supported for content model " . " {$model} used by {$name}", 'badformat');
     }
     if ($params['createonly'] && $titleObj->exists()) {
         $this->dieUsageMsg('createonly-exists');
     }
     if ($params['nocreate'] && !$titleObj->exists()) {
         $this->dieUsageMsg('nocreate-missing');
     }
     // Now let's check whether we're even allowed to do this
     $errors = $titleObj->getUserPermissionsErrors('edit', $user);
     if (!$titleObj->exists()) {
         $errors = array_merge($errors, $titleObj->getUserPermissionsErrors('create', $user));
     }
     if (count($errors)) {
         $this->dieUsageMsg($errors[0]);
     }
     $toMD5 = $params['text'];
     if (!is_null($params['appendtext']) || !is_null($params['prependtext'])) {
         $content = $pageObj->getContent();
         if (!$content) {
             if ($titleObj->getNamespace() == NS_MEDIAWIKI) {
                 # If this is a MediaWiki:x message, then load the messages
                 # and return the message value for x.
                 $text = $titleObj->getDefaultMessageText();
                 if ($text === false) {
                     $text = '';
                 }
                 try {
                     $content = ContentHandler::makeContent($text, $this->getTitle());
                 } catch (MWContentSerializationException $ex) {
                     $this->dieUsage($ex->getMessage(), 'parseerror');
                     return;
                 }
             } else {
                 # Otherwise, make a new empty content.
                 $content = $contentHandler->makeEmptyContent();
             }
         }
         // @todo Add support for appending/prepending to the Content interface
         if (!$content instanceof TextContent) {
             $mode = $contentHandler->getModelID();
             $this->dieUsage("Can't append to pages using content model {$mode}", 'appendnotsupported');
         }
         if (!is_null($params['section'])) {
             if (!$contentHandler->supportsSections()) {
                 $modelName = $contentHandler->getModelID();
                 $this->dieUsage("Sections are not supported for this content model: {$modelName}.", 'sectionsnotsupported');
             }
             if ($params['section'] == 'new') {
                 // DWIM if they're trying to prepend/append to a new section.
                 $content = null;
             } else {
                 // Process the content for section edits
                 $section = $params['section'];
                 $content = $content->getSection($section);
                 if (!$content) {
                     $this->dieUsage("There is no section {$section}.", 'nosuchsection');
                 }
             }
         }
         if (!$content) {
             $text = '';
         } else {
             $text = $content->serialize($contentFormat);
         }
         $params['text'] = $params['prependtext'] . $text . $params['appendtext'];
         $toMD5 = $params['prependtext'] . $params['appendtext'];
     }
     if ($params['undo'] > 0) {
         if ($params['undoafter'] > 0) {
             if ($params['undo'] < $params['undoafter']) {
                 list($params['undo'], $params['undoafter']) = array($params['undoafter'], $params['undo']);
             }
             $undoafterRev = Revision::newFromID($params['undoafter']);
         }
         $undoRev = Revision::newFromID($params['undo']);
         if (is_null($undoRev) || $undoRev->isDeleted(Revision::DELETED_TEXT)) {
             $this->dieUsageMsg(array('nosuchrevid', $params['undo']));
         }
         if ($params['undoafter'] == 0) {
             $undoafterRev = $undoRev->getPrevious();
         }
         if (is_null($undoafterRev) || $undoafterRev->isDeleted(Revision::DELETED_TEXT)) {
             $this->dieUsageMsg(array('nosuchrevid', $params['undoafter']));
         }
         if ($undoRev->getPage() != $pageObj->getID()) {
             $this->dieUsageMsg(array('revwrongpage', $undoRev->getID(), $titleObj->getPrefixedText()));
         }
         if ($undoafterRev->getPage() != $pageObj->getID()) {
             $this->dieUsageMsg(array('revwrongpage', $undoafterRev->getID(), $titleObj->getPrefixedText()));
         }
         $newContent = $contentHandler->getUndoContent($pageObj->getRevision(), $undoRev, $undoafterRev);
         if (!$newContent) {
             $this->dieUsageMsg('undo-failure');
         }
         $params['text'] = $newContent->serialize($params['contentformat']);
         // If no summary was given and we only undid one rev,
         // use an autosummary
         if (is_null($params['summary']) && $titleObj->getNextRevisionID($undoafterRev->getID()) == $params['undo']) {
             $params['summary'] = wfMessage('undo-summary')->params($params['undo'], $undoRev->getUserText())->inContentLanguage()->text();
         }
     }
     // See if the MD5 hash checks out
     if (!is_null($params['md5']) && md5($toMD5) !== $params['md5']) {
         $this->dieUsageMsg('hashcheckfailed');
     }
     // EditPage wants to parse its stuff from a WebRequest
     // That interface kind of sucks, but it's workable
     $requestArray = array('wpTextbox1' => $params['text'], 'format' => $contentFormat, 'model' => $contentHandler->getModelID(), 'wpEditToken' => $params['token'], 'wpIgnoreBlankSummary' => '', 'wpIgnoreBlankArticle' => true);
     if (!is_null($params['summary'])) {
         $requestArray['wpSummary'] = $params['summary'];
     }
     if (!is_null($params['sectiontitle'])) {
         $requestArray['wpSectionTitle'] = $params['sectiontitle'];
     }
     // TODO: Pass along information from 'undoafter' as well
     if ($params['undo'] > 0) {
         $requestArray['wpUndidRevision'] = $params['undo'];
     }
     // Watch out for basetimestamp == ''
     // wfTimestamp() treats it as NOW, almost certainly causing an edit conflict
     if (!is_null($params['basetimestamp']) && $params['basetimestamp'] != '') {
         $requestArray['wpEdittime'] = wfTimestamp(TS_MW, $params['basetimestamp']);
     } else {
         $requestArray['wpEdittime'] = $pageObj->getTimestamp();
     }
     if (!is_null($params['starttimestamp']) && $params['starttimestamp'] != '') {
         $requestArray['wpStarttime'] = wfTimestamp(TS_MW, $params['starttimestamp']);
     } else {
         $requestArray['wpStarttime'] = wfTimestampNow();
         // Fake wpStartime
     }
     if ($params['minor'] || !$params['notminor'] && $user->getOption('minordefault')) {
         $requestArray['wpMinoredit'] = '';
     }
     if ($params['recreate']) {
         $requestArray['wpRecreate'] = '';
     }
     if (!is_null($params['section'])) {
         $section = $params['section'];
         if (!preg_match('/^((T-)?\\d+|new)$/', $section)) {
             $this->dieUsage("The section parameter must be a valid section id or 'new'", "invalidsection");
         }
         $content = $pageObj->getContent();
         if ($section !== '0' && $section != 'new' && (!$content || !$content->getSection($section))) {
             $this->dieUsage("There is no section {$section}.", 'nosuchsection');
         }
         $requestArray['wpSection'] = $params['section'];
     } else {
         $requestArray['wpSection'] = '';
     }
     $watch = $this->getWatchlistValue($params['watchlist'], $titleObj);
     // Deprecated parameters
     if ($params['watch']) {
         $this->logFeatureUsage('action=edit&watch');
         $watch = true;
     } elseif ($params['unwatch']) {
         $this->logFeatureUsage('action=edit&unwatch');
         $watch = false;
     }
     if ($watch) {
         $requestArray['wpWatchthis'] = '';
     }
     // Pass through anything else we might have been given, to support extensions
     // This is kind of a hack but it's the best we can do to make extensions work
     $requestArray += $this->getRequest()->getValues();
     global $wgTitle, $wgRequest;
     $req = new DerivativeRequest($this->getRequest(), $requestArray, true);
     // Some functions depend on $wgTitle == $ep->mTitle
     // TODO: Make them not or check if they still do
     $wgTitle = $titleObj;
     $articleContext = new RequestContext();
     $articleContext->setRequest($req);
     $articleContext->setWikiPage($pageObj);
     $articleContext->setUser($this->getUser());
     /** @var $articleObject Article */
     $articleObject = Article::newFromWikiPage($pageObj, $articleContext);
     $ep = new EditPage($articleObject);
     // allow editing of non-textual content.
     $ep->allowNonTextContent = true;
     $ep->setContextTitle($titleObj);
     $ep->importFormData($req);
     $content = $ep->textbox1;
     // The following is needed to give the hook the full content of the
     // new revision rather than just the current section. (Bug 52077)
     if (!is_null($params['section']) && $contentHandler->supportsSections() && $titleObj->exists()) {
         // If sectiontitle is set, use it, otherwise use the summary as the section title (for
         // backwards compatibility with old forms/bots).
         if ($ep->sectiontitle !== '') {
             $sectionTitle = $ep->sectiontitle;
         } else {
             $sectionTitle = $ep->summary;
         }
         $contentObj = $contentHandler->unserializeContent($content, $contentFormat);
         $fullContentObj = $articleObject->replaceSectionContent($params['section'], $contentObj, $sectionTitle);
         if ($fullContentObj) {
             $content = $fullContentObj->serialize($contentFormat);
         } else {
             // This most likely means we have an edit conflict which means that the edit
             // wont succeed anyway.
             $this->dieUsageMsg('editconflict');
         }
     }
     // Run hooks
     // Handle APIEditBeforeSave parameters
     $r = array();
     if (!wfRunHooks('APIEditBeforeSave', array($ep, $content, &$r))) {
         if (count($r)) {
             $r['result'] = 'Failure';
             $apiResult->addValue(null, $this->getModuleName(), $r);
             return;
         }
         $this->dieUsageMsg('hookaborted');
     }
     // Do the actual save
     $oldRevId = $articleObject->getRevIdFetched();
     $result = null;
     // Fake $wgRequest for some hooks inside EditPage
     // @todo FIXME: This interface SUCKS
     $oldRequest = $wgRequest;
     $wgRequest = $req;
     $status = $ep->internalAttemptSave($result, $user->isAllowed('bot') && $params['bot']);
     $wgRequest = $oldRequest;
     switch ($status->value) {
         case EditPage::AS_HOOK_ERROR:
         case EditPage::AS_HOOK_ERROR_EXPECTED:
             $this->dieUsageMsg('hookaborted');
         case EditPage::AS_PARSE_ERROR:
             $this->dieUsage($status->getMessage(), 'parseerror');
         case EditPage::AS_IMAGE_REDIRECT_ANON:
             $this->dieUsageMsg('noimageredirect-anon');
         case EditPage::AS_IMAGE_REDIRECT_LOGGED:
             $this->dieUsageMsg('noimageredirect-logged');
         case EditPage::AS_SPAM_ERROR:
             $this->dieUsageMsg(array('spamdetected', $result['spam']));
         case EditPage::AS_BLOCKED_PAGE_FOR_USER:
             $this->dieUsageMsg('blockedtext');
         case EditPage::AS_MAX_ARTICLE_SIZE_EXCEEDED:
         case EditPage::AS_CONTENT_TOO_BIG:
             $this->dieUsageMsg(array('contenttoobig', $this->getConfig()->get('MaxArticleSize')));
         case EditPage::AS_READ_ONLY_PAGE_ANON:
             $this->dieUsageMsg('noedit-anon');
         case EditPage::AS_READ_ONLY_PAGE_LOGGED:
             $this->dieUsageMsg('noedit');
         case EditPage::AS_READ_ONLY_PAGE:
             $this->dieReadOnly();
         case EditPage::AS_RATE_LIMITED:
             $this->dieUsageMsg('actionthrottledtext');
         case EditPage::AS_ARTICLE_WAS_DELETED:
             $this->dieUsageMsg('wasdeleted');
         case EditPage::AS_NO_CREATE_PERMISSION:
             $this->dieUsageMsg('nocreate-loggedin');
         case EditPage::AS_BLANK_ARTICLE:
             $this->dieUsageMsg('blankpage');
         case EditPage::AS_CONFLICT_DETECTED:
             $this->dieUsageMsg('editconflict');
             // case EditPage::AS_SUMMARY_NEEDED: Can't happen since we set wpIgnoreBlankSummary
         // case EditPage::AS_SUMMARY_NEEDED: Can't happen since we set wpIgnoreBlankSummary
         case EditPage::AS_TEXTBOX_EMPTY:
             $this->dieUsageMsg('emptynewsection');
         case EditPage::AS_SUCCESS_NEW_ARTICLE:
             $r['new'] = '';
             // fall-through
         // fall-through
         case EditPage::AS_SUCCESS_UPDATE:
             $r['result'] = 'Success';
             $r['pageid'] = intval($titleObj->getArticleID());
             $r['title'] = $titleObj->getPrefixedText();
             $r['contentmodel'] = $titleObj->getContentModel();
             $newRevId = $articleObject->getLatest();
             if ($newRevId == $oldRevId) {
                 $r['nochange'] = '';
             } else {
                 $r['oldrevid'] = intval($oldRevId);
                 $r['newrevid'] = intval($newRevId);
                 $r['newtimestamp'] = wfTimestamp(TS_ISO_8601, $pageObj->getTimestamp());
             }
             break;
         case EditPage::AS_SUMMARY_NEEDED:
             $this->dieUsageMsg('summaryrequired');
         case EditPage::AS_END:
         default:
             // $status came from WikiPage::doEdit()
             $errors = $status->getErrorsArray();
             $this->dieUsageMsg($errors[0]);
             // TODO: Add new errors to message map
             break;
     }
     $apiResult->addValue(null, $this->getModuleName(), $r);
 }
Esempio n. 11
0
 /**
  * Handler for EchoGetNotificationTypes hook, Adjust the notify types (e.g. web, email) which
  * are applicable to this event and user based on various user options. In other words, allow
  * certain non-echo user options to override the echo notification options.
  * @param $user User
  * @param $event EchoEvent
  * @param $notifyTypes
  * @return bool
  */
 public static function getNotificationTypes($user, $event, &$notifyTypes)
 {
     $type = $event->getType();
     if (!$user->getOption('enotifminoredits')) {
         $extra = $event->getExtra();
         if (!empty($extra['revid'])) {
             $rev = Revision::newFromID($extra['revid']);
             if ($rev->isMinor()) {
                 $notifyTypes = array_diff($notifyTypes, array('email'));
             }
         }
     }
     return true;
 }
    $dbw->update("imageadder", array("imageadder_hasimage" => 0, "imageadder_skip" => 0), array("imageadder_page" => $t->getArticleID()));
    // last revision comment?
    $row = $dbr->selectRow('revision', '*', array('rev_page' => $t->getArticleID()), "fix intro adder", array("ORDER BY" => "rev_id desc", "LIMIT" => 1));
    if ($row->rev_comment == "Added Image using ImageAdder Tool") {
        $a = new Article($t);
        $a->commitRollback($row->rev_user_text, "Rolling back bug", false, &$results);
        echo "{$t->getFullURL()} rolled back \n";
        continue;
    }
    // how many sections?
    $r = Revision::newFromTitle($t);
    if (!$r) {
        echo "Can't make revision out of {$row->rc_title}\n";
        continue;
    }
    $text = $r->getText();
    preg_match_all("@^==.*==@m", $text, $matches);
    if (sizeof($matches[0]) == 0) {
        echo "{$t->getFullURL()} has no sections\n";
        // get the last edit
        $lastgood_rev = $dbr->selectRow("revision", "*", array('rev_page' => $t->getArticleID(), 'rev_comment != "Added Image using ImageAdder Tool"', "rev_id < {$row->rev_id}"), "fix intro adder", array("ORDER BY" => "rev_id desc", "LIMIT" => 1));
        $rev = Revision::newFromID($lastgood_rev->rev_id);
        if (!$rev) {
            // ?
            continue;
        }
        $text = $rev->getText();
        $a = new Article($t);
        $a->doEdit($text, "Rolling back bug going back to rev {$lastgood_rev->rev_id} by {$lastgood_rev->rev_user_text}");
    }
}
Esempio n. 13
0
 function getLastRevisionText()
 {
     $lastrev = $this->getLastRevID();
     $r = Revision::newFromID($lastrev);
     if (!$r) {
         return null;
     }
     return $r->getText();
 }
	protected function statusInterface() {
		global $wgOut, $wgUser, $wgPremoderationStrict;
		
		$params = $this->mParams;
		if( !isset( $params['id'] ) ) {
			$wgOut->setPageTitle( wfMsg( 'premoderation-manager-invalidaction' ) );
			$wgOut->addWikiMsg( 'premoderation-invalidaction' );
			return;		
		}
		
		$id = intval( $params['id'] );
		$dbr = wfGetDB( DB_SLAVE );
		$res = $dbr->select(
			'pm_queue',
			'*',
			"pmq_id = '$id'",
			__METHOD__,
			array( 'LIMIT' => 1 )
		);
		$row = $dbr->fetchRow( $res );
		if( !$row ) {
			$wgOut->setPageTitle( wfMsg( 'premoderation-manager-invalidaction' ) );
			$wgOut->addWikiMsg( 'premoderation-notexists-id' );
			return;
		}
		
		$wgOut->setPageTitle( wfMsg( 'premoderation-manager-status' ) );
		$wgOut->addWikiMsg( 'premoderation-status-intro' );
		
		$wgOut->addHTML( '<h2>' . wfMsg( 'premoderation-status-info' ) . '</h2>' .
			$this->getListTableHeader( 'status' ) . $this->formatListTableRow( $row ) .
			Xml::closeElement( 'table' ) );
		
		if( $wgUser->isAllowed( 'premoderation-viewip' ) ) {
			$wgOut->addWikiMsg( 'premoderation-private-ip', $row['pmq_ip'] );
		}
		
		$rev = Revision::newFromID( $row['pmq_page_last_id'] );
		$diff = new DifferenceEngine();
		$diff->showDiffStyle();
		$formattedDiff = $diff->generateDiffBody(
			isset( $rev ) ? $rev->getText() : '', $row['pmq_text']
		);
		
		$wgOut->addHTML( '<h2>' . wfMsg( 'premoderation-diff-h2' ) . '</h2>' .
			"<table class='mw-abusefilter-diff-multiline'><col class='diff-marker' />" .
			"<col class='diff-content' /><col class='diff-marker' /><col class='diff-content' />" .
			"<tbody>" . $formattedDiff . "</tbody></table>" );
		
		if( $row['pmq_status'] == 'approved' ) {
			return;
		}
		
		$externalConflicts = $this->checkExternalConflicts( $row['pmq_page_last_id'],
			$row['pmq_page_ns'], $row['pmq_page_title'] );
		if( $externalConflicts ) {
			$wgOut->addHTML( '<h2>' . wfMsg( 'premoderation-external-conflicts-h2' ) . '</h2>' );
			if( $wgPremoderationStrict ) {
				$wgOut->addWikiMsg( 'premoderation-error-externals' );
				return;			
			}
			$wgOut->addWikiMsg( 'premoderation-external-edits' );
		}
		
		$this->checkInternalConflicts( $dbr, $id, $row['pmq_page_ns'], $row['pmq_page_title'] );
		
		$final = Xml::fieldset( wfMsg( 'premoderation-status-fieldset' ) ) .
			Xml::openElement( 'form', array( 'id' => 'prem-status-form', 'method' => 'post' ) ) .
			$this->getStatusForm( $row['pmq_status'] ) .
			'<input type="hidden" name="id" value="' . $id . '" />' .
			Xml::closeElement( 'form' ) . Xml::closeElement( 'fieldset' );
			
		$wgOut->addHTML( $final );
	}
Esempio n. 15
0
 public function execute()
 {
     global $wgUser;
     $params = $this->extractRequestParams();
     if (is_null($params['title'])) {
         $this->dieUsageMsg(array('missingparam', 'title'));
     }
     if (is_null($params['xpath'])) {
         $this->dieUsage(array('missingparam', 'xpath'));
     }
     $titleObj = Title::newFromText($params['title']);
     if (!$titleObj || $titleObj->isExternal()) {
         $this->dieUsageMsg(array('invalidtitle', $params['title']));
     }
     // Some functions depend on $wgTitle == $ep->mTitle
     global $wgTitle;
     $wgTitle = $titleObj;
     if ($params['nocreate'] && !$titleObj->exists()) {
         $this->dieUsageMsg(array('nocreate-missing'));
     }
     // Now let's check whether we're even allowed to do this
     $errors = $titleObj->getUserPermissionsErrors('edit', $wgUser);
     if (!$titleObj->exists()) {
         $errors = array_merge($errors, $titleObj->getUserPermissionsErrors('create', $wgUser));
     }
     if (count($errors)) {
         $this->dieUsageMsg($errors[0]);
     }
     $articleObj = new Article($titleObj);
     if (!is_null($params['rid'])) {
         $revObj = Revision::newFromID($params['rid']);
         if (is_null($revObj) || $revObj->isDeleted(Revision::DELETED_TEXT)) {
             $this->dieUsageMsg(array('nosuchrevid', $params['rid']));
         }
         if ($revObj->getPage() != $articleObj->getID()) {
             $this->dieUsageMsg(array('revwrongpage', $revObj->getID(), $titleObj->getPrefixedText()));
         }
         if (!$params['force_update'] && !$revObj->isCurrent()) {
             $this->dieUsage("Page revision id is not current '{$titleObj->getPrefixedText()} ({$params['rid']})'", 'revnotcurrent');
         }
     } else {
         $params['rid'] = 0;
     }
     $verb = $params['verb'];
     $xpath = $params['xpath'];
     try {
         $wom = WOMProcessor::getPageObject($titleObj, $params['rid']);
         $obj_ids = WOMProcessor::getObjIdByXPath2($wom, $xpath);
         $obj_id = null;
         foreach ($obj_ids as $id) {
             if ($id != '') {
                 $obj_id = $id;
                 break;
             }
         }
         if ($obj_id == null) {
             throw new MWException(__METHOD__ . ": object does not found, xpath: {$xpath}");
         }
         if ($verb == 'remove') {
             $wom->removePageObject($obj_id);
         } elseif ($verb == 'removeall') {
             foreach ($obj_ids as $id) {
                 if ($id == '') {
                     continue;
                 }
                 $wom->removePageObject($id);
             }
         } else {
             if (is_null($params['text'])) {
                 $this->dieUsageMsg(array('missingparam', 'text'));
             }
             $toMD5 = $params['text'];
             // See if the MD5 hash checks out
             if (!is_null($params['md5']) && md5($toMD5) !== $params['md5']) {
                 $this->dieUsageMsg(array('hashcheckfailed'));
             }
             $text = $params['text'];
             if ($verb == 'insert') {
                 $text = WOMProcessor::getValidText($text, $wom->getObject($obj_id)->getParent(), $wom);
                 // no need to parse or merge object model but use text
                 $wom->insertPageObject(new WOMTextModel($text), $obj_id);
             } elseif ($verb == 'update') {
                 $text = WOMProcessor::getValidText($text, $wom->getObject($obj_id)->getParent(), $wom);
                 $wom->updatePageObject(new WOMTextModel($text), $obj_id);
             } elseif ($verb == 'append') {
                 $parent = $wom->getObject($obj_id);
                 if (!$parent instanceof WikiObjectModelCollection) {
                     throw new MWException(__METHOD__ . ": Object is not a collection object '{$title} ({$revision_id}) - {$obj_id}'");
                 }
                 $text = WOMProcessor::getValidText($text, $parent, $wom);
                 $wom->appendChildObject(new WOMTextModel($text), $obj_id);
             } elseif ($verb == 'attribute') {
                 $obj = $wom->getObject($obj_id);
                 $kv = explode('=', $text, 2);
                 if (count($kv) != 2) {
                     throw new MWException(__METHOD__ . ": value should be 'key=value' in attribute mode");
                 }
                 $obj->setXMLAttribute(trim($kv[0]), trim($kv[1]));
             }
         }
         $ep = new EditPage($articleObj);
         // EditPage wants to parse its stuff from a WebRequest
         // That interface kind of sucks, but it's workable
         $reqArr = array('wpTextbox1' => $wom->getWikiText(), 'wpEditToken' => $params['token'], 'wpIgnoreBlankSummary' => '', 'wpSection' => '');
         if (!is_null($params['summary'])) {
             $reqArr['wpSummary'] = $params['summary'];
         }
         // Watch out for basetimestamp == ''
         // wfTimestamp() treats it as NOW, almost certainly causing an edit conflict
         if (!is_null($params['basetimestamp']) && $params['basetimestamp'] != '') {
             $reqArr['wpEdittime'] = wfTimestamp(TS_MW, $params['basetimestamp']);
         } else {
             $reqArr['wpEdittime'] = $articleObj->getTimestamp();
         }
         if (!is_null($params['starttimestamp']) && $params['starttimestamp'] != '') {
             $reqArr['wpStarttime'] = wfTimestamp(TS_MW, $params['starttimestamp']);
         } else {
             $reqArr['wpStarttime'] = $reqArr['wpEdittime'];
         }
         // Fake wpStartime
         if ($params['minor'] || !$params['notminor'] && $wgUser->getOption('minordefault')) {
             $reqArr['wpMinoredit'] = '';
         }
         // Handle watchlist settings
         switch ($params['watchlist']) {
             case 'watch':
                 $watch = true;
                 break;
             case 'unwatch':
                 $watch = false;
                 break;
             case 'preferences':
                 if ($titleObj->exists()) {
                     $watch = $wgUser->getOption('watchdefault') || $titleObj->userIsWatching();
                 } else {
                     $watch = $wgUser->getOption('watchcreations');
                 }
                 break;
             case 'nochange':
             default:
                 $watch = $titleObj->userIsWatching();
         }
         // Deprecated parameters
         if ($params['watch']) {
             $watch = true;
         } elseif ($params['unwatch']) {
             $watch = false;
         }
         if ($watch) {
             $reqArr['wpWatchthis'] = '';
         }
         $req = new FauxRequest($reqArr, true);
         $ep->importFormData($req);
         // Run hooks
         // Handle CAPTCHA parameters
         global $wgRequest;
         if (!is_null($params['captchaid'])) {
             $wgRequest->setVal('wpCaptchaId', $params['captchaid']);
         }
         if (!is_null($params['captchaword'])) {
             $wgRequest->setVal('wpCaptchaWord', $params['captchaword']);
         }
         $r = array();
         if (!wfRunHooks('APIEditBeforeSave', array($ep, $ep->textbox1, &$r))) {
             if (count($r)) {
                 $r['result'] = "Failure";
                 $this->getResult()->addValue(null, $this->getModuleName(), $r);
                 return;
             } else {
                 $this->dieUsageMsg(array('hookaborted'));
             }
         }
         // Do the actual save
         $oldRevId = $articleObj->getRevIdFetched();
         $result = null;
         // Fake $wgRequest for some hooks inside EditPage
         // FIXME: This interface SUCKS
         $oldRequest = $wgRequest;
         $wgRequest = $req;
         $retval = $ep->internalAttemptSave($result, $wgUser->isAllowed('bot') && $params['bot']);
         $wgRequest = $oldRequest;
         switch ($retval) {
             case EditPage::AS_HOOK_ERROR:
             case EditPage::AS_HOOK_ERROR_EXPECTED:
                 $this->dieUsageMsg(array('hookaborted'));
             case EditPage::AS_IMAGE_REDIRECT_ANON:
                 $this->dieUsageMsg(array('noimageredirect-anon'));
             case EditPage::AS_IMAGE_REDIRECT_LOGGED:
                 $this->dieUsageMsg(array('noimageredirect-logged'));
             case EditPage::AS_SPAM_ERROR:
                 $this->dieUsageMsg(array('spamdetected', $result['spam']));
             case EditPage::AS_FILTERING:
                 $this->dieUsageMsg(array('filtered'));
             case EditPage::AS_BLOCKED_PAGE_FOR_USER:
                 $this->dieUsageMsg(array('blockedtext'));
             case EditPage::AS_MAX_ARTICLE_SIZE_EXCEEDED:
             case EditPage::AS_CONTENT_TOO_BIG:
                 global $wgMaxArticleSize;
                 $this->dieUsageMsg(array('contenttoobig', $wgMaxArticleSize));
             case EditPage::AS_READ_ONLY_PAGE_ANON:
                 $this->dieUsageMsg(array('noedit-anon'));
             case EditPage::AS_READ_ONLY_PAGE_LOGGED:
                 $this->dieUsageMsg(array('noedit'));
             case EditPage::AS_READ_ONLY_PAGE:
                 $this->dieReadOnly();
             case EditPage::AS_RATE_LIMITED:
                 $this->dieUsageMsg(array('actionthrottledtext'));
             case EditPage::AS_ARTICLE_WAS_DELETED:
                 $this->dieUsageMsg(array('wasdeleted'));
             case EditPage::AS_NO_CREATE_PERMISSION:
                 $this->dieUsageMsg(array('nocreate-loggedin'));
             case EditPage::AS_BLANK_ARTICLE:
                 $this->dieUsageMsg(array('blankpage'));
             case EditPage::AS_CONFLICT_DETECTED:
                 $this->dieUsageMsg(array('editconflict'));
                 // case EditPage::AS_SUMMARY_NEEDED: Can't happen since we set wpIgnoreBlankSummary
             // case EditPage::AS_SUMMARY_NEEDED: Can't happen since we set wpIgnoreBlankSummary
             case EditPage::AS_TEXTBOX_EMPTY:
                 $this->dieUsageMsg(array('emptynewsection'));
             case EditPage::AS_SUCCESS_NEW_ARTICLE:
                 $r['new'] = '';
             case EditPage::AS_SUCCESS_UPDATE:
                 $r['result'] = "Success";
                 $r['pageid'] = intval($titleObj->getArticleID());
                 $r['title'] = $titleObj->getPrefixedText();
                 // HACK: We create a new Article object here because getRevIdFetched()
                 // refuses to be run twice, and because Title::getLatestRevId()
                 // won't fetch from the master unless we select for update, which we
                 // don't want to do.
                 $newArticle = new Article($titleObj);
                 $newRevId = $newArticle->getRevIdFetched();
                 if ($newRevId == $oldRevId) {
                     $r['nochange'] = '';
                 } else {
                     $r['oldrevid'] = intval($oldRevId);
                     $r['newrevid'] = intval($newRevId);
                     $r['newtimestamp'] = wfTimestamp(TS_ISO_8601, $newArticle->getTimestamp());
                 }
                 break;
             case EditPage::AS_END:
                 // This usually means some kind of race condition
                 // or DB weirdness occurred. Fall through to throw an unknown
                 // error.
                 // This needs fixing higher up, as Article::doEdit should be
                 // used rather than Article::updateArticle, so that specific
                 // error conditions can be returned
             // This usually means some kind of race condition
             // or DB weirdness occurred. Fall through to throw an unknown
             // error.
             // This needs fixing higher up, as Article::doEdit should be
             // used rather than Article::updateArticle, so that specific
             // error conditions can be returned
             default:
                 $this->dieUsageMsg(array('unknownerror', $retval));
         }
         $this->getResult()->addValue(null, $this->getModuleName(), $r);
     } catch (Exception $e) {
         $this->dieUsage($e->getMessage(), 'WOM error');
     }
 }