function setUp() { parent::setUp(); $parser = new Parser(); $options = new ParserOptions(); $options->setTemplateCallback(array($this, 'templateCallback')); $parser->startExternalParse(Title::newMainPage(), $options, Parser::OT_HTML, true); try { $engine = new Scribunto_LuaSandboxEngine(array('parser' => $parser) + $this->sandboxOpts); $engine->setTitle($parser->getTitle()); $engine->getInterpreter(); $this->engines['LuaSandbox'] = $engine; } catch (Scribunto_LuaInterpreterNotFoundError $e) { $this->markTestSkipped("LuaSandbox interpreter not available"); return; } try { $engine = new Scribunto_LuaStandaloneEngine(array('parser' => $parser) + $this->standaloneOpts); $engine->setTitle($parser->getTitle()); $engine->getInterpreter(); $this->engines['LuaStandalone'] = $engine; } catch (Scribunto_LuaInterpreterNotFoundError $e) { $this->markTestSkipped("LuaStandalone interpreter not available"); return; } }
/** * Parser hook handler for {{#articletype}} * * @param Parser $parser : Parser instance available to render * wikitext into html, or parser methods. * * @return string: HTML to insert in the page. */ public static function renderGallery($input, array $args, Parser $parser, PPFrame $frame) { $parser->getOutput()->addModules('ext.promoter.gallery'); $pageName = $parser->getTitle()->getText(); try { $renderedAds = array(); $adChooser = new AdChooser($pageName, !$parser->getUser()->isLoggedIn()); $ads = $adChooser->getAds(); foreach ($ads as $ad) { $renderedAds[] = Ad::fromName($ad['name'])->renderHtml(); } } catch (AdCampaignExistenceException $e) { wfDebugLog('Promoter', $e->getMessage()); //@todo i18n return '<span class="error">No campaign for this page</span>'; } catch (MWException $e) { wfDebugLog('Promoter', $e->getMessage()); return '<span class="error text-danger">An error occurred [' . $e->getMessage() . ']</span>'; } $html = '<div class="promotion-gallery hidden hidden-print">' . '<h5 class="sr-only">זוהי גלריה המקדמת ערכים שונים באתר.</h5>' . '<div class="gallery-controls">' . '<span class="sr-only">בכל רגע מוצגות 3 ידיעות בגלריה. ניתן להציג ידיעה נוספת או לחזור לאחור באמצעות הכפתורים הבאים, או באמצעות מקשי החיצים כאשר הפוקוס הוא על הגלריה</span>' . '<a href="#" class="owl-prev"><span class="fa fa-chevron-right fa-lg" title="הקודם"></span><span class="sr-only">הצגת הידיעה הקודמת</span></a>' . '<a href="#" class="owl-next"><span class="fa fa-chevron-left fa-lg" title="הבא"></span><span class="sr-only">הצגת הידיעה הבאה</span></a>' . '</div>'; if ($args['title']) { $html .= '<div class="header">' . $args['title'] . '</div>'; } $html .= '<div class="owl-carousel clearfix" tabindex="0">' . implode('', $renderedAds) . '</div>' . '</div>'; return $html; }
/** * Get an engine instance for the given parser, and cache it in the parser * so that subsequent calls to this function for the same parser will return * the same engine. * * @param Parser $parser * @return ScribuntoEngineBase */ public static function getParserEngine(Parser $parser) { if (empty($parser->scribunto_engine)) { $parser->scribunto_engine = self::newDefaultEngine(array('parser' => $parser)); $parser->scribunto_engine->setTitle($parser->getTitle()); } return $parser->scribunto_engine; }
/** * Clear all stored data for a given parser. * * @param Parser $parser */ public static function clearStorage(Parser $parser) { $output = $parser->getOutput(); $title = $parser->getTitle(); if (!isset($output) || !isset($title)) { return; } $output->mSMWData = new SMWSemanticData(new SMWDIWikiPage($title->getDBkey(), $title->getNamespace(), $title->getInterwiki())); }
/** * Hooks into ParserAfterTidy. * * @param Parser $parser * @param String $text * @return Boolean */ static function parse(&$parser, &$text) { global $wgexLingoUseNamespaces; $title = $parser->getTitle(); // parse if if (!isset($parser->mDoubleUnderscores['noglossary']) && (!$title || !isset($wgexLingoUseNamespaces[$title->getNamespace()]) || $wgexLingoUseNamespaces[$title->getNamespace()])) { LingoParser::parse($parser, $text); } return true; }
/** * @param Parser $parser * @return string */ public static function sprintbtn($parser) { $html = ''; $title = $parser->getTitle(); $link = $title->getFullURL('printable=yes'); $link = '#'; $parser->getOutput()->addModules('ext.stools.foo'); $html .= $parser->insertStripItem('<a id="print-button" href="' . $link . '" type="button" class="btn btn-primary"><i class="fa fa-print"></i> ' . wfMessage('stools-button-print')->plain() . '</a>'); return $html; }
private function makeEngine($class, $opts) { $parser = new Parser(); $options = new ParserOptions(); $options->setTemplateCallback(array($this, 'templateCallback')); $parser->startExternalParse(Title::newMainPage(), $options, Parser::OT_HTML, true); $engine = new $class(array('parser' => $parser) + $opts); $parser->scribunto_engine = $engine; $engine->setTitle($parser->getTitle()); $engine->getInterpreter(); return $engine; }
/** * Method for handling the ask concept function. * * @todo The possible use of this in an HTML or Specal page context needs to be revisited. The code mentions it, but can this actually happen? * @todo The escaping of symbols in concept queries needs to be revisited. * * @since 1.5.3 * * @param Parser $parser */ public static function render(Parser &$parser) { global $wgContLang, $wgTitle; $title = $parser->getTitle(); $pconc = new SMWDIProperty('_CONC'); if ($title->getNamespace() != SMW_NS_CONCEPT) { $result = smwfEncodeMessages(array(wfMsgForContent('smw_no_concept_namespace'))); SMWOutputs::commitToParser($parser); return $result; } elseif (count(SMWParseData::getSMWdata($parser)->getPropertyValues($pconc)) > 0) { $result = smwfEncodeMessages(array(wfMsgForContent('smw_multiple_concepts'))); SMWOutputs::commitToParser($parser); return $result; } // process input: $params = func_get_args(); array_shift($params); // We already know the $parser ... // Use first parameter as concept (query) string. $concept_input = str_replace(array('>', '<'), array('>', '<'), array_shift($params)); // second parameter, if any, might be a description $concept_docu = array_shift($params); // NOTE: the str_replace above is required in MediaWiki 1.11, but not in MediaWiki 1.14 $query = SMWQueryProcessor::createQuery($concept_input, SMWQueryProcessor::getProcessedParams(array('limit' => 20, 'format' => 'list')), SMWQueryProcessor::CONCEPT_DESC); $concept_text = $query->getDescription()->getQueryString(); if (!is_null(SMWParseData::getSMWData($parser))) { $diConcept = new SMWDIConcept($concept_text, $concept_docu, $query->getDescription()->getQueryFeatures(), $query->getDescription()->getSize(), $query->getDescription()->getDepth()); SMWParseData::getSMWData($parser)->addPropertyObjectValue($pconc, $diConcept); } // display concept box: $rdflink = SMWInfolink::newInternalLink(wfMsgForContent('smw_viewasrdf'), $wgContLang->getNsText(NS_SPECIAL) . ':ExportRDF/' . $title->getPrefixedText(), 'rdflink'); SMWOutputs::requireResource('ext.smw.style'); // TODO: escape output, preferably via Html or Xml class. $result = '<div class="smwfact"><span class="smwfactboxhead">' . wfMsgForContent('smw_concept_description', $title->getText()) . (count($query->getErrors()) > 0 ? ' ' . smwfEncodeMessages($query->getErrors()) : '') . '</span>' . '<span class="smwrdflink">' . $rdflink->getWikiText() . '</span>' . '<br />' . ($concept_docu ? "<p>{$concept_docu}</p>" : '') . '<pre>' . str_replace('[', '[', $concept_text) . "</pre>\n</div>"; if (!is_null($wgTitle) && $wgTitle->isSpecialPage()) { global $wgOut; SMWOutputs::commitToOutputPage($wgOut); } else { SMWOutputs::commitToParser($parser); } return $result; }
/** * Renders the #serieslink parser function. * * @param Parser $parser * @return string the unique tag which must be inserted into the stripped text */ public static function renderSeriesLink(&$parser) { global $wgTitle; $params = func_get_args(); array_shift($params); // We don't need the parser. // remove the target parameter should it be present foreach ($params as $key => $value) { $elements = explode('=', $value, 2); if ($elements[0] === 'target') { unset($params[$key]); } } // set the origin parameter // This will block it from use as iterator parameter. Oh well. $params[] = "origin=" . $parser->getTitle()->getArticleId(); // hack to remove newline from beginning of output, thanks to // http://jimbojw.com/wiki/index.php?title=Raw_HTML_Output_from_a_MediaWiki_Parser_Function return $parser->insertStripItem(SFUtils::createFormLink($parser, 'SeriesEdit', $params), $parser->mStripState); }
/** * @param Parser $parser * @return string */ public static function render($parser) { $user = $parser->getUser(); $title = $parser->getTitle(); if (!$title || !$title->exists()) { return ''; } $author = self::getPageAuthor($title); if (!$author) { return ''; } $html = '<span class="author-rating-wrapper">'; // Add user link $html .= $parser->insertStripItem(' <a target="_blank" href="' . $author->getUserPage()->getFullURL() . '">' . $author->getName() . '</a>'); $html .= ' <i style="display: none;" class="fa fa-thumbs-o-up author-thumbs-up" title="' . wfMessage('authorrating-rate-title')->plain() . '"></i>'; $html .= ' <span class="label label-success">?</span>'; $html .= '</span>'; $parser->getOutput()->addModules('ext.authorrating.foo'); return array($html, 'markerType' => 'nowiki'); }
function wfSampleGetProp($input, array $args, Parser $parser, PPFrame $frame) { $pageId = $parser->getTitle()->getArticleId(); if (isset($args['page'])) { $title = Title::newFromText($args['page']); if (!$title || $title->getArticleId() === 0) { // In a real extension, this would be i18n-ized. return '<span class="error">Invalid page ' . htmlspecialchars($args['page']) . ' specified.</span>'; } // Do for some page other then current one. $dbr = wfGetDB(DB_SLAVE); $propValue = $dbr->selectField('page_props', 'pp_value', array('pp_page' => $title->getArticleId(), 'pp_propname' => "SimpleSetPropExtension"), __METHOD__); if ($propValue === false) { // No prop stored for this page // In a real extension, this would be i18n-ized. return '<span class="error">No prop set for page ' . htmlspecialchars($args['page']) . ' specified.</span>'; } // We found the prop. Unserialize (First level of serialization) $prop = unserialize($propValue); if (!$parser->isValidHalfParsedText($prop)) { // Probably won't ever happen. return '<span class="error">Error retrieving prop</span>'; } else { // Everything should be good. return $parser->unserializeHalfParsedText($prop); } } else { // Second case, current page. // Can't query db, because could be set earlier in the page and not saved yet. // So have to use the parserOutput object. $prop = unserialize($parser->getOutput()->getProperty('SimpleSetPropExtension')); if (!$parser->isValidHalfParsedText($prop)) { // Probably won't ever happen. return '<span class="error">Error retrieving prop</span>'; } else { // Everything should be good. return $parser->unserializeHalfParsedText($prop); } } }
function renderHeadCount(Parser &$parser, $page = '', $level = '') { if (empty($page)) { $title = $parser->getTitle(); } else { $title = Title::newFromText($page); if (!$title->exists()) { return "'''{$title} does not exist.'''"; } } $rev = Revision::newFromTitle($title); if ($rev === null) { return "'''Could not retrieve revision from {$title}.'''"; } $content = $rev->getContent(Revision::RAW); if ($content === null) { return "'''Could not extract text from {$title}.'''"; } $level = empty($level) ? 2 : intval($level); $header = str_repeat('=', $level); $serialized = $content->serialize(); $count = preg_match_all("/^{$header}" . "[^=]+" . "{$header}\$/m", $serialized); return $count == false ? 0 : $count; }
function getEngine() { if (!$this->engine) { $parser = new Parser(); $options = new ParserOptions(); $options->setTemplateCallback(array($this, 'templateCallback')); $parser->startExternalParse(Title::newMainPage(), $options, Parser::OT_HTML, true); $class = "Scribunto_{$this->engineName}Engine"; $this->engine = new $class(self::$engineConfigurations[$this->engineName] + array('parser' => $parser)); $this->engine->setTitle($parser->getTitle()); } return $this->engine; }
/** * Modify $this->internals and $colours according to language variant linking rules * @param array $colours */ protected function doVariants(&$colours) { global $wgContLang, $wgContentHandlerUseDB; $linkBatch = new LinkBatch(); $variantMap = array(); // maps $pdbkey_Variant => $keys (of link holders) $output = $this->parent->getOutput(); $linkCache = LinkCache::singleton(); $threshold = $this->parent->getOptions()->getStubThreshold(); $titlesToBeConverted = ''; $titlesAttrs = array(); // Concatenate titles to a single string, thus we only need auto convert the // single string to all variants. This would improve parser's performance // significantly. foreach ($this->internals as $ns => $entries) { if ($ns == NS_SPECIAL) { continue; } foreach ($entries as $index => $entry) { $pdbk = $entry['pdbk']; // we only deal with new links (in its first query) if (!isset($colours[$pdbk]) || $colours[$pdbk] === 'new') { $titlesAttrs[] = array($index, $entry['title']); // separate titles with \0 because it would never appears // in a valid title $titlesToBeConverted .= $entry['title']->getText() . ""; } } } // Now do the conversion and explode string to text of titles $titlesAllVariants = $wgContLang->autoConvertToAllVariants(rtrim($titlesToBeConverted, "")); $allVariantsName = array_keys($titlesAllVariants); foreach ($titlesAllVariants as &$titlesVariant) { $titlesVariant = explode("", $titlesVariant); } // Then add variants of links to link batch $parentTitle = $this->parent->getTitle(); foreach ($titlesAttrs as $i => $attrs) { /** @var Title $title */ list($index, $title) = $attrs; $ns = $title->getNamespace(); $text = $title->getText(); foreach ($allVariantsName as $variantName) { $textVariant = $titlesAllVariants[$variantName][$i]; if ($textVariant === $text) { continue; } $variantTitle = Title::makeTitle($ns, $textVariant); if (is_null($variantTitle)) { continue; } // Self-link checking for mixed/different variant titles. At this point, we // already know the exact title does not exist, so the link cannot be to a // variant of the current title that exists as a separate page. if ($variantTitle->equals($parentTitle) && !$title->hasFragment()) { $this->internals[$ns][$index]['selflink'] = true; continue 2; } $linkBatch->addObj($variantTitle); $variantMap[$variantTitle->getPrefixedDBkey()][] = "{$ns}:{$index}"; } } // process categories, check if a category exists in some variant $categoryMap = array(); // maps $category_variant => $category (dbkeys) $varCategories = array(); // category replacements oldDBkey => newDBkey foreach ($output->getCategoryLinks() as $category) { $categoryTitle = Title::makeTitleSafe(NS_CATEGORY, $category); $linkBatch->addObj($categoryTitle); $variants = $wgContLang->autoConvertToAllVariants($category); foreach ($variants as $variant) { if ($variant !== $category) { $variantTitle = Title::makeTitleSafe(NS_CATEGORY, $variant); if (is_null($variantTitle)) { continue; } $linkBatch->addObj($variantTitle); $categoryMap[$variant] = array($category, $categoryTitle); } } } if (!$linkBatch->isEmpty()) { // construct query $dbr = wfGetDB(DB_SLAVE); $fields = array('page_id', 'page_namespace', 'page_title', 'page_is_redirect', 'page_len', 'page_latest'); if ($wgContentHandlerUseDB) { $fields[] = 'page_content_model'; } $varRes = $dbr->select('page', $fields, $linkBatch->constructSet('page', $dbr), __METHOD__); $linkcolour_ids = array(); // for each found variants, figure out link holders and replace foreach ($varRes as $s) { $variantTitle = Title::makeTitle($s->page_namespace, $s->page_title); $varPdbk = $variantTitle->getPrefixedDBkey(); $vardbk = $variantTitle->getDBkey(); $holderKeys = array(); if (isset($variantMap[$varPdbk])) { $holderKeys = $variantMap[$varPdbk]; $linkCache->addGoodLinkObjFromRow($variantTitle, $s); $output->addLink($variantTitle, $s->page_id); } // loop over link holders foreach ($holderKeys as $key) { list($ns, $index) = explode(':', $key, 2); $entry =& $this->internals[$ns][$index]; $pdbk = $entry['pdbk']; if (!isset($colours[$pdbk]) || $colours[$pdbk] === 'new') { // found link in some of the variants, replace the link holder data $entry['title'] = $variantTitle; $entry['pdbk'] = $varPdbk; // set pdbk and colour # @todo FIXME: Convoluted data flow # The redirect status and length is passed to getLinkColour via the LinkCache # Use formal parameters instead $colours[$varPdbk] = Linker::getLinkColour($variantTitle, $threshold); $linkcolour_ids[$s->page_id] = $pdbk; } } // check if the object is a variant of a category if (isset($categoryMap[$vardbk])) { list($oldkey, $oldtitle) = $categoryMap[$vardbk]; if (!isset($varCategories[$oldkey]) && !$oldtitle->exists()) { $varCategories[$oldkey] = $vardbk; } } } Hooks::run('GetLinkColours', array($linkcolour_ids, &$colours)); // rebuild the categories in original order (if there are replacements) if (count($varCategories) > 0) { $newCats = array(); $originalCats = $output->getCategories(); foreach ($originalCats as $cat => $sortkey) { // make the replacement if (array_key_exists($cat, $varCategories)) { $newCats[$varCategories[$cat]] = $sortkey; } else { $newCats[$cat] = $sortkey; } } $output->setCategoryLinks($newCats); } } }
function BugzillaRender($input, array $args, Parser $parser, $frame = null) { global $wgBugzillaRESTURL; // We don't want the page to be cached // TODO: Not sure if we need this $parser->disableCache(); // TODO: Figure out to have the parser not do anything to our output // mediawiki docs are wrong :-( // error_log(print_r($parser->mStripState, true)); // $parser->mStripState->addItem( 'nowiki', 'NOWIKI', true); // 'noparse' => true, 'isHTML' => true, 'markerType' => 'nowiki' ); $input = $parser->recursiveTagParse($input, $frame); // Create a new bugzilla object $bz = Bugzilla::create($args, $input, $parser->getTitle()); // Show the desired output (or an error if there was one) return $bz->render(); }
/** * Handles the Parser Hook for TagExtensions * @param string $sInput Content of $lt;pagesvisited /> from MediaWiki Framework * @param array $aAttributes Attributes of <pagesvisited /> from MediaWiki Framework * @param Parser $oParser Parser object from MediaWiki Framework * @return string HTML list of recently visited pages */ public function onPagesVisitedTag($sInput, $aAttributes, $oParser) { $oParser->disableCache(); $oErrorListView = new ViewTagErrorList($this); $iCount = BsCore::sanitizeArrayEntry($aAttributes, 'count', 5, BsPARAMTYPE::INT); $iMaxTitleLength = BsCore::sanitizeArrayEntry($aAttributes, 'maxtitlelength', 20, BsPARAMTYPE::INT); $sNamespaces = BsCore::sanitizeArrayEntry($aAttributes, 'namespaces', 'all', BsPARAMTYPE::STRING | BsPARAMOPTION::CLEANUP_STRING); $sSortOrder = BsCore::sanitizeArrayEntry($aAttributes, 'order', 'time', BsPARAMTYPE::STRING | BsPARAMOPTION::CLEANUP_STRING); //Validation $oValidationICount = BsValidator::isValid('IntegerRange', $iCount, array('fullResponse' => true, 'lowerBoundary' => 1, 'upperBoundary' => 30)); if ($oValidationICount->getErrorCode()) { $oErrorListView->addItem(new ViewTagError('count: ' . $oValidationICount->getI18N())); } $oValidationIMaxTitleLength = BsValidator::isValid('IntegerRange', $iMaxTitleLength, array('fullResponse' => true, 'lowerBoundary' => 5, 'upperBoundary' => 50)); if ($oValidationIMaxTitleLength->getErrorCode()) { $oErrorListView->addItem(new ViewTagError('maxtitlelength: ' . $oValidationIMaxTitleLength->getI18N())); } if ($oErrorListView->hasItems()) { return $oErrorListView->execute(); } $iCurrentNamespaceId = $oParser->getTitle()->getNamespace(); $oListView = $this->makePagesVisitedWikiList($iCount, $sNamespaces, $iCurrentNamespaceId, $iMaxTitleLength, $sSortOrder); $sOut = $oListView->execute(); if ($oListView instanceof ViewTagErrorList) { return $sOut; } else { return $this->mCore->parseWikiText($sOut, $this->getTitle()); } }
protected function handleShapeData(array &$params, Parser $parserClone) { $textContainers = array(&$params['lines'], &$params['polygons'], &$params['circles'], &$params['rectangles'], &$params['imageoverlays']); foreach ($textContainers as &$textContainer) { if (is_array($textContainer)) { foreach ($textContainer as &$obj) { if ($obj instanceof Element) { $obj = $obj->getArrayValue(); } $obj['title'] = $parserClone->parse($obj['title'], $parserClone->getTitle(), new ParserOptions())->getText(); $obj['text'] = $parserClone->parse($obj['text'], $parserClone->getTitle(), new ParserOptions())->getText(); $hasTitleAndtext = $obj['title'] !== '' && $obj['text'] !== ''; $obj['text'] = ($hasTitleAndtext ? '<b>' . $obj['title'] . '</b><hr />' : $obj['title']) . $obj['text']; $obj['title'] = strip_tags($obj['title']); } } } }
/** * Clear all stored data for a given parser. * * @param Parser $parser */ public static function clearStorage(Parser $parser) { $title = $parser->getTitle(); if (!isset($title)) { return; } self::setSMWData($parser->getOutput(), new SMWSemanticData(SMWDIWikiPage::newFromTitle($title))); }
/** * Do not convert content on talk pages * * @param string $text * @param Parser $parser * @return string */ function parserConvert($text, &$parser) { $this->mDoContentConvert = !(is_object($parser->getTitle()) && $parser->getTitle()->isTalkPage()); return parent::parserConvert($text, $parser); }
static function parse_label($input, array $args, Parser $parser, PPFrame $frame) { $ThisPageName = (string) $parser->getTitle(); $ID = $args['label']; // return a id-ed span of the parsed input return Html::rawElement('span', array('id' => $ID), $parser->recursiveTagParse($input, $frame)); }
/** * Hook for parser function {{NUMBEROFVOTESPAGE:<page>}} * * @param Parser $parser * @param string $pagename Page name * @return int Amount of votes for the given page */ static function getNumberOfVotesPageParser($parser, $pagename) { $title = Title::newFromText($pagename); if (!$title instanceof Title) { $title = $parser->getTitle(); } return VoteHooks::getNumberOfVotesPage($title); }
/** * Renders the blog. Called by parser function for bs:blog tag and also from Blog::onUnknownAction. * @param string $input Inner HTML of bs:blog tag. Not used. * @param array $args List of tag attributes. * @param Parser $parser MediaWiki parser object * @return string HTML output that is to be displayed. */ public function onBlog($input, $args, $parser) { $oTitle = null; if ($parser instanceof Parser) { $oTitle = $parser->getTitle(); $parser->disableCache(); } else { $oTitle = $this->getTitle(); } $sKey = BsCacheHelper::getCacheKey('BlueSpice', 'Blog', $oTitle->getArticleID()); $aData = BsCacheHelper::get($sKey); if ($aData !== false) { return $aData; } // initialize local variables $oErrorListView = new ViewTagErrorList($this); BsExtensionManager::setContext('MW::Blog::ShowBlog'); // get all config options $iShowLimit = BsConfig::get('MW::Blog::ShowLimit'); //$blogShowTrackback = BsConfig::get('MW::Blog::ShowTrackback'); // see comment below $bShowPermalink = BsConfig::get('MW::Blog::ShowPermalink'); $bShowInfo = BsConfig::get('MW::Blog::ShowInfo'); $sSortBy = BsConfig::get('MW::Blog::SortBy'); $bMoreInNewWindow = BsConfig::get('MW::Blog::MoreInNewWindow'); $bShowAll = BsConfig::get('MW::Blog::ShowAll'); $bMoreAtEndOfEntry = BsConfig::get('MW::Blog::MoreAtEndOfEntry'); $bShowNewEntryField = BsConfig::get('MW::Blog::ShowNewEntryField'); $bNewEntryFieldPosition = BsConfig::get('MW::Blog::NewEntryFieldPosition'); $sImageRenderMode = BsConfig::get('MW::Blog::ImageRenderMode'); $sImageFloatDirection = BsConfig::get('MW::Blog::ThumbFloatDirection'); $iMaxEntryCharacters = BsConfig::get('MW::Blog::MaxEntryCharacters'); // Trackbacks are not supported the way we intend it to be. From http://www.mediawiki.org/wiki/Manual:$wgUseTrackbacks // When MediaWiki receives a trackback ping, a box will show up at the bottom of the article containing a link to the originating page //if (!$wgUseTrackbacks) $bShowTrackback = false; // get tag attributes $argsIShowLimit = BsCore::sanitizeArrayEntry($args, 'count', $iShowLimit, BsPARAMTYPE::NUMERIC | BsPARAMOPTION::DEFAULT_ON_ERROR); $argsSCategory = BsCore::sanitizeArrayEntry($args, 'cat', false, BsPARAMTYPE::STRING); $argsINamespace = BsNamespaceHelper::getNamespaceIndex(BsCore::sanitizeArrayEntry($args, 'ns', NS_BLOG, BsPARAMTYPE::STRING)); $argsBNewEntryField = BsCore::sanitizeArrayEntry($args, 'newentryfield', $bShowNewEntryField, BsPARAMTYPE::BOOL); $argsSNewEntryFieldPosition = BsCore::sanitizeArrayEntry($args, 'newentryfieldposition', $bNewEntryFieldPosition, BsPARAMTYPE::STRING); $argsSImageRenderMode = BsCore::sanitizeArrayEntry($args, 'imagerendermode', $sImageRenderMode, BsPARAMTYPE::STRING); $argsSImageFloatDirection = BsCore::sanitizeArrayEntry($args, 'imagefloatdirection', $sImageFloatDirection, BsPARAMTYPE::STRING); $argsIMaxEntryCharacters = BsCore::sanitizeArrayEntry($args, 'maxchars', $iMaxEntryCharacters, BsPARAMTYPE::INT); $argsSSortBy = BsCore::sanitizeArrayEntry($args, 'sort', $sSortBy, BsPARAMTYPE::STRING); $argsBShowInfo = BsCore::sanitizeArrayEntry($args, 'showinfo', $bShowInfo, BsPARAMTYPE::BOOL); $argsBMoreInNewWindow = BsCore::sanitizeArrayEntry($args, 'moreinnewwindow', $bMoreInNewWindow, BsPARAMTYPE::BOOL); $argsBShowPermalink = BsCore::sanitizeArrayEntry($args, 'showpermalink', $bShowPermalink, BsPARAMTYPE::BOOL); $argsModeNamespace = BsCore::sanitizeArrayEntry($args, 'mode', null, BsPARAMTYPE::STRING); if ($argsModeNamespace === 'ns' && is_object($oTitle)) { $argsINamespace = $oTitle->getNamespace(); } // validate tag attributes $validateIShowLimit = BsValidator::isValid('ArgCount', $argsIShowLimit, array('fullResponse' => true)); if ($validateIShowLimit->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($validateIShowLimit->getI18N())); } if ($argsSCategory) { $validateSCategory = BsValidator::isValid('Category', $argsSCategory, array('fullResponse' => true)); if ($validateSCategory->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($validateSCategory->getI18N())); } } $oValidationResult = BsValidator::isValid('SetItem', $argsSImageRenderMode, array('fullResponse' => true, 'setname' => 'imagerendermode', 'set' => array('full', 'thumb', 'none'))); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } $oValidationResult = BsValidator::isValid('SetItem', $argsSImageFloatDirection, array('fullResponse' => true, 'setname' => 'imagefloatdirection', 'set' => array('left', 'right', 'none'))); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } $oValidationResult = BsValidator::isValid('SetItem', $argsSSortBy, array('fullResponse' => true, 'setname' => 'sort', 'set' => array('title', 'creation'))); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } // if there are errors, abort with a message if ($oErrorListView->hasEntries()) { return $oErrorListView->execute(); } if (BsConfig::get('MW::Blog::ShowTagFormWhenNotLoggedIn') != true) { $oPermissionTest = Title::newFromText('PermissionTest', $argsINamespace); if (!$oPermissionTest->userCan('edit')) { $argsBNewEntryField = false; } } // get array of article ids from Blog/subpages $oBlogTitle = Title::makeTitleSafe($oTitle->getNamespace(), 'Blog'); $aSubpages = $oBlogTitle->getSubpages(); $iLimit = 0; // for later use $aArticleIds = array(); foreach ($aSubpages as $oSubpage) { $aArticleIds[] = $oSubpage->getArticleID(); $iLimit++; // for later use } if (count($aArticleIds) < 1) { $aArticleIds = 0; } $aTables = array('page'); $aFields = array('entry_page_id' => 'page_id'); $aConditions = array(); $aOptions = array(); $aJoins = array(); $dbr = wfGetDB(DB_SLAVE); // get blog entries if ($argsSSortBy == 'title') { $aOptions['ORDER BY'] = 'page_title ASC'; } else { //Creation: Also fetch possible custom timestamps from page_props table $aOptions['ORDER BY'] = 'entry_timestamp DESC'; $aOptions['GROUP BY'] = 'page_id'; global $wgDBtype; switch ($wgDBtype) { case 'oracle': $aFields['entry_timestamp'] = "NVL( pp_value, rev_timestamp )"; $aConditions[] = "NVL( pp_value, rev_timestamp ) < " . wfTimestampNow(); break; case 'mssql': $aFields['entry_timestamp'] = "ISNULL( pp_value, rev_timestamp )"; $aConditions[] = "ISNULL( pp_value, rev_timestamp ) < " . wfTimestampNow(); break; case 'postgres': $aFields['entry_timestamp'] = "NULLIF( pp_value, rev_timestamp )"; $aConditions[] = "NULLIF( pp_value, rev_timestamp ) < " . wfTimestampNow(); break; default: //MySQL, SQLite //use pp_value if exists $aFields['entry_timestamp'] = "IFNULL( pp_value, rev_timestamp )"; //also do not list future entries $aConditions[] = "IFNULL( pp_value, rev_timestamp ) < " . wfTimestampNow(); } $aTables[] = 'revision'; $aTables[] = 'page_props'; $aConditions[] = 'rev_page = page_id'; $aJoins['page_props'] = array('LEFT JOIN', "pp_page = rev_page AND pp_propname = 'blogtime'"); } if ($argsSCategory) { $aTables[] = 'categorylinks'; $aConditions['cl_to'] = $argsSCategory; $aConditions[] = 'cl_from = page_id'; } else { if ($argsModeNamespace === 'ns') { $aConditions['page_id'] = $aArticleIds; } $aConditions['page_namespace'] = $argsINamespace; } $res = $dbr->select($aTables, $aFields, $aConditions, __METHOD__, $aOptions, $aJoins); $iNumberOfEntries = $dbr->numRows($res); $iLimit = $iNumberOfEntries; //All // Sole importance is the existence of param 'showall' $paramBShowAll = $this->getRequest()->getFuzzyBool('showall', false); if ($paramBShowAll == false) { $iLimit = $argsIShowLimit; } // abort if there are no entries if ($iNumberOfEntries < 1) { $oBlogView = new ViewBlog(); $oBlogView->setOption('shownewentryfield', $argsBNewEntryField); $oBlogView->setOption('newentryfieldposition', $argsSNewEntryFieldPosition); $oBlogView->setOption('namespace', BsNamespaceHelper::getNamespaceName($argsINamespace)); if ($argsSCategory) { $oBlogView->setOption('blogcat', $argsSCategory); } // actually create blog output $sOut = $oBlogView->execute(); $sOut .= wfMessage('bs-blog-no-entries')->plain(); return $sOut; } $oBlogView = new ViewBlog(); // prepare views per blog item $iLoop = 0; foreach ($res as $row) { // prepare data for view class $oEntryTitle = Title::newFromID($row->entry_page_id); if (!$oEntryTitle->userCan('read')) { $iNumberOfEntries--; continue; } $bMore = false; $aContent = preg_split('#<(bs:blog:)?more */>#', BsPageContentProvider::getInstance()->getContentFromTitle($oEntryTitle)); if (sizeof($aContent) > 1) { $bMore = true; } $aContent = trim($aContent[0]); // Prevent recursive rendering of blog tag $aContent = preg_replace('/<(bs:)blog[^>]*?>/', '', $aContent); // Thumbnail images $sNamespaceRegEx = implode('|', BsNamespaceHelper::getNamespaceNamesAndAliases(NS_IMAGE)); switch ($argsSImageRenderMode) { case 'none': $aContent = preg_replace('/(\\[\\[(' . $sNamespaceRegEx . '):[^\\|\\]]*)(\\|)?(.*?)(\\]\\])/', '', $aContent); break; case 'full': // do nothing break; case 'thumb': default: $aContent = preg_replace('/(\\[\\[(' . $sNamespaceRegEx . '):[^\\|\\]]*)(\\|)?(.*?)(\\]\\])/', "\$1|thumb|{$argsSImageFloatDirection}\$3\$4|150px\$5", $aContent); break; } if (strlen($aContent) > $argsIMaxEntryCharacters) { $bMore = true; } $aContent = BsStringHelper::shorten($aContent, array('max-length' => $argsIMaxEntryCharacters, 'ignore-word-borders' => false, 'position' => 'end')); $resComment = $dbr->selectRow('revision', 'COUNT( rev_id ) AS cnt', array('rev_page' => $oEntryTitle->getTalkPage()->getArticleID())); $iCount = $resComment->cnt; // set data for view class $oBlogItemView = new ViewBlogItem(); // use magic set $oBlogItemView->setOption('showInfo', $argsBShowInfo); $oBlogItemView->setOption('showLimit', $argsIShowLimit); $oBlogItemView->setOption('showTrackback', $bShowTrackback); $oBlogItemView->setOption('showPermalink', $argsBShowPermalink); $oBlogItemView->setOption('moreInNewWindow', $argsBMoreInNewWindow); $oBlogItemView->setOption('showAll', $bShowAll); $oBlogItemView->setOption('moreAtEndOfEntry', $bMoreAtEndOfEntry); $oBlogItemView->setOption('more', $bMore); //TODO: magic_call? if ($argsModeNamespace === 'ns') { $sTitle = substr($oEntryTitle->getText(), 5); } else { $sTitle = $oEntryTitle->getText(); } $aTalkParams = array(); if (!$oEntryTitle->getTalkPage()->exists()) { $aTalkParams = array('action' => 'edit'); } $oRevision = Revision::newFromTitle($oEntryTitle); $oBlogItemView->setTitle($sTitle); $oBlogItemView->setRevId($oRevision->getId()); $oBlogItemView->setURL($oEntryTitle->getLocalURL()); $oBlogItemView->setTalkURL($oEntryTitle->getTalkPage()->getLocalURL($aTalkParams)); $oBlogItemView->setTalkCount($iCount); $oBlogItemView->setTrackbackUrl($oEntryTitle->getLocalURL()); if ($bShowInfo) { $oFirstRevision = $oEntryTitle->getFirstRevision(); $sTimestamp = $oFirstRevision->getTimestamp(); $sLocalDateTimeString = BsFormatConverter::timestampToAgeString(wfTimestamp(TS_UNIX, $sTimestamp)); $oBlogItemView->setEntryDate($sLocalDateTimeString); $iUserId = $oFirstRevision->getUser(); if ($iUserId != 0) { $oAuthorUser = User::newFromId($iUserId); $oBlogItemView->setAuthorPage($oAuthorUser->getUserPage()->getPrefixedText()); $oBlogItemView->setAuthorName($this->mCore->getUserDisplayName($oAuthorUser)); } else { $oBlogItemView->setAuthorName($oFirstRevision->getUserText()); } } $oBlogItemView->setContent($aContent); $oBlogView->addItem($oBlogItemView); $iLoop++; if ($iLoop >= $iLimit) { break; } } $dbr->freeResult($res); // prepare complete blog output if ($bShowAll && !$paramBShowAll && $iNumberOfEntries > $argsIShowLimit) { $oBlogView->setOption('showall', true); } $oBlogView->setOption('shownewentryfield', $argsBNewEntryField); $oBlogView->setOption('newentryfieldposition', $argsSNewEntryFieldPosition); $oBlogView->setOption('namespace', BsNamespaceHelper::getNamespaceName($argsINamespace, false)); $oBlogView->setOption('blogcat', $argsSCategory); if ($argsModeNamespace === 'ns') { $oBlogView->setOption('parentpage', 'Blog/'); } // actually create blog output $sOut = $oBlogView->execute(); //Use cache only in NS_BLOG - there is curently no functionality to //figure out in what type of blog tag a entry is showen and why //(coditions). Possible blog by categories or subpages... //Needs rework. if (in_array($oTitle->getNamespace(), array(NS_BLOG, NS_BLOG_TALK))) { $aKey = array($sKey); $sTagsKey = BsCacheHelper::getCacheKey('BlueSpice', 'Blog', 'Tags'); $aTagsData = BsCacheHelper::get($sTagsKey); if ($aTagsData !== false) { if (!in_array($sKey, $aTagsData)) { $aTagsData = array_merge($aTagsData, $aKey); } } else { $aTagsData = $aKey; } BsCacheHelper::set($sTagsKey, $aTagsData, 60 * 1440); // one day BsCacheHelper::set($sKey, $sOut, 60 * 1440); // one day } return $sOut; }
/** * If this song is on takedown list... replace the lyrics content with a message about why * it is gone. This will replace the content of all <lyrics> tags on the page (also <lyricfind> * and <gracenotelyrics> tags for support of legacy pages). * * @param Parser $parser * @param $text a string containing the wikitext (this is _not_ a Text object). * @param strip_state (undocumented) */ public static function onParserBeforeStrip(Parser $parser, &$text, &$strip_state) { $removedProp = wfGetWikiaPageProp(WPP_LYRICFIND_MARKED_FOR_REMOVAL, $parser->getTitle()->getArticleID()); $isMarkedAsRemoved = !empty($removedProp); if ($isMarkedAsRemoved) { // Replace just the lyrics boxes if any are found. If none are found, hide the whole page. $NO_LIMIT = -1; $numReplacements = 0; $text = preg_replace("/<(lyrics|lyricfind|gracenotelyrics)>(.*?)<\\/(lyrics|lyricfind|gracenotelyrics)>/is", "<lyrics>{{lyricfind_takedown}}</lyrics>", $text, $NO_LIMIT, $numReplacements); } return true; }
/** * * @param type $input * @param string $args * @param Parser $parser * @return string */ public function onTagBsPageAccess($input, $args, $parser) { //ignore access tag on mainpage or it will break all ajax calls without title param if ($parser->getTitle()->equals(Title::newMainPage()) === true) { return ''; } $parser->disableCache(); if (!isset($args['groups'])) { $oErrorView = new ViewTagError(wfMessage('bs-pageaccess-error-no-groups-given')->escaped()); return $oErrorView->execute(); } $sOldAccessGroups = $parser->getOutput()->getProperty('bs-page-access'); if ($sOldAccessGroups) { $args['groups'] = $sOldAccessGroups . "," . $args['groups']; } $parser->getOutput()->setProperty('bs-page-access', $args['groups']); return ''; }
/** * Helper to get a new title from user input. Returns null if invalid title is given. * * @param Parser $parser * @param string $title * * @return Title|null */ private static function newTitleObject ( Parser &$parser, $title = null ) { if( is_array( $title ) ) { /* * Instead of one Title, all arguments given to the parser function are given. * This is because it makes things more generic to deal with extension 'Parser Fun' support * especially for functions only requiring an option title. */ // get all possible arguments: $args = ExtSubpageFun::getFunctionArgsArray( $title ); $title = isset( $args[1] ) ? $args[1] : null; } if( $title !== null && $title !== '' ) { return Title::newFromText( $title ); } //returns object of current page if nothing else is requested: return $parser->getTitle(); }
/** * At the end of article parsing, in case of layer page, save layers to database * * @since 3.0 * * @param Parser &$parser * @param string &$text * * @return true */ public static function onParserAfterTidy(Parser &$parser, &$text) { $title = $parser->getTitle(); if ($title === null || self::$purgedBeforeStore !== true) { // just preprocessing some stuff or no purge return true; } self::processLayersStoreCandidate($parser->getOutput(), $title); // Set helper to false immediately so we won't run into job-processing weirdness: self::$purgedBeforeStore = false; return true; }
/** * Get the pageid of a specified page * @param Parser $parser * @param string $title Title to get the pageid from * @return int|null|string * @since 1.23 */ public static function pageid($parser, $title = null) { $t = Title::newFromText($title); if (is_null($t)) { return ''; } // Use title from parser to have correct pageid after edit if ($t->equals($parser->getTitle())) { $t = $parser->getTitle(); return $t->getArticleID(); } // These can't have ids if (!$t->canExist() || $t->isExternal()) { return 0; } // Check the link cache, maybe something already looked it up. $linkCache = LinkCache::singleton(); $pdbk = $t->getPrefixedDBkey(); $id = $linkCache->getGoodLinkID($pdbk); if ($id != 0) { $parser->mOutput->addLink($t, $id); return $id; } if ($linkCache->isBadLink($pdbk)) { $parser->mOutput->addLink($t, 0); return $id; } // We need to load it from the DB, so mark expensive if ($parser->incrementExpensiveFunctionCount()) { $id = $t->getArticleID(); $parser->mOutput->addLink($t, $id); return $id; } return null; }
protected function getJsonForStaticLocation(Location $location, array $params, $iconUrl, $visitedIconUrl, Parser $parser) { $jsonObj = $location->getJSONObject($params['title'], $params['label'], $iconUrl, '', '', $visitedIconUrl); $jsonObj['title'] = $parser->parse($jsonObj['title'], $parser->getTitle(), new ParserOptions())->getText(); $jsonObj['text'] = $parser->parse($jsonObj['text'], $parser->getTitle(), new ParserOptions())->getText(); $hasTitleAndtext = $jsonObj['title'] !== '' && $jsonObj['text'] !== ''; $jsonObj['text'] = ($hasTitleAndtext ? '<b>' . $jsonObj['title'] . '</b><hr />' : $jsonObj['title']) . $jsonObj['text']; $jsonObj['title'] = strip_tags($jsonObj['title']); if ($params['pagelabel']) { $jsonObj['inlineLabel'] = Linker::link(Title::newFromText($jsonObj['title'])); } return $jsonObj; }
protected function parse($wikitext, $params, $newline = false) { $withVars = $this->parser->replaceVariables($wikitext, $this->parser->getPreprocessor()->newCustomFrame($params)); $parserOutput = $this->parser->parse($withVars, $this->parser->getTitle(), $this->parser->getOptions(), $newline); return preg_replace('|{{{.*}}}|Us', '', preg_replace('|[\\n\\r]|Us', '', $parserOutput->getText())); }
/** * Parser hook for the <opengraph> tag. * * This tag is dual-purpose. By specifying the "type" attribute, the type * of Open Graph object represented by the wiki page can be set. The * additional attributes set the <meta> properties for the object. Even * if "type" isn't specified, the other attributes can still be used to * override the default properties. * * If the "action" attribute is given, this tag will render a link that, * when clicked, adds an action to the Facebook user's Timeline with the * wiki page as the target object. If no action is given, $innertext is * discarded. */ public static function parserHook($innertext, array $args, Parser $parser, PPFrame $frame) { global $wgFbOpenGraph, $wgFbOpenGraphCustomObjects; if (empty($wgFbOpenGraph) || empty($wgFbOpenGraphCustomObjects)) { return ''; // Open Graph is disabled for this wiki } if (isset($args['action'])) { $action = $args['action']; unset($args['action']); } else { $action = ''; } if (count($args)) { foreach ($args as $key => $value) { // Expand template arguments $value = trim($parser->replaceVariables($value, $frame)); // Check if $value is a wiki link if (substr($value, 0, 2) == '[[') { $resolved = $parser->replaceInternalLinks($value); $parser->replaceLinkHolders($resolved); preg_match('/^<a\\b[^<>]*?\\bhref=("[^"]*"|\'[^\']*\')/', $resolved, $matches); if (count($matches) >= 2) { global $wgServer; // strip quotes $matches[1] = substr($matches[1], 1, strlen($matches[1]) - 2); $url = $wgServer . $matches[1]; } } $value = !empty($url) ? $url : $parser->recursiveTagParse($value, $frame); $args[$key] = htmlspecialchars($value); } self::registerProperties($parser->getTitle(), $args); } // TODO: Insert a placeholder so that actions can be placed above type definitions on the page if ($action != '') { // See if the action is available for the object type $object = self::newObjectFromTitle($parser->getTitle()); $actions = $object->getCustomActions(); if (count($actions) && in_array($action, $actions)) { // Let the page know it should load the actions module global $wgVersion; if (version_compare($wgVersion, '1.17', '>=')) { global $wgOut; $wgOut->addModules('ext.facebook.actions'); } $innertext = htmlspecialchars($parser->replaceVariables($innertext, $frame)); return '<a href="#" class="mw-facebook-logo opengraph-action opengraph-action-' . $action . '">' . $innertext . '</a>'; } } return ''; }