/** * @param \Article $article * @return JsonFormatNode */ public function getJsonFormatForArticle(\Article $article) { $measurement = \Wikia\Measurements\Time::start([__CLASS__, __METHOD__]); $html = $article->getPage()->getParserOutput(\ParserOptions::newFromContext($this->requestContext))->getText(); $measurement->stop(); return $this->htmlParser->parse($html); }
public function index() { $title = Title::newFromText('Version', NS_SPECIAL); $popts = ParserOptions::newFromContext(RequestContext::getMain()); $this->wg->Title = $title; $this->specialPage->setHeaders(); $softwareListPrepped = array(); foreach ($this->version->getSoftwareList() as $key => $val) { $softwareListPrepped[$this->wg->Parser->parse($key, $title, $popts)->getText()] = $this->wg->Parser->parse($val, $title, $popts)->getText(); } $this->setVal('copyRightAndAuthorList', $this->wg->Parser->parse($this->version->getCopyrightAndAuthorList(), $title, $popts)->getText()); $this->setVal('softwareInformation', $this->wg->Parser->parse($this->version->softwareInformation(), $title, $popts)->getText()); $this->setVal('extensionCredit', $this->wg->Parser->parse($this->version->getExtensionCredits(), $title, $popts)->getText()); $this->setVal('ip', str_replace('--', ' - ', htmlspecialchars($this->getContext()->getRequest()->getIP()))); $this->setVal('wikiaCodeMessage', wfMessage('wikia-version-code')->escaped()); $this->setVal('wikiaCodeVersion', $this->version->getWikiaCodeVersion()); $this->setVal('wikiaConfigMessage', wfMessage('wikia-version-config')->escaped()); $this->setVal('wikiaConfigVersion', $this->version->getWikiaConfigVersion()); $this->setVal('versionLicenseMessage', wfMessage('version-license')->escaped()); $this->setVal('versionLicenseInfoMessage', wfMessage('version-license-info')->parse()); $this->setVal('versionSoftwareMessage', wfMessage('version-software')->escaped()); $this->setVal('versionSoftwareProductMessage', wfMessage('version-software-product')->escaped()); $this->setVal('versionSoftwareVersionMessage', wfMessage('version-software-version')->escaped()); $this->setVal('versionSoftwareList', $softwareListPrepped); }
public function execute() { // Cache may vary on $wgUser because ParserOptions gets data from it $this->getMain()->setCacheMode('anon-public-user-private'); // Get parameters $params = $this->extractRequestParams(); // Create title for parser $title_obj = Title::newFromText($params['title']); if (!$title_obj) { $this->dieUsageMsg(array('invalidtitle', $params['title'])); } $result = $this->getResult(); // Parse text global $wgParser; $options = ParserOptions::newFromContext($this->getContext()); if ($params['includecomments']) { $options->setRemoveComments(false); } if ($params['generatexml']) { $wgParser->startExternalParse($title_obj, $options, OT_PREPROCESS); $dom = $wgParser->preprocessToDom($params['text']); if (is_callable(array($dom, 'saveXML'))) { $xml = $dom->saveXML(); } else { $xml = $dom->__toString(); } $xml_result = array(); $result->setContent($xml_result, $xml); $result->addValue(null, 'parsetree', $xml_result); } $retval = $wgParser->preprocess($params['text'], $title_obj, $options); // Return result $retval_array = array(); $result->setContent($retval_array, $retval); $result->addValue(null, $this->getModuleName(), $retval_array); }
/** * Get/set the ParserOptions object to use for wikitext parsing * * @param ParserOptions|null $options Either the ParserOption to use or null to only get the * current ParserOption object * @return ParserOptions */ public function parserOptions($options = null) { if ($options !== null && !empty($options->isBogus)) { // Someone is trying to set a bogus pre-$wgUser PO. Check if it has // been changed somehow, and keep it if so. $anonPO = ParserOptions::newFromAnon(); $anonPO->setEditSection(false); if (!$options->matches($anonPO)) { wfLogWarning(__METHOD__ . ': Setting a changed bogus ParserOptions: ' . wfGetAllCallers(5)); $options->isBogus = false; } } if (!$this->mParserOptions) { if (!$this->getContext()->getUser()->isSafeToLoad()) { // $wgUser isn't unstubbable yet, so don't try to get a // ParserOptions for it. And don't cache this ParserOptions // either. $po = ParserOptions::newFromAnon(); $po->setEditSection(false); $po->isBogus = true; if ($options !== null) { $this->mParserOptions = empty($options->isBogus) ? $options : null; } return $po; } $this->mParserOptions = ParserOptions::newFromContext($this->getContext()); $this->mParserOptions->setEditSection(false); } if ($options !== null && !empty($options->isBogus)) { // They're trying to restore the bogus pre-$wgUser PO. Do the right // thing. return wfSetVar($this->mParserOptions, null, true); } else { return wfSetVar($this->mParserOptions, $options); } }
/** * @group medium * @dataProvider parserTestProvider * @param string $desc * @param string $input * @param string $result * @param array $opts * @param array $config */ public function testParserTest($desc, $input, $result, $opts, $config) { if ($this->regex != '' && !preg_match('/' . $this->regex . '/', $desc)) { $this->assertTrue(true); // XXX: don't flood output with "test made no assertions" // $this->markTestSkipped( 'Filtered out by the user' ); return; } if (!$this->isWikitextNS(NS_MAIN)) { // parser tests frequently assume that the main namespace contains wikitext. // @todo When setting up pages, force the content model. Only skip if // $wgtContentModelUseDB is false. $this->markTestSkipped("Main namespace does not support wikitext," . "skipping parser test: {$desc}"); } wfDebug("Running parser test: {$desc}\n"); $opts = $this->parseOptions($opts); $context = $this->setupGlobals($opts, $config); $user = $context->getUser(); $options = ParserOptions::newFromContext($context); if (isset($opts['title'])) { $titleText = $opts['title']; } else { $titleText = 'Parser test'; } $local = isset($opts['local']); $preprocessor = isset($opts['preprocessor']) ? $opts['preprocessor'] : null; $parser = $this->getParser($preprocessor); $title = Title::newFromText($titleText); # Parser test requiring math. Make sure texvc is executable # or just skip such tests. if (isset($opts['math']) || isset($opts['texvc'])) { global $wgTexvc; if (!isset($wgTexvc)) { $this->markTestSkipped("SKIPPED: \$wgTexvc is not set"); } elseif (!is_executable($wgTexvc)) { $this->markTestSkipped("SKIPPED: texvc binary does not exist" . " or is not executable.\n" . "Current configuration is:\n\$wgTexvc = '{$wgTexvc}'"); } } if (isset($opts['djvu'])) { if (!$this->djVuSupport->isEnabled()) { $this->markTestSkipped("SKIPPED: djvu binaries do not exist or are not executable.\n"); } } if (isset($opts['tidy'])) { if (!$this->tidySupport->isEnabled()) { $this->markTestSkipped("SKIPPED: tidy extension is not installed.\n"); } else { $options->setTidy(true); } } if (isset($opts['pst'])) { $out = $parser->preSaveTransform($input, $title, $user, $options); } elseif (isset($opts['msg'])) { $out = $parser->transformMsg($input, $options, $title); } elseif (isset($opts['section'])) { $section = $opts['section']; $out = $parser->getSection($input, $section); } elseif (isset($opts['replace'])) { $section = $opts['replace'][0]; $replace = $opts['replace'][1]; $out = $parser->replaceSection($input, $section, $replace); } elseif (isset($opts['comment'])) { $out = Linker::formatComment($input, $title, $local); } elseif (isset($opts['preload'])) { $out = $parser->getPreloadText($input, $title, $options); } else { $output = $parser->parse($input, $title, $options, true, true, 1337); $output->setTOCEnabled(!isset($opts['notoc'])); $out = $output->getText(); if (isset($opts['tidy'])) { $out = preg_replace('/\\s+$/', '', $out); } if (isset($opts['showtitle'])) { if ($output->getTitleText()) { $title = $output->getTitleText(); } $out = "{$title}\n{$out}"; } if (isset($opts['showindicators'])) { $indicators = ''; foreach ($output->getIndicators() as $id => $content) { $indicators .= "{$id}={$content}\n"; } $out = $indicators . $out; } if (isset($opts['ill'])) { $out = implode(' ', $output->getLanguageLinks()); } elseif (isset($opts['cat'])) { $outputPage = $context->getOutput(); $outputPage->addCategoryLinks($output->getCategories()); $cats = $outputPage->getCategoryLinks(); if (isset($cats['normal'])) { $out = implode(' ', $cats['normal']); } else { $out = ''; } } $parser->mPreprocessor = null; } $this->teardownGlobals(); $this->assertEquals($result, $out, $desc); }
/** * Wrapper around OutputPage::parseInline * * @param $value String Wikitext to parse * @param $lang Language * * @since 1.3 * * @return String parsed wikitext */ private function parseValue($value, Language $lang) { global $wgParser; wfProfileIn(__METHOD__); $parserOptions = ParserOptions::newFromContext($this->context); $parserOptions->setEditSection(false); $parserOptions->setInterfaceMessage(true); $parserOptions->setUserLang($lang); $parserOptions->setTargetLanguage($lang); $output = $wgParser->parse($value, $this->getTitle(), $parserOptions); $parsed = $output->getText(); // Strip out the surrounding <p> tags $m = array(); if (preg_match('/^<p>(.*)\\n?<\\/p>\\n?/sU', $parsed, $m)) { $parsed = $m[1]; } $this->updateTemplates($output); wfProfileOut(__METHOD__); return $parsed; }
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 } }
/** * Get parser options suitable for rendering the primary article wikitext * * @param IContextSource|User|string $context One of the following: * - IContextSource: Use the User and the Language of the provided * context * - User: Use the provided User object and $wgLang for the language, * so use an IContextSource object if possible. * - 'canonical': Canonical options (anonymous user with default * preferences and content language). * @return ParserOptions */ public function makeParserOptions($context) { global $wgContLang; if ($context instanceof IContextSource) { $options = ParserOptions::newFromContext($context); } elseif ($context instanceof User) { // settings per user (even anons) $options = ParserOptions::newFromUser($context); } else { // canonical settings $options = ParserOptions::newFromUserAndLang(new User(), $wgContLang); } if ($this->getTitle()->isConversionTable()) { $options->disableContentConversion(); } $options->enableLimitReport(); // show inclusion/loop reports $options->setTidy(true); // fix bad HTML return $options; }
public function execute() { // Cache may vary on $wgUser because ParserOptions gets data from it $this->getMain()->setCacheMode('anon-public-user-private'); // Get parameters $params = $this->extractRequestParams(); $this->requireMaxOneParameter($params, 'prop', 'generatexml'); if ($params['prop'] === null) { $this->logFeatureUsage('action=expandtemplates&!prop'); $this->setWarning('Because no values have been specified for the prop parameter, a ' . 'legacy format has been used for the output. This format is deprecated, and in ' . 'the future, a default value will be set for the prop parameter, causing the new' . 'format to always be used.'); $prop = array(); } else { $prop = array_flip($params['prop']); } // Get title and revision ID for parser $revid = $params['revid']; if ($revid !== null) { $rev = Revision::newFromId($revid); if (!$rev) { $this->dieUsage("There is no revision ID {$revid}", 'missingrev'); } $title_obj = $rev->getTitle(); } else { $title_obj = Title::newFromText($params['title']); if (!$title_obj || $title_obj->isExternal()) { $this->dieUsageMsg(array('invalidtitle', $params['title'])); } } $result = $this->getResult(); // Parse text global $wgParser; $options = ParserOptions::newFromContext($this->getContext()); if ($params['includecomments']) { $options->setRemoveComments(false); } $retval = array(); if (isset($prop['parsetree']) || $params['generatexml']) { $wgParser->startExternalParse($title_obj, $options, Parser::OT_PREPROCESS); $dom = $wgParser->preprocessToDom($params['text']); if (is_callable(array($dom, 'saveXML'))) { $xml = $dom->saveXML(); } else { $xml = $dom->__toString(); } if (isset($prop['parsetree'])) { unset($prop['parsetree']); $retval['parsetree'] = $xml; } else { // the old way $result->addValue(null, 'parsetree', $xml); $result->addValue(null, ApiResult::META_BC_SUBELEMENTS, array('parsetree')); } } // if they didn't want any output except (probably) the parse tree, // then don't bother actually fully expanding it if ($prop || $params['prop'] === null) { $wgParser->startExternalParse($title_obj, $options, Parser::OT_PREPROCESS); $frame = $wgParser->getPreprocessor()->newFrame(); $wikitext = $wgParser->preprocess($params['text'], $title_obj, $options, $revid, $frame); if ($params['prop'] === null) { // the old way ApiResult::setContentValue($retval, 'wikitext', $wikitext); } else { $p_output = $wgParser->getOutput(); if (isset($prop['categories'])) { $categories = $p_output->getCategories(); if ($categories) { $categories_result = array(); foreach ($categories as $category => $sortkey) { $entry = array(); $entry['sortkey'] = $sortkey; ApiResult::setContentValue($entry, 'category', $category); $categories_result[] = $entry; } ApiResult::setIndexedTagName($categories_result, 'category'); $retval['categories'] = $categories_result; } } if (isset($prop['properties'])) { $properties = $p_output->getProperties(); if ($properties) { ApiResult::setArrayType($properties, 'BCkvp', 'name'); ApiResult::setIndexedTagName($properties, 'property'); $retval['properties'] = $properties; } } if (isset($prop['volatile'])) { $retval['volatile'] = $frame->isVolatile(); } if (isset($prop['ttl']) && $frame->getTTL() !== null) { $retval['ttl'] = $frame->getTTL(); } if (isset($prop['wikitext'])) { $retval['wikitext'] = $wikitext; } if (isset($prop['modules'])) { $retval['modules'] = array_values(array_unique($p_output->getModules())); $retval['modulescripts'] = array_values(array_unique($p_output->getModuleScripts())); $retval['modulestyles'] = array_values(array_unique($p_output->getModuleStyles())); } if (isset($prop['jsconfigvars'])) { $retval['jsconfigvars'] = ApiResult::addMetadataToResultVars($p_output->getJsConfigVars()); } if (isset($prop['encodedjsconfigvars'])) { $retval['encodedjsconfigvars'] = FormatJson::encode($p_output->getJsConfigVars(), false, FormatJson::ALL_OK); $retval[ApiResult::META_SUBELEMENTS][] = 'encodedjsconfigvars'; } if (isset($prop['modules']) && !isset($prop['jsconfigvars']) && !isset($prop['encodedjsconfigvars'])) { $this->setWarning("Property 'modules' was set but not 'jsconfigvars' " . "or 'encodedjsconfigvars'. Configuration variables are necessary " . "for proper module usage."); } } } ApiResult::setSubelementsList($retval, array('wikitext', 'parsetree')); $result->addValue(null, $this->getModuleName(), $retval); }
private function extractRowInfo($row) { $revision = new Revision($row); $title = $revision->getTitle(); $vals = array(); if ($this->fld_ids) { $vals['revid'] = intval($revision->getId()); // $vals['oldid'] = intval( $row->rev_text_id ); // todo: should this be exposed? if (!is_null($revision->getParentId())) { $vals['parentid'] = intval($revision->getParentId()); } } if ($this->fld_flags && $revision->isMinor()) { $vals['minor'] = ''; } if ($this->fld_user || $this->fld_userid) { if ($revision->isDeleted(Revision::DELETED_USER)) { $vals['userhidden'] = ''; } else { if ($this->fld_user) { $vals['user'] = $revision->getUserText(); } $userid = $revision->getUser(); if (!$userid) { $vals['anon'] = ''; } if ($this->fld_userid) { $vals['userid'] = $userid; } } } if ($this->fld_timestamp) { $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $revision->getTimestamp()); } if ($this->fld_size) { if (!is_null($revision->getSize())) { $vals['size'] = intval($revision->getSize()); } else { $vals['size'] = 0; } } if ($this->fld_sha1) { if ($revision->getSha1() != '') { $vals['sha1'] = wfBaseConvert($revision->getSha1(), 36, 16, 40); } else { $vals['sha1'] = ''; } } if ($this->fld_comment || $this->fld_parsedcomment) { if ($revision->isDeleted(Revision::DELETED_COMMENT)) { $vals['commenthidden'] = ''; } else { $comment = $revision->getComment(); if ($this->fld_comment) { $vals['comment'] = $comment; } if ($this->fld_parsedcomment) { $vals['parsedcomment'] = Linker::formatComment($comment, $title); } } } if ($this->fld_tags) { if ($row->ts_tags) { $tags = explode(',', $row->ts_tags); $this->getResult()->setIndexedTagName($tags, 'tag'); $vals['tags'] = $tags; } else { $vals['tags'] = array(); } } if (!is_null($this->token)) { $tokenFunctions = $this->getTokenFunctions(); foreach ($this->token as $t) { $val = call_user_func($tokenFunctions[$t], $title->getArticleID(), $title, $revision); if ($val === false) { $this->setWarning("Action '{$t}' is not allowed for the current user"); } else { $vals[$t . 'token'] = $val; } } } $text = null; global $wgParser; if ($this->fld_content || !is_null($this->difftotext)) { $text = $revision->getText(); // Expand templates after getting section content because // template-added sections don't count and Parser::preprocess() // will have less input if ($this->section !== false) { $text = $wgParser->getSection($text, $this->section, false); if ($text === false) { $this->dieUsage("There is no section {$this->section} in r" . $revision->getId(), 'nosuchsection'); } } } if ($this->fld_content && !$revision->isDeleted(Revision::DELETED_TEXT)) { if ($this->generateXML) { $wgParser->startExternalParse($title, ParserOptions::newFromContext($this->getContext()), OT_PREPROCESS); $dom = $wgParser->preprocessToDom($text); if (is_callable(array($dom, 'saveXML'))) { $xml = $dom->saveXML(); } else { $xml = $dom->__toString(); } $vals['parsetree'] = $xml; } if ($this->expandTemplates && !$this->parseContent) { $text = $wgParser->preprocess($text, $title, ParserOptions::newFromContext($this->getContext())); } if ($this->parseContent) { $text = $wgParser->parse($text, $title, ParserOptions::newFromContext($this->getContext()))->getText(); } ApiResult::setContent($vals, $text); } elseif ($this->fld_content) { $vals['texthidden'] = ''; } if (!is_null($this->diffto) || !is_null($this->difftotext)) { global $wgAPIMaxUncachedDiffs; static $n = 0; // Number of uncached diffs we've had if ($n < $wgAPIMaxUncachedDiffs) { $vals['diff'] = array(); $context = new DerivativeContext($this->getContext()); $context->setTitle($title); if (!is_null($this->difftotext)) { $engine = new DifferenceEngine($context); $engine->setText($text, $this->difftotext); } else { $engine = new DifferenceEngine($context, $revision->getID(), $this->diffto); $vals['diff']['from'] = $engine->getOldid(); $vals['diff']['to'] = $engine->getNewid(); } $difftext = $engine->getDiffBody(); ApiResult::setContent($vals['diff'], $difftext); if (!$engine->wasCacheHit()) { $n++; } } else { $vals['diff']['notcached'] = ''; } } return $vals; }
/** * Get the text that should be returned, or false if the page or revision * was not found. * * @return String|Bool */ public function getRawText() { global $wgParser; # No longer used if ($this->mGen) { return ''; } $text = false; $title = $this->getTitle(); $request = $this->getRequest(); // If it's a MediaWiki message we can just hit the message cache if ($request->getBool('usemsgcache') && $title->getNamespace() == NS_MEDIAWIKI) { // The first "true" is to use the database, the second is to use the content langue // and the last one is to specify the message key already contains the language in it ("/de", etc.) $text = MessageCache::singleton()->get($title->getDBkey(), true, true, true); // If the message doesn't exist, return a blank if ($text === false) { $text = ''; } } else { // Get it from the DB $rev = Revision::newFromTitle($title, $this->getOldId()); if ($rev) { $lastmod = wfTimestamp(TS_RFC2822, $rev->getTimestamp()); $request->response()->header("Last-modified: {$lastmod}"); // Public-only due to cache headers $content = $rev->getContent(); if ($content === null) { // revision not found (or suppressed) $text = false; } elseif (!$content instanceof TextContent) { // non-text content wfHttpError(415, "Unsupported Media Type", "The requested page uses the content model `" . $content->getModel() . "` which is not supported via this interface."); die; } else { // want a section? $section = $request->getIntOrNull('section'); if ($section !== null) { $content = $content->getSection($section); } if ($content === null || $content === false) { // section not found (or section not supported, e.g. for JS and CSS) $text = false; } else { $text = $content->getNativeData(); } } } } if ($text !== false && $text !== '' && $request->getVal('templates') === 'expand') { $text = $wgParser->preprocess($text, $title, ParserOptions::newFromContext($this->getContext())); } return $text; }
/** * Run a given wikitext input through a freshly-constructed wiki parser, * and compare the output against the expected results. * Prints status and explanatory messages to stdout. * * staticSetup() and setupWikiData() must be called before this function * is entered. * * @param array $test The test parameters: * - test: The test name * - desc: The subtest description * - input: Wikitext to try rendering * - options: Array of test options * - config: Overrides for global variables, one per line * * @return ParserTestResult or false if skipped */ public function runTest($test) { wfDebug(__METHOD__ . ": running {$test['desc']}"); $opts = $this->parseOptions($test['options']); $teardownGuard = $this->perTestSetup($test); $context = RequestContext::getMain(); $user = $context->getUser(); $options = ParserOptions::newFromContext($context); if (isset($opts['tidy'])) { if (!$this->tidySupport->isEnabled()) { $this->recorder->skipped($test, 'tidy extension is not installed'); return false; } else { $options->setTidy(true); } } if (isset($opts['title'])) { $titleText = $opts['title']; } else { $titleText = 'Parser test'; } $local = isset($opts['local']); $preprocessor = isset($opts['preprocessor']) ? $opts['preprocessor'] : null; $parser = $this->getParser($preprocessor); $title = Title::newFromText($titleText); if (isset($opts['pst'])) { $out = $parser->preSaveTransform($test['input'], $title, $user, $options); } elseif (isset($opts['msg'])) { $out = $parser->transformMsg($test['input'], $options, $title); } elseif (isset($opts['section'])) { $section = $opts['section']; $out = $parser->getSection($test['input'], $section); } elseif (isset($opts['replace'])) { $section = $opts['replace'][0]; $replace = $opts['replace'][1]; $out = $parser->replaceSection($test['input'], $section, $replace); } elseif (isset($opts['comment'])) { $out = Linker::formatComment($test['input'], $title, $local); } elseif (isset($opts['preload'])) { $out = $parser->getPreloadText($test['input'], $title, $options); } else { $output = $parser->parse($test['input'], $title, $options, true, true, 1337); $output->setTOCEnabled(!isset($opts['notoc'])); $out = $output->getText(); if (isset($opts['tidy'])) { $out = preg_replace('/\\s+$/', '', $out); } if (isset($opts['showtitle'])) { if ($output->getTitleText()) { $title = $output->getTitleText(); } $out = "{$title}\n{$out}"; } if (isset($opts['showindicators'])) { $indicators = ''; foreach ($output->getIndicators() as $id => $content) { $indicators .= "{$id}={$content}\n"; } $out = $indicators . $out; } if (isset($opts['ill'])) { $out = implode(' ', $output->getLanguageLinks()); } elseif (isset($opts['cat'])) { $out = ''; foreach ($output->getCategories() as $name => $sortkey) { if ($out !== '') { $out .= "\n"; } $out .= "cat={$name} sort={$sortkey}"; } } } ScopedCallback::consume($teardownGuard); $expected = $test['result']; if (count($this->normalizationFunctions)) { $expected = ParserTestResultNormalizer::normalize($test['expected'], $this->normalizationFunctions); $out = ParserTestResultNormalizer::normalize($out, $this->normalizationFunctions); } $testResult = new ParserTestResult($test, $expected, $out); return $testResult; }
/** * Get the text that should be returned, or false if the page or revision * was not found. * * @return String|Bool */ public function getRawText() { global $wgParser; # No longer used if ($this->mGen) { return ''; } $text = false; $title = $this->getTitle(); $request = $this->getRequest(); // If it's a MediaWiki message we can just hit the message cache if ($request->getBool('usemsgcache') && $title->getNamespace() == NS_MEDIAWIKI) { $key = $title->getDBkey(); $msg = wfMessage($key)->inContentLanguage(); # If the message doesn't exist, return a blank $text = !$msg->exists() ? '' : $msg->plain(); } else { // Get it from the DB $rev = Revision::newFromTitle($title, $this->getOldId()); if ($rev) { $lastmod = wfTimestamp(TS_RFC2822, $rev->getTimestamp()); $request->response()->header("Last-modified: {$lastmod}"); // Public-only due to cache headers $text = $rev->getText(); $section = $request->getIntOrNull('section'); if ($section !== null) { $text = $wgParser->getSection($text, $section); } } } if ($text !== false && $text !== '' && $request->getVal('templates') === 'expand') { $text = $wgParser->preprocess($text, $title, ParserOptions::newFromContext($this->getContext())); } return $text; }
/** * @param $user User * @param $context IContextSource * @param $defaultPreferences * @return void */ static function profilePreferences($user, IContextSource $context, &$defaultPreferences) { global $wgAuth, $wgContLang, $wgParser, $wgCookieExpiration, $wgLanguageCode, $wgDisableTitleConversion, $wgDisableLangConversion, $wgMaxSigChars, $wgEnableEmail, $wgEmailConfirmToEdit, $wgEnableUserEmail, $wgEmailAuthentication, $wgEnotifWatchlist, $wgEnotifUserTalk, $wgEnotifRevealEditorAddress; ## User info ##################################### // Information panel $defaultPreferences['username'] = array('type' => 'info', 'label-message' => 'username', 'default' => $user->getName(), 'section' => 'personal/info'); $defaultPreferences['userid'] = array('type' => 'info', 'label-message' => 'uid', 'default' => $user->getId(), 'section' => 'personal/info'); # Get groups to which the user belongs $userEffectiveGroups = $user->getEffectiveGroups(); $userGroups = $userMembers = array(); foreach ($userEffectiveGroups as $ueg) { if ($ueg == '*') { // Skip the default * group, seems useless here continue; } $groupName = User::getGroupName($ueg); $userGroups[] = User::makeGroupLinkHTML($ueg, $groupName); $memberName = User::getGroupMember($ueg, $user->getName()); $userMembers[] = User::makeGroupLinkHTML($ueg, $memberName); } asort($userGroups); asort($userMembers); $lang = $context->getLanguage(); $defaultPreferences['usergroups'] = array('type' => 'info', 'label' => $context->msg('prefs-memberingroups')->numParams(count($userGroups))->parse(), 'default' => $context->msg('prefs-memberingroups-type', $lang->commaList($userGroups), $lang->commaList($userMembers))->plain(), 'raw' => true, 'section' => 'personal/info'); $defaultPreferences['editcount'] = array('type' => 'info', 'label-message' => 'prefs-edits', 'default' => $lang->formatNum($user->getEditCount()), 'section' => 'personal/info'); if ($user->getRegistration()) { $displayUser = $context->getUser(); $userRegistration = $user->getRegistration(); $defaultPreferences['registrationdate'] = array('type' => 'info', 'label-message' => 'prefs-registration', 'default' => $context->msg('prefs-registration-date-time', $lang->userTimeAndDate($userRegistration, $displayUser), $lang->userDate($userRegistration, $displayUser), $lang->userTime($userRegistration, $displayUser))->parse(), 'section' => 'personal/info'); } // Actually changeable stuff $defaultPreferences['realname'] = array('type' => $wgAuth->allowPropChange('realname') ? 'text' : 'info', 'default' => $user->getRealName(), 'section' => 'personal/info', 'label-message' => 'yourrealname', 'help-message' => 'prefs-help-realname'); $defaultPreferences['gender'] = array('type' => 'select', 'section' => 'personal/info', 'options' => array($context->msg('gender-male')->text() => 'male', $context->msg('gender-female')->text() => 'female', $context->msg('gender-unknown')->text() => 'unknown'), 'label-message' => 'yourgender', 'help-message' => 'prefs-help-gender'); if ($wgAuth->allowPasswordChange()) { $link = Linker::link(SpecialPage::getTitleFor('ChangePassword'), $context->msg('prefs-resetpass')->escaped(), array(), array('returnto' => SpecialPage::getTitleFor('Preferences'))); $defaultPreferences['password'] = array('type' => 'info', 'raw' => true, 'default' => $link, 'label-message' => 'yourpassword', 'section' => 'personal/info'); } if ($wgCookieExpiration > 0) { $defaultPreferences['rememberpassword'] = array('type' => 'toggle', 'label' => $context->msg('tog-rememberpassword')->numParams(ceil($wgCookieExpiration / (3600 * 24)))->text(), 'section' => 'personal/info'); } // Language $languages = Language::getLanguageNames(false); if (!array_key_exists($wgLanguageCode, $languages)) { $languages[$wgLanguageCode] = $wgLanguageCode; } ksort($languages); $options = array(); foreach ($languages as $code => $name) { $display = wfBCP47($code) . ' - ' . $name; $options[$display] = $code; } $defaultPreferences['language'] = array('type' => 'select', 'section' => 'personal/i18n', 'options' => $options, 'label-message' => 'yourlanguage'); /* see if there are multiple language variants to choose from*/ $variantArray = array(); if (!$wgDisableLangConversion) { $variants = $wgContLang->getVariants(); foreach ($variants as $v) { $v = str_replace('_', '-', strtolower($v)); $variantArray[$v] = $wgContLang->getVariantname($v, false); } $options = array(); foreach ($variantArray as $code => $name) { $display = wfBCP47($code) . ' - ' . $name; $options[$display] = $code; } if (count($variantArray) > 1) { $defaultPreferences['variant'] = array('label-message' => 'yourvariant', 'type' => 'select', 'options' => $options, 'section' => 'personal/i18n', 'help-message' => 'prefs-help-variant'); } } if (count($variantArray) > 1 && !$wgDisableLangConversion && !$wgDisableTitleConversion) { $defaultPreferences['noconvertlink'] = array('type' => 'toggle', 'section' => 'personal/i18n', 'label-message' => 'tog-noconvertlink'); } // show a preview of the old signature first $oldsigWikiText = $wgParser->preSaveTransform("~~~", $context->getTitle(), $user, ParserOptions::newFromContext($context)); $oldsigHTML = $context->getOutput()->parseInline($oldsigWikiText, true, true); $defaultPreferences['oldsig'] = array('type' => 'info', 'raw' => true, 'label-message' => 'tog-oldsig', 'default' => $oldsigHTML, 'section' => 'personal/signature'); $defaultPreferences['nickname'] = array('type' => $wgAuth->allowPropChange('nickname') ? 'text' : 'info', 'maxlength' => $wgMaxSigChars, 'label-message' => 'yournick', 'validation-callback' => array('Preferences', 'validateSignature'), 'section' => 'personal/signature', 'filter-callback' => array('Preferences', 'cleanSignature')); $defaultPreferences['fancysig'] = array('type' => 'toggle', 'label-message' => 'tog-fancysig', 'help-message' => 'prefs-help-signature', 'section' => 'personal/signature'); ## Email stuff if ($wgEnableEmail) { $helpMessages[] = $wgEmailConfirmToEdit ? 'prefs-help-email-required' : 'prefs-help-email'; if ($wgEnableUserEmail) { // additional messages when users can send email to each other $helpMessages[] = 'prefs-help-email-others'; } $link = Linker::link(SpecialPage::getTitleFor('ChangeEmail'), $context->msg($user->getEmail() ? 'prefs-changeemail' : 'prefs-setemail')->escaped(), array(), array('returnto' => SpecialPage::getTitleFor('Preferences'))); $emailAddress = $user->getEmail() ? htmlspecialchars($user->getEmail()) : ''; if ($wgAuth->allowPropChange('emailaddress')) { $emailAddress .= $emailAddress == '' ? $link : " ({$link})"; } $defaultPreferences['emailaddress'] = array('type' => 'info', 'raw' => true, 'default' => $emailAddress, 'label-message' => 'youremail', 'section' => 'personal/email', 'help-messages' => $helpMessages); $disableEmailPrefs = false; if ($wgEmailAuthentication) { if ($user->getEmail()) { if ($user->getEmailAuthenticationTimestamp()) { // date and time are separate parameters to facilitate localisation. // $time is kept for backward compat reasons. // 'emailauthenticated' is also used in SpecialConfirmemail.php $displayUser = $context->getUser(); $emailTimestamp = $user->getEmailAuthenticationTimestamp(); $time = $lang->userTimeAndDate($emailTimestamp, $displayUser); $d = $lang->userDate($emailTimestamp, $displayUser); $t = $lang->userTime($emailTimestamp, $displayUser); $emailauthenticated = $context->msg('emailauthenticated', $time, $d, $t)->parse() . '<br />'; $disableEmailPrefs = false; } else { $disableEmailPrefs = true; $emailauthenticated = $context->msg('emailnotauthenticated')->parse() . '<br />' . Linker::linkKnown(SpecialPage::getTitleFor('Confirmemail'), $context->msg('emailconfirmlink')->escaped()) . '<br />'; } } else { $disableEmailPrefs = true; $emailauthenticated = $context->msg('noemailprefs')->escaped(); } $defaultPreferences['emailauthentication'] = array('type' => 'info', 'raw' => true, 'section' => 'personal/email', 'label-message' => 'prefs-emailconfirm-label', 'default' => $emailauthenticated); } if ($wgEnableUserEmail && $user->isAllowed('sendemail')) { $defaultPreferences['disablemail'] = array('type' => 'toggle', 'invert' => true, 'section' => 'personal/email', 'label-message' => 'allowemail', 'disabled' => $disableEmailPrefs); $defaultPreferences['ccmeonemails'] = array('type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-ccmeonemails', 'disabled' => $disableEmailPrefs); } if ($wgEnotifWatchlist) { $defaultPreferences['enotifwatchlistpages'] = array('type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifwatchlistpages', 'disabled' => $disableEmailPrefs); } if ($wgEnotifUserTalk) { $defaultPreferences['enotifusertalkpages'] = array('type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifusertalkpages', 'disabled' => $disableEmailPrefs); } if ($wgEnotifUserTalk || $wgEnotifWatchlist) { $defaultPreferences['enotifminoredits'] = array('type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifminoredits', 'disabled' => $disableEmailPrefs); if ($wgEnotifRevealEditorAddress) { $defaultPreferences['enotifrevealaddr'] = array('type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifrevealaddr', 'disabled' => $disableEmailPrefs); } } } }
public function parseText($rawText) { global $wgEnableParserCache; $this->mRawtext = self::removeMetadataTag($rawText); $wgEnableParserCache = false; $parser = ParserPool::get(); $parser->ac_metadata = []; // VOLDEV-68: Remove broken section edit links $opts = ParserOptions::newFromContext(RequestContext::getMain()); $opts->setEditSection(false); $head = $parser->parse($rawText, $this->mTitle, $opts); $this->mText = wfFixMalformedHTML($head->getText()); $this->mHeadItems = $head->getHeadItems(); if (isset($parser->ac_metadata)) { $this->mMetadata = $parser->ac_metadata; } else { $this->mMetadata = []; } ParserPool::release($parser); return $this->mText; }
/** * Show the new revision of the page. */ function renderNewRevision() { wfProfileIn(__METHOD__); $out = $this->getOutput(); $revHeader = $this->getRevisionHeader($this->mNewRev); # Add "current version as of X" title $out->addHTML("<hr class='diff-hr' />\n\t\t<h2 class='diff-currentversion-title'>{$revHeader}</h2>\n"); # Page content may be handled by a hooked call instead... if (wfRunHooks('ArticleContentOnDiff', array($this, $out))) { $this->loadNewText(); $out->setRevisionId($this->mNewid); $out->setRevisionTimestamp($this->mNewRev->getTimestamp()); $out->setArticleFlag(true); if ($this->mNewPage->isCssJsSubpage() || $this->mNewPage->isCssOrJsPage()) { // Stolen from Article::view --AG 2007-10-11 // Give hooks a chance to customise the output // @TODO: standardize this crap into one function if (wfRunHooks('ShowRawCssJs', array($this->mNewtext, $this->mNewPage, $out))) { // Wrap the whole lot in a <pre> and don't parse $m = array(); preg_match('!\\.(css|js)$!u', $this->mNewPage->getText(), $m); $out->addHTML("<pre class=\"mw-code mw-{$m[1]}\" dir=\"ltr\">\n"); $out->addHTML(htmlspecialchars($this->mNewtext)); $out->addHTML("\n</pre>\n"); } } elseif (!wfRunHooks('ArticleViewCustom', array($this->mNewtext, $this->mNewPage, $out))) { // Handled by extension } else { // Normal page if ($this->getTitle()->equals($this->mNewPage)) { // If the Title stored in the context is the same as the one // of the new revision, we can use its associated WikiPage // object. $wikiPage = $this->getWikiPage(); } else { // Otherwise we need to create our own WikiPage object $wikiPage = WikiPage::factory($this->mNewPage); } $parserOptions = ParserOptions::newFromContext($this->getContext()); $parserOptions->enableLimitReport(); $parserOptions->setTidy(true); if (!$this->mNewRev->isCurrent()) { $parserOptions->setEditSection(false); } $parserOutput = $wikiPage->getParserOutput($parserOptions, $this->mNewid); # WikiPage::getParserOutput() should not return false, but just in case if ($parserOutput) { $out->addParserOutput($parserOutput); } } } # Add redundant patrol link on bottom... $out->addHTML($this->markPatrolledLink()); wfProfileOut(__METHOD__); }
/** * @param $article * @param $htmlParser * @return JsonFormatSectionNode */ protected function parseArticleToSection($article, $htmlParser, $tabTitle) { $html = $article->getPage()->getParserOutput(\ParserOptions::newFromContext(new RequestContext()))->getText(); $jsonArticle = $htmlParser->parse($html); $tabSection = new JsonFormatSectionNode(1, $tabTitle); foreach ($jsonArticle->getChildren() as $child) { $tabSection->addChild($child); } return $tabSection; }
public function execute() { // Cache may vary on $wgUser because ParserOptions gets data from it $this->getMain()->setCacheMode('anon-public-user-private'); // Get parameters $params = $this->extractRequestParams(); $this->requireMaxOneParameter($params, 'prop', 'generatexml'); if ($params['prop'] === null) { $this->logFeatureUsage('action=expandtemplates&!prop'); $this->setWarning('Because no values have been specified for the prop parameter, a ' . 'legacy format has been used for the output. This format is deprecated, and in ' . 'the future, a default value will be set for the prop parameter, causing the new' . 'format to always be used.'); $prop = array(); } else { $prop = array_flip($params['prop']); } // Create title for parser $title_obj = Title::newFromText($params['title']); if (!$title_obj || $title_obj->isExternal()) { $this->dieUsageMsg(array('invalidtitle', $params['title'])); } $result = $this->getResult(); // Parse text global $wgParser; $options = ParserOptions::newFromContext($this->getContext()); if ($params['includecomments']) { $options->setRemoveComments(false); } $retval = array(); if (isset($prop['parsetree']) || $params['generatexml']) { if (!isset($prop['parsetree'])) { $this->logFeatureUsage('action=expandtemplates&generatexml'); } $wgParser->startExternalParse($title_obj, $options, OT_PREPROCESS); $dom = $wgParser->preprocessToDom($params['text']); if (is_callable(array($dom, 'saveXML'))) { $xml = $dom->saveXML(); } else { $xml = $dom->__toString(); } if (isset($prop['parsetree'])) { unset($prop['parsetree']); $retval['parsetree'] = $xml; } else { // the old way $xml_result = array(); ApiResult::setContent($xml_result, $xml); $result->addValue(null, 'parsetree', $xml_result); } } // if they didn't want any output except (probably) the parse tree, // then don't bother actually fully expanding it if ($prop || $params['prop'] === null) { $wgParser->startExternalParse($title_obj, $options, OT_PREPROCESS); $frame = $wgParser->getPreprocessor()->newFrame(); $wikitext = $wgParser->preprocess($params['text'], $title_obj, $options, null, $frame); if ($params['prop'] === null) { // the old way ApiResult::setContent($retval, $wikitext); } else { if (isset($prop['categories'])) { $categories = $wgParser->getOutput()->getCategories(); if (!empty($categories)) { $categories_result = array(); foreach ($categories as $category => $sortkey) { $entry = array(); $entry['sortkey'] = $sortkey; ApiResult::setContent($entry, $category); $categories_result[] = $entry; } $result->setIndexedTagName($categories_result, 'category'); $retval['categories'] = $categories_result; } } if (isset($prop['volatile']) && $frame->isVolatile()) { $retval['volatile'] = ''; } if (isset($prop['ttl']) && $frame->getTTL() !== null) { $retval['ttl'] = $frame->getTTL(); } if (isset($prop['wikitext'])) { $retval['wikitext'] = $wikitext; } } } $result->setSubelements($retval, array('wikitext', 'parsetree')); $result->addValue(null, $this->getModuleName(), $retval); }
/** * Get parser options suitable for rendering and caching the article * * @param IContextSource|User|string $context One of the following: * - IContextSource: Use the User and the Language of the provided * context * - User: Use the provided User object and $wgLang for the language, * so use an IContextSource object if possible. * - 'canonical': Canonical options (anonymous user with default * preferences and content language). * * @throws MWException * @return ParserOptions */ public function makeParserOptions($context) { global $wgContLang, $wgEnableParserLimitReporting; if ($context instanceof IContextSource) { $options = ParserOptions::newFromContext($context); } elseif ($context instanceof User) { // settings per user (even anons) $options = ParserOptions::newFromUser($context); } elseif ($context === 'canonical') { // canonical settings $options = ParserOptions::newFromUserAndLang(new User(), $wgContLang); } else { throw new MWException("Bad context for parser options: {$context}"); } $options->enableLimitReport($wgEnableParserLimitReporting); // show inclusion/loop reports $options->setTidy(true); // fix bad HTML return $options; }
/** * Extract information from the Revision * * @param Revision $revision * @param object $row Should have a field 'ts_tags' if $this->fld_tags is set * @return array */ protected function extractRevisionInfo(Revision $revision, $row) { $title = $revision->getTitle(); $user = $this->getUser(); $vals = array(); $anyHidden = false; if ($this->fld_ids) { $vals['revid'] = intval($revision->getId()); if (!is_null($revision->getParentId())) { $vals['parentid'] = intval($revision->getParentId()); } } if ($this->fld_flags) { $vals['minor'] = $revision->isMinor(); } if ($this->fld_user || $this->fld_userid) { if ($revision->isDeleted(Revision::DELETED_USER)) { $vals['userhidden'] = true; $anyHidden = true; } if ($revision->userCan(Revision::DELETED_USER, $user)) { if ($this->fld_user) { $vals['user'] = $revision->getUserText(Revision::RAW); } $userid = $revision->getUser(Revision::RAW); if (!$userid) { $vals['anon'] = true; } if ($this->fld_userid) { $vals['userid'] = $userid; } } } if ($this->fld_timestamp) { $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $revision->getTimestamp()); } if ($this->fld_size) { if (!is_null($revision->getSize())) { $vals['size'] = intval($revision->getSize()); } else { $vals['size'] = 0; } } if ($this->fld_sha1) { if ($revision->isDeleted(Revision::DELETED_TEXT)) { $vals['sha1hidden'] = true; $anyHidden = true; } if ($revision->userCan(Revision::DELETED_TEXT, $user)) { if ($revision->getSha1() != '') { $vals['sha1'] = wfBaseConvert($revision->getSha1(), 36, 16, 40); } else { $vals['sha1'] = ''; } } } if ($this->fld_contentmodel) { $vals['contentmodel'] = $revision->getContentModel(); } if ($this->fld_comment || $this->fld_parsedcomment) { if ($revision->isDeleted(Revision::DELETED_COMMENT)) { $vals['commenthidden'] = true; $anyHidden = true; } if ($revision->userCan(Revision::DELETED_COMMENT, $user)) { $comment = $revision->getComment(Revision::RAW); if ($this->fld_comment) { $vals['comment'] = $comment; } if ($this->fld_parsedcomment) { $vals['parsedcomment'] = Linker::formatComment($comment, $title); } } } if ($this->fld_tags) { if ($row->ts_tags) { $tags = explode(',', $row->ts_tags); ApiResult::setIndexedTagName($tags, 'tag'); $vals['tags'] = $tags; } else { $vals['tags'] = array(); } } $content = null; global $wgParser; if ($this->fetchContent) { $content = $revision->getContent(Revision::FOR_THIS_USER, $this->getUser()); // Expand templates after getting section content because // template-added sections don't count and Parser::preprocess() // will have less input if ($content && $this->section !== false) { $content = $content->getSection($this->section, false); if (!$content) { $this->dieUsage("There is no section {$this->section} in r" . $revision->getId(), 'nosuchsection'); } } if ($revision->isDeleted(Revision::DELETED_TEXT)) { $vals['texthidden'] = true; $anyHidden = true; } elseif (!$content) { $vals['textmissing'] = true; } } if ($this->fld_content && $content) { $text = null; if ($this->generateXML) { if ($content->getModel() === CONTENT_MODEL_WIKITEXT) { $t = $content->getNativeData(); # note: don't set $text $wgParser->startExternalParse($title, ParserOptions::newFromContext($this->getContext()), Parser::OT_PREPROCESS); $dom = $wgParser->preprocessToDom($t); if (is_callable(array($dom, 'saveXML'))) { $xml = $dom->saveXML(); } else { $xml = $dom->__toString(); } $vals['parsetree'] = $xml; } else { $vals['badcontentformatforparsetree'] = true; $this->setWarning("Conversion to XML is supported for wikitext only, " . $title->getPrefixedDBkey() . " uses content model " . $content->getModel()); } } if ($this->expandTemplates && !$this->parseContent) { #XXX: implement template expansion for all content types in ContentHandler? if ($content->getModel() === CONTENT_MODEL_WIKITEXT) { $text = $content->getNativeData(); $text = $wgParser->preprocess($text, $title, ParserOptions::newFromContext($this->getContext())); } else { $this->setWarning("Template expansion is supported for wikitext only, " . $title->getPrefixedDBkey() . " uses content model " . $content->getModel()); $vals['badcontentformat'] = true; $text = false; } } if ($this->parseContent) { $po = $content->getParserOutput($title, $revision->getId(), ParserOptions::newFromContext($this->getContext())); $text = $po->getText(); } if ($text === null) { $format = $this->contentFormat ? $this->contentFormat : $content->getDefaultFormat(); $model = $content->getModel(); if (!$content->isSupportedFormat($format)) { $name = $title->getPrefixedDBkey(); $this->setWarning("The requested format {$this->contentFormat} is not " . "supported for content model {$model} used by {$name}"); $vals['badcontentformat'] = true; $text = false; } else { $text = $content->serialize($format); // always include format and model. // Format is needed to deserialize, model is needed to interpret. $vals['contentformat'] = $format; $vals['contentmodel'] = $model; } } if ($text !== false) { ApiResult::setContentValue($vals, 'content', $text); } } if ($content && (!is_null($this->diffto) || !is_null($this->difftotext))) { static $n = 0; // Number of uncached diffs we've had if ($n < $this->getConfig()->get('APIMaxUncachedDiffs')) { $vals['diff'] = array(); $context = new DerivativeContext($this->getContext()); $context->setTitle($title); $handler = $revision->getContentHandler(); if (!is_null($this->difftotext)) { $model = $title->getContentModel(); if ($this->contentFormat && !ContentHandler::getForModelID($model)->isSupportedFormat($this->contentFormat)) { $name = $title->getPrefixedDBkey(); $this->setWarning("The requested format {$this->contentFormat} is not " . "supported for content model {$model} used by {$name}"); $vals['diff']['badcontentformat'] = true; $engine = null; } else { $difftocontent = ContentHandler::makeContent($this->difftotext, $title, $model, $this->contentFormat); $engine = $handler->createDifferenceEngine($context); $engine->setContent($content, $difftocontent); } } else { $engine = $handler->createDifferenceEngine($context, $revision->getID(), $this->diffto); $vals['diff']['from'] = $engine->getOldid(); $vals['diff']['to'] = $engine->getNewid(); } if ($engine) { $difftext = $engine->getDiffBody(); ApiResult::setContentValue($vals['diff'], 'body', $difftext); if (!$engine->wasCacheHit()) { $n++; } } } else { $vals['diff']['notcached'] = true; } } if ($anyHidden && $revision->isDeleted(Revision::DELETED_RESTRICTED)) { $vals['suppressed'] = true; } return $vals; }
/** * Get/set the ParserOptions object to use for wikitext parsing * * @param ParserOptions|null $options Either the ParserOption to use or null to only get the * current ParserOption object * @return ParserOptions */ public function parserOptions($options = null) { if (!$this->mParserOptions) { $this->mParserOptions = ParserOptions::newFromContext($this->getContext()); $this->mParserOptions->setEditSection(false); } return wfSetVar($this->mParserOptions, $options); }
private function extractRowInfo($row) { $revision = new Revision($row); $title = $revision->getTitle(); $vals = array(); if ($this->fld_ids) { $vals['revid'] = intval($revision->getId()); // $vals['oldid'] = intval( $row->rev_text_id ); // todo: should this be exposed? if (!is_null($revision->getParentId())) { $vals['parentid'] = intval($revision->getParentId()); } } if ($this->fld_flags && $revision->isMinor()) { $vals['minor'] = ''; } if ($this->fld_user || $this->fld_userid) { if ($revision->isDeleted(Revision::DELETED_USER)) { $vals['userhidden'] = ''; } else { if ($this->fld_user) { $vals['user'] = $revision->getUserText(); } $userid = $revision->getUser(); if (!$userid) { $vals['anon'] = ''; } if ($this->fld_userid) { $vals['userid'] = $userid; } } } if ($this->fld_timestamp) { $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $revision->getTimestamp()); } if ($this->fld_size) { if (!is_null($revision->getSize())) { $vals['size'] = intval($revision->getSize()); } else { $vals['size'] = 0; } } if ($this->fld_sha1) { if ($revision->getSha1() != '') { $vals['sha1'] = wfBaseConvert($revision->getSha1(), 36, 16, 40); } else { $vals['sha1'] = ''; } } if ($this->fld_contentmodel) { $vals['contentmodel'] = $revision->getContentModel(); } if ($this->fld_comment || $this->fld_parsedcomment) { if ($revision->isDeleted(Revision::DELETED_COMMENT)) { $vals['commenthidden'] = ''; } else { $comment = $revision->getComment(); if ($this->fld_comment) { $vals['comment'] = $comment; } if ($this->fld_parsedcomment) { $vals['parsedcomment'] = Linker::formatComment($comment, $title); } } } if ($this->fld_tags) { if ($row->ts_tags) { $tags = explode(',', $row->ts_tags); $this->getResult()->setIndexedTagName($tags, 'tag'); $vals['tags'] = $tags; } else { $vals['tags'] = array(); } } if (!is_null($this->token)) { $tokenFunctions = $this->getTokenFunctions(); foreach ($this->token as $t) { $val = call_user_func($tokenFunctions[$t], $title->getArticleID(), $title, $revision); if ($val === false) { $this->setWarning("Action '{$t}' is not allowed for the current user"); } else { $vals[$t . 'token'] = $val; } } } $content = null; global $wgParser; if ($this->fld_content || !is_null($this->difftotext)) { $content = $revision->getContent(); // Expand templates after getting section content because // template-added sections don't count and Parser::preprocess() // will have less input if ($this->section !== false) { $content = $content->getSection($this->section, false); if (!$content) { $this->dieUsage("There is no section {$this->section} in r" . $revision->getId(), 'nosuchsection'); } } } if ($this->fld_content && !$revision->isDeleted(Revision::DELETED_TEXT)) { $text = null; if ($this->generateXML) { if ($content->getModel() === CONTENT_MODEL_WIKITEXT) { $t = $content->getNativeData(); # note: don't set $text $wgParser->startExternalParse($title, ParserOptions::newFromContext($this->getContext()), OT_PREPROCESS); $dom = $wgParser->preprocessToDom($t); if (is_callable(array($dom, 'saveXML'))) { $xml = $dom->saveXML(); } else { $xml = $dom->__toString(); } $vals['parsetree'] = $xml; } else { $this->setWarning("Conversion to XML is supported for wikitext only, " . $title->getPrefixedDBkey() . " uses content model " . $content->getModel() . ")"); } } if ($this->expandTemplates && !$this->parseContent) { #XXX: implement template expansion for all content types in ContentHandler? if ($content->getModel() === CONTENT_MODEL_WIKITEXT) { $text = $content->getNativeData(); $text = $wgParser->preprocess($text, $title, ParserOptions::newFromContext($this->getContext())); } else { $this->setWarning("Template expansion is supported for wikitext only, " . $title->getPrefixedDBkey() . " uses content model " . $content->getModel() . ")"); $text = false; } } if ($this->parseContent) { $po = $content->getParserOutput($title, $revision->getId(), ParserOptions::newFromContext($this->getContext())); $text = $po->getText(); } if ($text === null) { $format = $this->contentFormat ? $this->contentFormat : $content->getDefaultFormat(); if (!$content->isSupportedFormat($format)) { $model = $content->getModel(); $name = $title->getPrefixedDBkey(); $this->dieUsage("The requested format {$this->contentFormat} is not supported " . "for content model {$model} used by {$name}", 'badformat'); } $text = $content->serialize($format); $vals['contentformat'] = $format; } if ($text !== false) { ApiResult::setContent($vals, $text); } } elseif ($this->fld_content) { $vals['texthidden'] = ''; } if (!is_null($this->diffto) || !is_null($this->difftotext)) { global $wgAPIMaxUncachedDiffs; static $n = 0; // Number of uncached diffs we've had if ($n < $wgAPIMaxUncachedDiffs) { $vals['diff'] = array(); $context = new DerivativeContext($this->getContext()); $context->setTitle($title); $handler = $revision->getContentHandler(); if (!is_null($this->difftotext)) { $model = $title->getContentModel(); if ($this->contentFormat && !ContentHandler::getForModelID($model)->isSupportedFormat($this->contentFormat)) { $name = $title->getPrefixedDBkey(); $this->dieUsage("The requested format {$this->contentFormat} is not supported for " . "content model {$model} used by {$name}", 'badformat'); } $difftocontent = ContentHandler::makeContent($this->difftotext, $title, $model, $this->contentFormat); $engine = $handler->createDifferenceEngine($context); $engine->setContent($content, $difftocontent); } else { $engine = $handler->createDifferenceEngine($context, $revision->getID(), $this->diffto); $vals['diff']['from'] = $engine->getOldid(); $vals['diff']['to'] = $engine->getNewid(); } $difftext = $engine->getDiffBody(); ApiResult::setContent($vals['diff'], $difftext); if (!$engine->wasCacheHit()) { $n++; } } else { $vals['diff']['notcached'] = ''; } } return $vals; }
/** * Renders the supplied wikitext as html * * @param Title $title * @param string $text * @return string */ private function generateHtml(Title $title, $text) { global $wgParser; $popts = ParserOptions::newFromContext($this->getContext()); $popts->setTargetLanguage($title->getPageLanguage()); $pout = $wgParser->parse($text, $title, $popts); return $pout->getText(); }
/** @dataProvider parserTestProvider */ public function testParserTest($desc, $input, $result, $opts, $config) { if ($this->regex != '' && !preg_match('/' . $this->regex . '/', $desc)) { $this->assertTrue(true); // XXX: don't flood output with "test made no assertions" //$this->markTestSkipped( 'Filtered out by the user' ); return; } wfDebug("Running parser test: {$desc}\n"); $opts = $this->parseOptions($opts); $context = $this->setupGlobals($opts, $config); $user = $context->getUser(); $options = ParserOptions::newFromContext($context); if (isset($opts['title'])) { $titleText = $opts['title']; } else { $titleText = 'Parser test'; } $local = isset($opts['local']); $preprocessor = isset($opts['preprocessor']) ? $opts['preprocessor'] : null; $parser = $this->getParser($preprocessor); $title = Title::newFromText($titleText); if (isset($opts['pst'])) { $out = $parser->preSaveTransform($input, $title, $user, $options); } elseif (isset($opts['msg'])) { $out = $parser->transformMsg($input, $options, $title); } elseif (isset($opts['section'])) { $section = $opts['section']; $out = $parser->getSection($input, $section); } elseif (isset($opts['replace'])) { $section = $opts['replace'][0]; $replace = $opts['replace'][1]; $out = $parser->replaceSection($input, $section, $replace); } elseif (isset($opts['comment'])) { $out = Linker::formatComment($input, $title, $local); } elseif (isset($opts['preload'])) { $out = $parser->getpreloadText($input, $title, $options); } else { $output = $parser->parse($input, $title, $options, true, true, 1337); $out = $output->getText(); if (isset($opts['showtitle'])) { if ($output->getTitleText()) { $title = $output->getTitleText(); } $out = "{$title}\n{$out}"; } if (isset($opts['ill'])) { $out = $this->tidy(implode(' ', $output->getLanguageLinks())); } elseif (isset($opts['cat'])) { $outputPage = $context->getOutput(); $outputPage->addCategoryLinks($output->getCategories()); $cats = $outputPage->getCategoryLinks(); if (isset($cats['normal'])) { $out = $this->tidy(implode(' ', $cats['normal'])); } else { $out = ''; } } $parser->mPreprocessor = null; $result = $this->tidy($result); } $this->teardownGlobals(); $this->assertEquals($result, $out, $desc); }
/** * @param $user User * @param $context IContextSource * @param $defaultPreferences * @return void */ static function profilePreferences( $user, IContextSource $context, &$defaultPreferences ) { global $wgAuth, $wgContLang, $wgParser, $wgCookieExpiration, $wgLanguageCode, $wgDisableTitleConversion, $wgDisableLangConversion, $wgMaxSigChars, $wgEnableEmail, $wgEmailConfirmToEdit, $wgEnableUserEmail, $wgEmailAuthentication, $wgEnotifWatchlist, $wgEnotifUserTalk, $wgEnotifRevealEditorAddress, $wgSecureLogin; // retrieving user name for GENDER and misc. $userName = $user->getName(); ## User info ##################################### // Information panel $defaultPreferences['username'] = array( 'type' => 'info', 'label-message' => array( 'username', $userName ), 'default' => $userName, 'section' => 'personal/info', ); $defaultPreferences['userid'] = array( 'type' => 'info', 'label-message' => array( 'uid', $userName ), 'default' => $user->getId(), 'section' => 'personal/info', ); # Get groups to which the user belongs $userEffectiveGroups = $user->getEffectiveGroups(); $userGroups = $userMembers = array(); foreach ( $userEffectiveGroups as $ueg ) { if ( $ueg == '*' ) { // Skip the default * group, seems useless here continue; } $groupName = User::getGroupName( $ueg ); $userGroups[] = User::makeGroupLinkHTML( $ueg, $groupName ); $memberName = User::getGroupMember( $ueg, $userName ); $userMembers[] = User::makeGroupLinkHTML( $ueg, $memberName ); } asort( $userGroups ); asort( $userMembers ); $lang = $context->getLanguage(); $defaultPreferences['usergroups'] = array( 'type' => 'info', 'label' => $context->msg( 'prefs-memberingroups' )->numParams( count( $userGroups ) )->params( $userName )->parse(), 'default' => $context->msg( 'prefs-memberingroups-type', $lang->commaList( $userGroups ), $lang->commaList( $userMembers ) )->plain(), 'raw' => true, 'section' => 'personal/info', ); $editCount = Linker::link( SpecialPage::getTitleFor( "Contributions", $userName ), $lang->formatNum( $user->getEditCount() ) ); $defaultPreferences['editcount'] = array( 'type' => 'info', 'raw' => true, 'label-message' => 'prefs-edits', 'default' => $editCount, 'section' => 'personal/info', ); if ( $user->getRegistration() ) { $displayUser = $context->getUser(); $userRegistration = $user->getRegistration(); $defaultPreferences['registrationdate'] = array( 'type' => 'info', 'label-message' => 'prefs-registration', 'default' => $context->msg( 'prefs-registration-date-time', $lang->userTimeAndDate( $userRegistration, $displayUser ), $lang->userDate( $userRegistration, $displayUser ), $lang->userTime( $userRegistration, $displayUser ) )->parse(), 'section' => 'personal/info', ); } $canViewPrivateInfo = $user->isAllowed( 'viewmyprivateinfo' ); $canEditPrivateInfo = $user->isAllowed( 'editmyprivateinfo' ); // Actually changeable stuff $defaultPreferences['realname'] = array( // (not really "private", but still shouldn't be edited without permission) 'type' => $canEditPrivateInfo && $wgAuth->allowPropChange( 'realname' ) ? 'text' : 'info', 'default' => $user->getRealName(), 'section' => 'personal/info', 'label-message' => 'yourrealname', 'help-message' => 'prefs-help-realname', ); if ( $canEditPrivateInfo && $wgAuth->allowPasswordChange() ) { $link = Linker::link( SpecialPage::getTitleFor( 'ChangePassword' ), $context->msg( 'prefs-resetpass' )->escaped(), array(), array( 'returnto' => SpecialPage::getTitleFor( 'Preferences' )->getPrefixedText() ) ); $defaultPreferences['password'] = array( 'type' => 'info', 'raw' => true, 'default' => $link, 'label-message' => 'yourpassword', 'section' => 'personal/info', ); } if ( $wgCookieExpiration > 0 ) { $defaultPreferences['rememberpassword'] = array( 'type' => 'toggle', 'label' => $context->msg( 'tog-rememberpassword' )->numParams( ceil( $wgCookieExpiration / ( 3600 * 24 ) ) )->text(), 'section' => 'personal/info', ); } // Only show preferhttps if secure login is turned on if ( $wgSecureLogin && wfCanIPUseHTTPS( $context->getRequest()->getIP() ) ) { $defaultPreferences['prefershttps'] = array( 'type' => 'toggle', 'label-message' => 'tog-prefershttps', 'help-message' => 'prefs-help-prefershttps', 'section' => 'personal/info' ); } // Language $languages = Language::fetchLanguageNames( null, 'mw' ); if ( !array_key_exists( $wgLanguageCode, $languages ) ) { $languages[$wgLanguageCode] = $wgLanguageCode; } ksort( $languages ); $options = array(); foreach ( $languages as $code => $name ) { $display = wfBCP47( $code ) . ' - ' . $name; $options[$display] = $code; } $defaultPreferences['language'] = array( 'type' => 'select', 'section' => 'personal/i18n', 'options' => $options, 'label-message' => 'yourlanguage', ); $defaultPreferences['gender'] = array( 'type' => 'radio', 'section' => 'personal/i18n', 'options' => array( $context->msg( 'parentheses', $context->msg( 'gender-unknown' )->text() )->text() => 'unknown', $context->msg( 'gender-female' )->text() => 'female', $context->msg( 'gender-male' )->text() => 'male', ), 'label-message' => 'yourgender', 'help-message' => 'prefs-help-gender', ); // see if there are multiple language variants to choose from if ( !$wgDisableLangConversion ) { foreach ( LanguageConverter::$languagesWithVariants as $langCode ) { if ( $langCode == $wgContLang->getCode() ) { $variants = $wgContLang->getVariants(); if ( count( $variants ) <= 1 ) { continue; } $variantArray = array(); foreach ( $variants as $v ) { $v = str_replace( '_', '-', strtolower( $v ) ); $variantArray[$v] = $lang->getVariantname( $v, false ); } $options = array(); foreach ( $variantArray as $code => $name ) { $display = wfBCP47( $code ) . ' - ' . $name; $options[$display] = $code; } $defaultPreferences['variant'] = array( 'label-message' => 'yourvariant', 'type' => 'select', 'options' => $options, 'section' => 'personal/i18n', 'help-message' => 'prefs-help-variant', ); if ( !$wgDisableTitleConversion ) { $defaultPreferences['noconvertlink'] = array( 'type' => 'toggle', 'section' => 'personal/i18n', 'label-message' => 'tog-noconvertlink', ); } } else { $defaultPreferences["variant-$langCode"] = array( 'type' => 'api', ); } } } // Stuff from Language::getExtraUserToggles() // FIXME is this dead code? $extraUserToggles doesn't seem to be defined for any language $toggles = $wgContLang->getExtraUserToggles(); foreach ( $toggles as $toggle ) { $defaultPreferences[$toggle] = array( 'type' => 'toggle', 'section' => 'personal/i18n', 'label-message' => "tog-$toggle", ); } // show a preview of the old signature first $oldsigWikiText = $wgParser->preSaveTransform( "~~~", $context->getTitle(), $user, ParserOptions::newFromContext( $context ) ); $oldsigHTML = $context->getOutput()->parseInline( $oldsigWikiText, true, true ); $defaultPreferences['oldsig'] = array( 'type' => 'info', 'raw' => true, 'label-message' => 'tog-oldsig', 'default' => $oldsigHTML, 'section' => 'personal/signature', ); $defaultPreferences['nickname'] = array( 'type' => $wgAuth->allowPropChange( 'nickname' ) ? 'text' : 'info', 'maxlength' => $wgMaxSigChars, 'label-message' => 'yournick', 'validation-callback' => array( 'Preferences', 'validateSignature' ), 'section' => 'personal/signature', 'filter-callback' => array( 'Preferences', 'cleanSignature' ), ); $defaultPreferences['fancysig'] = array( 'type' => 'toggle', 'label-message' => 'tog-fancysig', 'help-message' => 'prefs-help-signature', // show general help about signature at the bottom of the section 'section' => 'personal/signature' ); ## Email stuff if ( $wgEnableEmail ) { if ( $canViewPrivateInfo ) { $helpMessages[] = $wgEmailConfirmToEdit ? 'prefs-help-email-required' : 'prefs-help-email'; if ( $wgEnableUserEmail ) { // additional messages when users can send email to each other $helpMessages[] = 'prefs-help-email-others'; } $emailAddress = $user->getEmail() ? htmlspecialchars( $user->getEmail() ) : ''; if ( $canEditPrivateInfo && $wgAuth->allowPropChange( 'emailaddress' ) ) { $link = Linker::link( SpecialPage::getTitleFor( 'ChangeEmail' ), $context->msg( $user->getEmail() ? 'prefs-changeemail' : 'prefs-setemail' )->escaped(), array(), array( 'returnto' => SpecialPage::getTitleFor( 'Preferences' )->getPrefixedText() ) ); $emailAddress .= $emailAddress == '' ? $link : ( $context->msg( 'word-separator' )->plain() . $context->msg( 'parentheses' )->rawParams( $link )->plain() ); } $defaultPreferences['emailaddress'] = array( 'type' => 'info', 'raw' => true, 'default' => $emailAddress, 'label-message' => 'youremail', 'section' => 'personal/email', 'help-messages' => $helpMessages, # 'cssclass' chosen below ); } $disableEmailPrefs = false; if ( $wgEmailAuthentication ) { $emailauthenticationclass = 'mw-email-not-authenticated'; if ( $user->getEmail() ) { if ( $user->getEmailAuthenticationTimestamp() ) { // date and time are separate parameters to facilitate localisation. // $time is kept for backward compat reasons. // 'emailauthenticated' is also used in SpecialConfirmemail.php $displayUser = $context->getUser(); $emailTimestamp = $user->getEmailAuthenticationTimestamp(); $time = $lang->userTimeAndDate( $emailTimestamp, $displayUser ); $d = $lang->userDate( $emailTimestamp, $displayUser ); $t = $lang->userTime( $emailTimestamp, $displayUser ); $emailauthenticated = $context->msg( 'emailauthenticated', $time, $d, $t )->parse() . '<br />'; $disableEmailPrefs = false; $emailauthenticationclass = 'mw-email-authenticated'; } else { $disableEmailPrefs = true; $emailauthenticated = $context->msg( 'emailnotauthenticated' )->parse() . '<br />' . Linker::linkKnown( SpecialPage::getTitleFor( 'Confirmemail' ), $context->msg( 'emailconfirmlink' )->escaped() ) . '<br />'; $emailauthenticationclass = "mw-email-not-authenticated"; } } else { $disableEmailPrefs = true; $emailauthenticated = $context->msg( 'noemailprefs' )->escaped(); $emailauthenticationclass = 'mw-email-none'; } if ( $canViewPrivateInfo ) { $defaultPreferences['emailauthentication'] = array( 'type' => 'info', 'raw' => true, 'section' => 'personal/email', 'label-message' => 'prefs-emailconfirm-label', 'default' => $emailauthenticated, # Apply the same CSS class used on the input to the message: 'cssclass' => $emailauthenticationclass, ); $defaultPreferences['emailaddress']['cssclass'] = $emailauthenticationclass; } } if ( $wgEnableUserEmail && $user->isAllowed( 'sendemail' ) ) { $defaultPreferences['disablemail'] = array( 'type' => 'toggle', 'invert' => true, 'section' => 'personal/email', 'label-message' => 'allowemail', 'disabled' => $disableEmailPrefs, ); $defaultPreferences['ccmeonemails'] = array( 'type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-ccmeonemails', 'disabled' => $disableEmailPrefs, ); } if ( $wgEnotifWatchlist ) { $defaultPreferences['enotifwatchlistpages'] = array( 'type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifwatchlistpages', 'disabled' => $disableEmailPrefs, ); } if ( $wgEnotifUserTalk ) { $defaultPreferences['enotifusertalkpages'] = array( 'type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifusertalkpages', 'disabled' => $disableEmailPrefs, ); } if ( $wgEnotifUserTalk || $wgEnotifWatchlist ) { $defaultPreferences['enotifminoredits'] = array( 'type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifminoredits', 'disabled' => $disableEmailPrefs, ); if ( $wgEnotifRevealEditorAddress ) { $defaultPreferences['enotifrevealaddr'] = array( 'type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifrevealaddr', 'disabled' => $disableEmailPrefs, ); } } } }
/** * Get the text that should be returned, or false if the page or revision * was not found. * * @return String|Bool */ public function getRawText() { global $wgParser; # No longer used if ($this->mGen) { return ''; } $text = false; $title = $this->getTitle(); $request = $this->getRequest(); // If it's a MediaWiki message we can just hit the message cache if ($request->getBool('usemsgcache') && $title->getNamespace() == NS_MEDIAWIKI) { // The first "true" is to use the database, the second is to use the content langue // and the last one is to specify the message key already contains the language in it ("/de", etc.) $text = MessageCache::singleton()->get($title->getDBkey(), true, true, true); // If the message doesn't exist, return a blank if ($text === false) { $text = ''; } } else { // Get it from the DB $rev = Revision::newFromTitle($title, $this->getOldId()); if ($rev) { $lastmod = wfTimestamp(TS_RFC2822, $rev->getTimestamp()); $request->response()->header("Last-modified: {$lastmod}"); // Public-only due to cache headers $text = $rev->getText(); $section = $request->getIntOrNull('section'); if ($section !== null) { $text = $wgParser->getSection($text, $section); } } } if ($text !== false && $text !== '' && $request->getVal('templates') === 'expand') { $text = $wgParser->preprocess($text, $title, ParserOptions::newFromContext($this->getContext())); } return $text; }