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']; if ($title === null) { $titleProvided = false; // A title is needed for parsing, so arbitrarily choose one $title = 'API'; } else { $titleProvided = true; } $page = $params['page']; $pageid = $params['pageid']; $oldid = $params['oldid']; $model = $params['contentmodel']; $format = $params['contentformat']; if (!is_null($page) && (!is_null($text) || $titleProvided)) { $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 behavior of uselang $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'); } $this->checkReadPermissions($rev->getTitle()); 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 = $this->makeParserOptions($pageObj, $params); // 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'); } $this->checkReadPermissions($titleObj); $wgTitle = $titleObj; if (isset($prop['revid'])) { $oldid = $pageObj->getLatest(); } $popts = $this->makeParserOptions($pageObj, $params); // 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 || $titleObj->isExternal()) { $this->dieUsageMsg(array('invalidtitle', $title)); } $wgTitle = $titleObj; if ($titleObj->canExist()) { $pageObj = WikiPage::factory($titleObj); } else { // Do like MediaWiki::initializeArticle() $article = Article::newFromTitle($titleObj, $this->getContext()); $pageObj = $article->getPage(); } $popts = $this->makeParserOptions($pageObj, $params); $textProvided = !is_null($text); if (!$textProvided) { if ($titleProvided && ($prop || $params['generatexml'])) { $this->setWarning("'title' used without 'text', and parsed page properties were requested " . "(did you mean to use 'page' instead of 'title'?)"); } // Prevent warning from ContentHandler::makeContent() $text = ''; } // If we are parsing text, do not use the content model of the default // API title, but default to wikitext to keep BC. if ($textProvided && !$titleProvided && is_null($model)) { $model = CONTENT_MODEL_WIKITEXT; $this->setWarning("No 'title' or 'contentmodel' was given, assuming {$model}."); } 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(); ApiResult::setContent($result_array['text'], $this->pstContent->serialize($format)); if (isset($prop['wikitext'])) { $result_array['wikitext'] = array(); ApiResult::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 ($params['disabletoc']) { $p_result->setTOCEnabled(false); } if (isset($prop['text'])) { $result_array['text'] = array(); ApiResult::setContent($result_array['text'], $p_result->getText()); } if (!is_null($params['summary'])) { $result_array['parsedsummary'] = array(); ApiResult::setContent($result_array['parsedsummary'], Linker::formatComment($params['summary'], $titleObj)); } if (isset($prop['langlinks']) || isset($prop['languageshtml'])) { $langlinks = $p_result->getLanguageLinks(); if ($params['effectivelanglinks']) { // Link flags are ignored for now, but may in the future be // included in the result. $linkFlags = array(); wfRunHooks('LanguageLinks', array($titleObj, &$langlinks, &$linkFlags)); } } else { $langlinks = false; } if (isset($prop['langlinks'])) { $result_array['langlinks'] = $this->formatLangLinks($langlinks); } if (isset($prop['languageshtml'])) { $languagesHtml = $this->languagesHtml($langlinks); $result_array['languageshtml'] = array(); ApiResult::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(); ApiResult::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 = new DerivativeContext($this->getContext()); $context->setTitle($titleObj); $context->setWikiPage($pageObj); // We need an OutputPage tied to $context, not to the // RequestContext at the root of the stack. $output = new OutputPage($context); $output->addParserOutputNoText($p_result); if (isset($prop['headitems'])) { $headItems = $this->formatHeadItems($p_result->getHeadItems()); $css = $this->formatCss($output->buildCssLinksArray()); $scripts = array($output->getHeadScripts()); $result_array['headitems'] = array_merge($headItems, $css, $scripts); } if (isset($prop['headhtml'])) { $result_array['headhtml'] = array(); ApiResult::setContent($result_array['headhtml'], $output->headElement($context->getSkin())); } } if (isset($prop['iwlinks'])) { $result_array['iwlinks'] = $this->formatIWLinks($p_result->getInterwikiLinks()); } if (isset($prop['wikitext'])) { $result_array['wikitext'] = array(); ApiResult::setContent($result_array['wikitext'], $this->content->serialize($format)); if (!is_null($this->pstContent)) { $result_array['psttext'] = array(); ApiResult::setContent($result_array['psttext'], $this->pstContent->serialize($format)); } } if (isset($prop['properties'])) { $result_array['properties'] = $this->formatProperties($p_result->getProperties()); } if (isset($prop['limitreportdata'])) { $result_array['limitreportdata'] = $this->formatLimitReportData($p_result->getLimitReportData()); } if (isset($prop['limitreporthtml'])) { $limitreportHtml = EditPage::getPreviewLimitReport($p_result); $result_array['limitreporthtml'] = array(); ApiResult::setContent($result_array['limitreporthtml'], $limitreportHtml); } 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(); ApiResult::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', 'limitreportdata' => 'lr'); $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 } }
function outputPage(OutputPage $out = null) { global $wgTitle, $wgArticle, $wgUser, $wgLang, $wgContLang, $wgOut; global $wgScript, $wgStylePath, $wgLanguageCode, $wgContLanguageCode; global $wgMimeType, $wgOutputEncoding, $wgUseDatabaseMessages; global $wgRequest, $wgUseNewInterlanguage; global $wgDisableCounters, $wgLogo, $action, $wgFeedClasses; global $wgMaxCredits, $wgShowCreditsIfMax, $wgHideInterlanguageLinks; global $wgServer; global $wgSquidMaxage, $IP; $fname = __METHOD__; wfProfileIn($fname); wfRunHooks('BeforePageDisplay', array(&$wgOut, &$this)); $this->mTitle = $wgTitle; extract($wgRequest->getValues('oldid', 'diff')); wfProfileIn("{$fname}-init"); //$this->initPage( $out ); $tpl = $this->setupTemplate('WikiHowTemplate', 'skins'); $tpl->setTranslator(new MediaWiki_I18N()); wfProfileOut("{$fname}-init"); wfProfileIn("{$fname}-stuff"); $this->thispage = $wgTitle->getPrefixedDbKey(); $this->thisurl = $wgTitle->getPrefixedURL(); $this->loggedin = $wgUser->getID() != 0; $this->iscontent = $wgTitle->getNamespace() != NS_SPECIAL; $this->iseditable = ($this->iscontent and !($action == 'edit' or $action == 'submit')); $this->username = $wgUser->getName(); $this->userpage = $wgContLang->getNsText(NS_USER) . ":" . $wgUser->getName(); $this->userpageUrlDetails = $this->makeUrlDetails($this->userpage); $this->usercss = $this->userjs = $this->userjsprev = false; //$this->setupUserCss(); //$this->setupUserJs(false); $this->titletxt = $wgTitle->getPrefixedText(); wfProfileOut("{$fname}-stuff"); // add utm wfProfileIn("{$fname}-stuff2"); $tpl->set('title', $wgOut->getPageTitle()); $tpl->setRef("thispage", $this->thispage); $undelete = $this->getUndeleteLink(); $tpl->set("undelete", !empty($undelete) ? '<span class="subpages">' . $undelete . '</span>' : ''); $tpl->set('headscripts', $out->getHeadScripts() . $out->getHeadItems()); $description = ArticleMetaInfo::getCurrentTitleMetaDescription(); if ($description) { $wgOut->addMeta('description', $description); } $keywords = ArticleMetaInfo::getCurrentTitleMetaKeywords(); if ($keywords) { $wgOut->mKeywords = array(); $wgOut->addMeta('keywords', $keywords); } ArticleMetaInfo::addFacebookMetaProperties($tpl->data['title']); ArticleMetaInfo::addTwitterMetaProperties(); if ($wgOut->isSyndicated()) { $feeds = array(); foreach ($wgFeedClasses as $format => $class) { $feeds[$format] = array('text' => $format, 'href' => $wgRequest->appendQuery("feed={$format}"), 'ttip' => wfMessage('tooltip-' . $format)->text()); } $tpl->setRef('feeds', $feeds); } else { $tpl->set('feeds', false); } $tpl->setRef('mimetype', $wgMimeType); $tpl->setRef('charset', $wgOutputEncoding); $tpl->set('headlinks', $out->getHeadLinks()); $tpl->setRef('wgScript', $wgScript); $tpl->setRef('skinname', $this->skinname); $tpl->setRef('stylename', $this->stylename); $tpl->setRef('loggedin', $this->loggedin); $tpl->set('nsclass', 'ns-' . $wgTitle->getNamespace()); $tpl->set('notspecialpage', $wgTitle->getNamespace() != NS_SPECIAL); /* XXX currently unused, might get useful later $tpl->set( "editable", ($wgTitle->getNamespace() != NS_SPECIAL ) ); $tpl->set( "exists", $wgTitle->getArticleID() != 0 ); $tpl->set( "watch", $wgTitle->userIsWatching() ? "unwatch" : "watch" ); $tpl->set( "protect", count($wgTitle->isProtected()) ? "unprotect" : "protect" ); $tpl->set( "helppage", wfMessage('helppage')->text()); */ $tpl->set('searchaction', $this->escapeSearchLink()); $tpl->set('search', trim($wgRequest->getVal('search'))); $tpl->setRef('stylepath', $wgStylePath); $tpl->setRef('logopath', $wgLogo); $tpl->setRef("lang", $wgContLanguageCode); $tpl->set('dir', $wgContLang->isRTL() ? "rtl" : "ltr"); $tpl->set('rtl', $wgContLang->isRTL()); $tpl->set('langname', $wgContLang->getLanguageName($wgContLanguageCode)); $tpl->setRef('username', $this->username); $tpl->setRef('userpage', $this->userpage); $tpl->setRef('userpageurl', $this->userpageUrlDetails['href']); $tpl->setRef('usercss', $this->usercss); $tpl->setRef('userjs', $this->userjs); $tpl->setRef('userjsprev', $this->userjsprev); if ($this->iseditable && $wgUser->getOption('editsectiononrightclick')) { $tpl->set('body_onload', 'setupRightClickEdit()'); } else { $tpl->set('body_onload', false); } global $wgUseSiteJs; if ($wgUseSiteJs) { if ($this->loggedin) { $tpl->set('jsvarurl', $this->makeUrl($this->userpage . '/-', 'action=raw&gen=js&maxage=' . $wgSquidMaxage)); } else { $tpl->set('jsvarurl', $this->makeUrl('-', 'action=raw&gen=js')); } } else { $tpl->set('jsvarurl', false); } wfProfileOut("{$fname}-stuff2"); wfProfileIn("{$fname}-stuff3"); $tpl->setRef('newtalk', $ntl); $tpl->setRef('skin', $this); $tpl->set('logo', $this->logoText()); if ($wgOut->isArticle() and (!isset($oldid) or isset($diff)) and $this->getContext()->canUseWikiPage() && 0 != $this->getContext()->getWikiPage()->getId()) { if (!$wgDisableCounters) { $viewcount = $this->getContext()->getWikiPage()->getCount(); if ($viewcount) { $tpl->set('viewcount', wfMessage("viewcount", $viewcount)->text()); } else { $tpl->set('viewcount', false); } } else { $tpl->set('viewcount', false); } $tpl->set('lastmod', $this->lastModified()); $tpl->set('copyright', $this->getCopyright()); $this->credits = false; if (isset($wgMaxCredits) && $wgMaxCredits != 0) { require_once "{$IP}/includes/Credits.php"; $this->credits = getCredits($wgArticle, $wgMaxCredits, $wgShowCreditsIfMax); } $tpl->setRef('credits', $this->credits); } elseif (isset($oldid) && !isset($diff)) { $tpl->set('copyright', $this->getCopyright()); $tpl->set('viewcount', false); $tpl->set('lastmod', false); $tpl->set('credits', false); } else { $tpl->set('copyright', false); $tpl->set('viewcount', false); $tpl->set('lastmod', false); $tpl->set('credits', false); } wfProfileOut("{$fname}-stuff3"); wfProfileIn("{$fname}-stuff4"); $tpl->set('copyrightico', $this->getCopyrightIcon()); $tpl->set('poweredbyico', $this->getPoweredBy()); $tpl->set('disclaimer', $this->disclaimerLink()); $tpl->set('about', $this->aboutLink()); $tpl->setRef('debug', $out->mDebugtext); //$out->addHTML($printfooter); $tpl->set('bottomscripts', $this->bottomScripts()); if ($wgTitle->getNamespace() == NS_USER && $wgUser->getId() == 0 && !UserPagePolicy::isGoodUserPage($wgTitle->getDBKey())) { $txt = $out->parse(wfMessage('noarticletext_user')->text()); $tpl->setRef('bodytext', $txt); header('HTTP/1.1 404 Not Found'); } else { if (!is_null($out)) { $tpl->setRef('bodytext', $out->getHTML()); } } # Language links $language_urls = array(); if (!$wgHideInterlanguageLinks) { foreach ($wgOut->getLanguageLinks() as $l) { $tmp = explode(':', $l, 2); $class = 'interwiki-' . $tmp[0]; $code = $tmp[0]; $lTitle = $tmp[1]; unset($tmp); $nt = Title::newFromText($l); $language = $wgContLang->fetchLanguageName($nt->getInterwiki(), $wgLanguageCode); $language_urls[] = array('code' => $code, 'href' => $nt->getFullURL(), 'text' => $lTitle, 'class' => $class, 'language' => ($language != '' ? Misc::capitalize($language) : $l) . ": "); } } if (count($language_urls)) { $tpl->setRef('language_urls', $language_urls); } else { $tpl->set('language_urls', false); } wfProfileOut("{$fname}-stuff4"); # Personal toolbar //$tpl->set('personal_urls', $this->buildPersonalUrls()); /*$content_actions = $this->buildContentActionUrls(); $tpl->setRef('content_actions', $content_actions); // XXX: attach this from javascript, same with section editing if($this->iseditable && $wgUser->getOption("editondblclick") ) { $tpl->set('body_ondblclick', 'document.location = "' .$content_actions['edit']['href'] .'";'); } else { $tpl->set('body_ondblclick', false); } */ //$tpl->set( 'navigation_urls', $this->buildNavigationUrls() ); //$tpl->set( 'nav_urls', $this->buildNavUrls() ); // execute template wfProfileIn("{$fname}-execute"); $res = $tpl->execute(); wfProfileOut("{$fname}-execute"); // result may be an error $this->printOrError($res); wfProfileOut($fname); }