function StripMarkupExtension($text, $param = array(), $parser = null) { $text = preg_replace('~\\[\\[(.+)(|.+)?\\]\\]~i', '$1', $text); $text = $parser->recursiveTagParse($text); // echo $text; //echo $text; exit; //echo Sanitizer::stripAllTags( $text ); //exit; return trim(Sanitizer::stripAllTags($text)); }
public function setHeaders() { // Overwritten the parent because it sucks! // We want to set <title> but not <h1> $out = $this->getOutput(); $out->setArticleRelated(false); $out->setRobotPolicy('noindex,nofollow'); $name = $this->msg('searchtranslations'); $name = Sanitizer::stripAllTags($name); $out->setHTMLTitle($this->msg('pagetitle')->rawParams($name)); }
/** * Formats an edit comment * @param string $comment The raw comment text * @param Title $title The title of the page that was edited * @fixme: Duplication with SpecialMobileWatchlist * * @return string HTML code */ protected function formatComment($comment, $title) { if ($comment === '') { $comment = $this->msg('mobile-frontend-changeslist-nocomment')->plain(); } else { $comment = Linker::formatComment($comment, $title); // flatten back to text $comment = Sanitizer::stripAllTags($comment); } return $comment; }
/** * Exception constructor * * The input message is a HTTP status message. Because an exception with the * message 'Not Found' is not very clear it this message is tranformed to a * more descriptive text. The original message is available using the * {@link getStatusMessage} method. * * @param string $statusMessage * @param int|null $code */ public function __construct($statusMessage, $code = null, $body = null) { $this->_statusMessage = $statusMessage; $message = 'Solr HTTP error: ' . $statusMessage; if (null !== $code) { $message .= ' (' . $code . ')'; } if (null !== $body) { $message .= html_entity_decode(Sanitizer::stripAllTags($body)); } parent::__construct($message, $code); }
/** * Get text before first heading. * @param string $text * @return string|null */ private function extractHeadingBeforeFirstHeading($text) { $matches = []; if (!preg_match('/<h[123456]>/', $text, $matches, PREG_OFFSET_CAPTURE)) { // There isn't a first heading so we interpret this as the article // being entirely without heading. return null; } $text = substr($text, 0, $matches[0][1]); if (!$text) { // There isn't any text before the first heading so we declare there isn't // a first heading. return null; } $formatter = new HtmlFormatter($text); $formatter->remove($this->excludedElementSelectors); $formatter->remove($this->auxiliaryElementSelectors); $formatter->filterContent(); $text = trim(Sanitizer::stripAllTags($formatter->getText())); if (!$text) { // There isn't any text after filtering before the first heading so we declare // that there isn't a first heading. return null; } return $text; }
/** * "Page title" means the contents of \<h1\>. It is stored as a valid HTML fragment. * This function allows good tags like \<sup\> in the \<h1\> tag, but not bad tags like \<script\>. * This function automatically sets \<title\> to the same content as \<h1\> but with all tags removed. * Bad tags that were escaped in \<h1\> will still be escaped in \<title\>, and good tags like \<i\> will be dropped entirely. * * @param $name string */ public function setPageTitle($name) { # change "<script>foo&bar</script>" to "<script>foo&bar</script>" # but leave "<i>foobar</i>" alone $nameWithTags = Sanitizer::normalizeCharReferences(Sanitizer::removeHTMLtags($name)); $this->mPagetitle = $nameWithTags; # change "<i>foo&bar</i>" to "foo&bar" $this->setHTMLTitle(wfMsg('pagetitle', Sanitizer::stripAllTags($nameWithTags))); }
/** * Override the title of the page when viewed, provided we've been given a * title which will normalise to the canonical title * * @param $parser Parser: parent parser * @param string $text desired title text * @return String */ static function displaytitle($parser, $text = '') { global $wgRestrictDisplayTitle; #parse a limited subset of wiki markup (just the single quote items) $text = $parser->doQuotes($text); #remove stripped text (e.g. the UNIQ-QINU stuff) that was generated by tag extensions/whatever $text = preg_replace('/' . preg_quote($parser->uniqPrefix(), '/') . '.*?' . preg_quote(Parser::MARKER_SUFFIX, '/') . '/', '', $text); #list of disallowed tags for DISPLAYTITLE #these will be escaped even though they are allowed in normal wiki text $bad = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'blockquote', 'ol', 'ul', 'li', 'hr', 'table', 'tr', 'th', 'td', 'dl', 'dd', 'caption', 'p', 'ruby', 'rb', 'rt', 'rp', 'br'); #only requested titles that normalize to the actual title are allowed through #if $wgRestrictDisplayTitle is true (it is by default) #mimic the escaping process that occurs in OutputPage::setPageTitle $text = Sanitizer::normalizeCharReferences(Sanitizer::removeHTMLtags($text, null, array(), array(), $bad)); $title = Title::newFromText(Sanitizer::stripAllTags($text)); if (!$wgRestrictDisplayTitle) { $parser->mOutput->setDisplayTitle($text); } elseif ($title instanceof Title && $title->getFragment() == '' && $title->equals($parser->mTitle)) { $parser->mOutput->setDisplayTitle($text); } return ''; }
/** * Parse image options text and use it to make an image */ function makeImage($title, $options) { # @TODO: let the MediaHandler specify its transform parameters # # Check if the options text is of the form "options|alt text" # Options are: # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang # * left no resizing, just left align. label is used for alt= only # * right same, but right aligned # * none same, but not aligned # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox # * center center the image # * framed Keep original image size, no magnify-button. # * frameless like 'thumb' but without a frame. Keeps user preferences for width # * upright reduce width for upright images, rounded to full __0 px # * border draw a 1px border around the image # vertical-align values (no % or length right now): # * baseline # * sub # * super # * top # * text-top # * middle # * bottom # * text-bottom $parts = array_map('trim', explode('|', $options)); $sk = $this->mOptions->getSkin(); # Give extensions a chance to select the file revision for us $skip = $time = false; wfRunHooks('BeforeParserMakeImageLinkObj', array(&$this, &$title, &$skip, &$time)); if ($skip) { return $sk->makeLinkObj($title); } # Get parameter map $file = wfFindFile($title, $time); $handler = $file ? $file->getHandler() : false; list($paramMap, $mwArray) = $this->getImageParams($handler); # Process the input parameters $caption = ''; $params = array('frame' => array(), 'handler' => array(), 'horizAlign' => array(), 'vertAlign' => array()); foreach ($parts as $part) { list($magicName, $value) = $mwArray->matchVariableStartToEnd($part); if (isset($paramMap[$magicName])) { list($type, $paramName) = $paramMap[$magicName]; $params[$type][$paramName] = $value; // Special case; width and height come in one variable together if ($type == 'handler' && $paramName == 'width') { $m = array(); if (preg_match('/^([0-9]*)x([0-9]*)$/', $value, $m)) { $params[$type]['width'] = intval($m[1]); $params[$type]['height'] = intval($m[2]); } else { $params[$type]['width'] = intval($value); } } } else { $caption = $part; } } # Process alignment parameters if ($params['horizAlign']) { $params['frame']['align'] = key($params['horizAlign']); } if ($params['vertAlign']) { $params['frame']['valign'] = key($params['vertAlign']); } # Validate the handler parameters if ($handler) { foreach ($params['handler'] as $name => $value) { if (!$handler->validateParam($name, $value)) { unset($params['handler'][$name]); } } } # Strip bad stuff out of the alt text $alt = $this->replaceLinkHoldersText($caption); # make sure there are no placeholders in thumbnail attributes # that are later expanded to html- so expand them now and # remove the tags $alt = $this->mStripState->unstripBoth($alt); $alt = Sanitizer::stripAllTags($alt); $params['frame']['alt'] = $alt; $params['frame']['caption'] = $caption; # Linker does the rest $ret = $sk->makeImageLink2($title, $file, $params['frame'], $params['handler']); # Give the handler a chance to modify the parser object if ($handler) { $handler->parserTransformHook($this, $file); } return $ret; }
/** * Override the title of the page when viewed, provided we've been given a * title which will normalise to the canonical title * * @param Parser $parser Parent parser * @param string $text Desired title text * @param string $uarg * @return string */ public static function displaytitle($parser, $text = '', $uarg = '') { global $wgRestrictDisplayTitle; static $magicWords = null; if (is_null($magicWords)) { $magicWords = new MagicWordArray(['displaytitle_noerror', 'displaytitle_noreplace']); } $arg = $magicWords->matchStartToEnd($uarg); // parse a limited subset of wiki markup (just the single quote items) $text = $parser->doQuotes($text); // remove stripped text (e.g. the UNIQ-QINU stuff) that was generated by tag extensions/whatever $text = $parser->killMarkers($text); // list of disallowed tags for DISPLAYTITLE // these will be escaped even though they are allowed in normal wiki text $bad = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'blockquote', 'ol', 'ul', 'li', 'hr', 'table', 'tr', 'th', 'td', 'dl', 'dd', 'caption', 'p', 'ruby', 'rb', 'rt', 'rtc', 'rp', 'br']; // disallow some styles that could be used to bypass $wgRestrictDisplayTitle if ($wgRestrictDisplayTitle) { $htmlTagsCallback = function (&$params) { $decoded = Sanitizer::decodeTagAttributes($params); if (isset($decoded['style'])) { // this is called later anyway, but we need it right now for the regexes below to be safe // calling it twice doesn't hurt $decoded['style'] = Sanitizer::checkCss($decoded['style']); if (preg_match('/(display|user-select|visibility)\\s*:/i', $decoded['style'])) { $decoded['style'] = '/* attempt to bypass $wgRestrictDisplayTitle */'; } } $params = Sanitizer::safeEncodeTagAttributes($decoded); }; } else { $htmlTagsCallback = null; } // only requested titles that normalize to the actual title are allowed through // if $wgRestrictDisplayTitle is true (it is by default) // mimic the escaping process that occurs in OutputPage::setPageTitle $text = Sanitizer::normalizeCharReferences(Sanitizer::removeHTMLtags($text, $htmlTagsCallback, [], [], $bad)); $title = Title::newFromText(Sanitizer::stripAllTags($text)); if (!$wgRestrictDisplayTitle || $title instanceof Title && !$title->hasFragment() && $title->equals($parser->mTitle)) { $old = $parser->mOutput->getProperty('displaytitle'); if ($old === false || $arg !== 'displaytitle_noreplace') { $parser->mOutput->setDisplayTitle($text); } if ($old !== false && $old !== $text && !$arg) { $converter = $parser->getConverterLanguage()->getConverter(); return '<span class="error">' . wfMessage('duplicate-displaytitle', $converter->markNoConversion(wfEscapeWikiText($old)), $converter->markNoConversion(wfEscapeWikiText($text)))->inContentLanguage()->text() . '</span>'; } else { return ''; } } else { $parser->addTrackingCategory('restricted-displaytitle-ignored'); $converter = $parser->getConverterLanguage()->getConverter(); return '<span class="error">' . wfMessage('restricted-displaytitle', $converter->markNoConversion(wfEscapeWikiText($text)))->inContentLanguage()->text() . '</span>'; } }
/** * Formats a comment of revision via Linker:formatComment and Sanitizer::stripAllTags * @param string $comment the comment * @param string $title the title object of comments page * @return string formatted comment */ protected function formatComment($comment, $title) { if ($comment !== '') { $comment = Linker::formatComment($comment, $title); // flatten back to text $comment = Sanitizer::stripAllTags($comment); } return $comment; }
/** * Actually renders the SmartList list view. * @param int $aArgs['count'] Maximum number of items in list. * @param string $aArgs['namespaces'] Comma separated list of namespaces that should be considered. * @param string $aArgs['categories'] Comma separated list of categories that should be considered. * @param string $aArgs['period'] Period of time that should be considered (-|day|week|month) * @param string $aArgs['mode'] Defines the basic criteria of pages that should be considered. Default: recentchanges. Other Extensions can hook into SmartList and define their own mode. * @param bool $aArgs['showMinorChanges'] Should minor changes be considered * @param bool $aArgs['showOnlyNewArtiles'] Should edits be considered or only page creations * @param int $aArgs['trim'] Maximum number of title characters. * @param bool $aArgs['showtext'] Also display article text. * @param int $aArgs['trimtext'] Maximum number of text characters. * @param string $aArgs['order'] Sort order for list. (time|title) * @param bool $aArgs['showns'] Show namespace befor title. * @return string HTML output that is to be displayed. */ private function getCustomList($aArgs) { /* * Contains the items that need to be displayed * @var List of objects with three properties: title, namespace and timestamp */ $aObjectList = array(); $oErrorListView = new ViewTagErrorList($this); $oValidationResult = BsValidator::isValid('ArgCount', $aArgs['count'], array('fullResponse' => true)); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } /* * Validation of namespaces and categories */ $oValidationResult = BsValidator::isValid('SetItem', $aArgs['categoryMode'], array('fullResponse' => true, 'setname' => 'catmode', 'set' => array('AND', 'OR'))); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } $oValidationResult = BsValidator::isValid('SetItem', $aArgs['period'], array('fullResponse' => true, 'setname' => 'period', 'set' => array('-', 'day', 'week', 'month'))); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } $oValidationResult = BsValidator::isValid('PositiveInteger', $aArgs['trim'], array('fullResponse' => true)); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } $oValidationResult = BsValidator::isValid('PositiveInteger', $aArgs['trimtext'], array('fullResponse' => true)); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } $oValidationResult = BsValidator::isValid('SetItem', $aArgs['sort'], array('fullResponse' => true, 'setname' => 'sort', 'set' => array('time', 'title'))); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } $oValidationResult = BsValidator::isValid('SetItem', $aArgs['order'], array('fullResponse' => true, 'setname' => 'order', 'set' => array('ASC', 'DESC'))); if ($oValidationResult->getErrorCode()) { $oErrorListView->addItem(new ViewTagError($oValidationResult->getI18N())); } if ($aArgs['mode'] == 'recentchanges') { $dbr = wfGetDB(DB_SLAVE); $aConditions = array(); switch ($aArgs['period']) { case 'month': $sMinTimestamp = $dbr->timestamp(time() - 30 * 24 * 60 * 60); break; case 'week': $sMinTimestamp = $dbr->timestamp(time() - 7 * 24 * 60 * 60); break; case 'day': $sMinTimestamp = $dbr->timestamp(time() - 24 * 60 * 60); break; default: break; } try { $aNamespaceIds = BsNamespaceHelper::getNamespaceIdsFromAmbiguousCSVString($aArgs['namespaces']); $aConditions[] = 'rc_namespace IN (' . implode(',', $aNamespaceIds) . ')'; } catch (BsInvalidNamespaceException $ex) { $sInvalidNamespaces = implode(', ', $ex->getListOfInvalidNamespaces()); $oErrorListView->addItem(new ViewTagError(wfMessage('bs-smartlist-invalid-namespaces')->numParams(count($ex->getListOfInvalidNamespaces()))->params($sInvalidNamespaces)->text())); } $this->makeCategoriesFilterCondition($aConditions, $aArgs, 'rc_cur_id'); switch ($aArgs['sort']) { case 'title': $sOrderSQL = 'rc_title'; break; default: // ORDER BY MAX() - this one was tricky. It makes sure, only the changes with the maximum date are selected. $sOrderSQL = 'MAX(rc_timestamp)'; break; } switch ($aArgs['order']) { case 'ASC': $sOrderSQL .= ' ASC'; break; default: $sOrderSQL .= ' DESC'; break; } if (!$aArgs['showMinorChanges']) { $aConditions[] = 'rc_minor = 0'; } if ($aArgs['showOnlyNewArticles']) { $sOrderSQL = 'MIN(rc_timestamp) DESC'; $aConditions[] = 'rc_new = 1'; } if (!empty($aArgs['period']) && $aArgs['period'] !== '-') { $aConditions[] = "rc_timestamp > '" . $sMinTimestamp . "'"; } $aConditions[] = 'rc_title = page_title AND rc_namespace = page_namespace'; //prevent display of deleted articles $aConditions[] = 'NOT (rc_type = 3)'; //prevent moves and deletes from being displayed $aFields = array('rc_title as title', 'rc_namespace as namespace'); if (isset($aArgs['meta']) && $aArgs['meta'] == true) { $aFields[] = 'MAX(rc_timestamp) as time, rc_user_text as username'; } if (BsConfig::get('MW::SmartList::Comments')) { $aFields[] = 'MAX(rc_comment) as comment'; } $res = $dbr->select(array('recentchanges', 'page'), $aFields, $aConditions, __METHOD__, array('GROUP BY' => 'rc_title, rc_namespace', 'ORDER BY' => $sOrderSQL)); $iCount = 0; foreach ($res as $row) { if ($iCount == $aArgs['count']) { break; } $oTitle = Title::makeTitleSafe($row->namespace, $row->title); if (!$oTitle || !$oTitle->quickUserCan('read')) { continue; } $aObjectList[] = $row; $iCount++; } $dbr->freeResult($res); } elseif ($aArgs['mode'] == 'whatlinkshere') { //PW(25.02.2015) TODO: //There could be filters - see Special:Whatlinkshere $oTargetTitle = empty($aArgs['target']) ? $this->getContext()->getTitle() : Title::newFromText($aArgs['target']); if (is_null($oTargetTitle)) { $oErrorListView->addItem(new ViewTagError(wfMessage('bs-smartlist-invalid-target')->text())); return $oErrorListView->execute(); } $dbr = wfGetDB(DB_SLAVE); $aTables = array('pagelinks', 'page'); $aFields = array('title' => 'page_title', 'namespace' => 'page_namespace'); $aConditions = array("page_id = pl_from", "pl_namespace = {$oTargetTitle->getNamespace()}", "pl_from NOT IN ({$oTargetTitle->getArticleID()})", "pl_title = '{$oTargetTitle->getDBkey()}'"); $aOptions = array(); try { $aNamespaceIds = BsNamespaceHelper::getNamespaceIdsFromAmbiguousCSVString($aArgs['namespaces']); $aConditions['page_namespace'] = $aNamespaceIds; } catch (BsInvalidNamespaceException $ex) { $sInvalidNamespaces = implode(', ', $ex->getListOfInvalidNamespaces()); $oErrorListView->addItem(new ViewTagError(wfMessage('bs-smartlist-invalid-namespaces')->numParams(count($ex->getListOfInvalidNamespaces()))->params($sInvalidNamespaces)->text())); return $oErrorListView->execute(); } $this->makeCategoriesFilterCondition($aConditions, $aArgs, 'page_id'); //Default: time $aOptions['ORDER BY'] = $aArgs['sort'] == 'title' ? 'page_title' : 'page_id'; //Default DESC $aOptions['ORDER BY'] .= $aArgs['order'] == 'ASC' ? ' ASC' : ' DESC'; $res = $dbr->select($aTables, $aFields, $aConditions, __METHOD__, $aOptions); $iCount = 0; foreach ($res as $row) { if ($iCount == $aArgs['count']) { break; } $oTitle = Title::makeTitleSafe($row->namespace, $row->title); if (!$oTitle || !$oTitle->quickUserCan('read')) { continue; } $aObjectList[] = $row; $iCount++; } $dbr->freeResult($res); } else { wfRunHooks('BSSmartListCustomMode', array(&$aObjectList, $aArgs, $this)); } if ($oErrorListView->hasEntries()) { return $oErrorListView->execute(); } $oSmartListListView = new ViewBaseElement(); $oSmartListListView->setAutoElement(false); $iItems = 1; if (count($aObjectList)) { foreach ($aObjectList as $row) { $oTitle = Title::makeTitleSafe($row->namespace, $row->title); // Security here: only show pages the user can read. $sText = ''; $sMeta = ''; $sComment = ''; $sTitle = $oTitle->getText(); if (BsConfig::get('MW::SmartList::Comments')) { $sComment = strlen($row->comment) > 50 ? substr($row->comment, 0, 50) . '...' : $row->comment; $sComment = wfMessage('bs-smartlist-comment')->params($sComment)->escaped(); } if (isset($aArgs['meta']) && $aArgs['meta'] == true) { $sMeta = ' - <i>(' . $row->username . ', ' . $this->getLanguage()->date($row->time, true, true) . ')</i>'; } $oSmartListListEntryView = new ViewBaseElement(); if ($aArgs['showtext'] && $iItems <= $aArgs['numwithtext']) { $oSmartListListEntryView->setTemplate('*[[:{NAMESPACE}:{TITLE}|{DISPLAYTITLE}]]{META}<br/>{TEXT}' . "\n"); $sText = BsPageContentProvider::getInstance()->getContentFromTitle($oTitle); $sText = Sanitizer::stripAllTags($sText); $sText = BsStringHelper::shorten($sText, array('max-length' => $aArgs['trimtext'], 'position' => 'end')); $sText = '<nowiki>' . $sText . '</nowiki>'; } else { $oSmartListListEntryView->setTemplate('*[[:{NAMESPACE}:{TITLE}|{DISPLAYTITLE}]] {COMMENT} {META}' . "\n"); } if ($aArgs['showns'] == true) { $sDisplayTitle = $oTitle->getFullText(); } else { $sDisplayTitle = $oTitle->getText(); } $sDisplayTitle = BsStringHelper::shorten($sDisplayTitle, array('max-length' => $aArgs['trim'], 'position' => 'middle')); $sNamespaceText = ''; if ($row->namespace > 0 && $row->namespace != null) { $sNamespaceText = MWNamespace::getCanonicalName($row->namespace); } $aData = array('NAMESPACE' => $sNamespaceText, 'TITLE' => $sTitle, 'DISPLAYTITLE' => $sDisplayTitle, 'COMMENT' => $sComment, 'META' => $sMeta, 'TEXT' => $sText); wfRunHooks('BSSmartListBeforeEntryViewAddData', array(&$aData, $aArgs, $oSmartListListEntryView, $row)); $oSmartListListEntryView->addData($aData); $oSmartListListView->addItem($oSmartListListEntryView); $iItems++; } } else { return ''; } return $this->mCore->parseWikiText($oSmartListListView->execute(), $this->getTitle()); }
/** * Generates plain text content of a given wiki page without WikiText or HTML tags * @param object $oTitle Title object * @return string Plain text content */ public function prepareTextForIndex(Title $oTitle) { $sText = WikiPage::newFromID($oTitle->getArticleID())->getContent()->getParserOutput($oTitle)->getText(); $sText = Sanitizer::stripAllTags($sText); $sText = str_replace($this->aFragsToBeReplaced, ' ', $sText); $sText = html_entity_decode($sText); return $sText; }
/** * Parse image options text and use it to make an image */ function makeImage($nt, $options) { # @TODO: let the MediaHandler specify its transform parameters # # Check if the options text is of the form "options|alt text" # Options are: # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang # * left no resizing, just left align. label is used for alt= only # * right same, but right aligned # * none same, but not aligned # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox # * center center the image # * framed Keep original image size, no magnify-button. # vertical-align values (no % or length right now): # * baseline # * sub # * super # * top # * text-top # * middle # * bottom # * text-bottom $part = array_map('trim', explode('|', $options)); $mwAlign = array(); $alignments = array('left', 'right', 'center', 'none', 'baseline', 'sub', 'super', 'top', 'text-top', 'middle', 'bottom', 'text-bottom'); foreach ($alignments as $alignment) { $mwAlign[$alignment] =& MagicWord::get('img_' . $alignment); } $mwThumb =& MagicWord::get('img_thumbnail'); $mwManualThumb =& MagicWord::get('img_manualthumb'); $mwWidth =& MagicWord::get('img_width'); $mwFramed =& MagicWord::get('img_framed'); $mwPage =& MagicWord::get('img_page'); $caption = ''; $params = array(); $framed = $thumb = false; $manual_thumb = ''; $align = $valign = ''; $sk = $this->mOptions->getSkin(); foreach ($part as $val) { if (!is_null($mwThumb->matchVariableStartToEnd($val))) { $thumb = true; } elseif (!is_null($match = $mwManualThumb->matchVariableStartToEnd($val))) { # use manually specified thumbnail $thumb = true; $manual_thumb = $match; } else { foreach ($alignments as $alignment) { if (!is_null($mwAlign[$alignment]->matchVariableStartToEnd($val))) { switch ($alignment) { case 'left': case 'right': case 'center': case 'none': $align = $alignment; break; default: $valign = $alignment; } continue 2; } } if (!is_null($match = $mwPage->matchVariableStartToEnd($val))) { # Select a page in a multipage document $params['page'] = $match; } elseif (!isset($params['width']) && !is_null($match = $mwWidth->matchVariableStartToEnd($val))) { wfDebug("img_width match: {$match}\n"); # $match is the image width in pixels $m = array(); if (preg_match('/^([0-9]*)x([0-9]*)$/', $match, $m)) { $params['width'] = intval($m[1]); $params['height'] = intval($m[2]); } else { $params['width'] = intval($match); } } elseif (!is_null($mwFramed->matchVariableStartToEnd($val))) { $framed = true; } else { $caption = $val; } } } # Strip bad stuff out of the alt text $alt = $this->replaceLinkHoldersText($caption); # make sure there are no placeholders in thumbnail attributes # that are later expanded to html- so expand them now and # remove the tags $alt = $this->mStripState->unstripBoth($alt); $alt = Sanitizer::stripAllTags($alt); # Linker does the rest return $sk->makeImageLinkObj($nt, $caption, $alt, $align, $params, $framed, $thumb, $manual_thumb, $valign); }
/** * ArticleEditUpdates hook handler function. * Performs post-edit updates if article is a wikilog article. */ static function ArticleEditUpdates( &$article, &$editInfo, $changed ) { # When editing through MW interface, article is derived from # WikilogCommentsPage. In this case, update the comment object. if ( $article instanceof WikilogCommentsPage && $changed ) { $cmt =& $article->mSingleComment; if ( $cmt && !$cmt->isTextChanged() && $changed ) { $cmt->mUpdated = wfTimestamp( TS_MW ); $cmt->saveComment(); } } $title = $article->getTitle(); $wi = Wikilog::getWikilogInfo( $title ); # Do nothing if not a wikilog article. if ( !$wi ) return true; if ( $title->isTalkPage() ) { # ::WikilogCommentsPage:: # Invalidate cache of wikilog item page. if ( $wi->getItemTitle()->exists() ) { $wi->getItemTitle()->invalidateCache(); $wi->getItemTitle()->purgeSquid(); } } elseif ( $wi->isItem() ) { # ::WikilogItemPage:: $item = WikilogItem::newFromInfo( $wi ); if ( !$item ) { $item = new WikilogItem(); } $item->mName = $wi->getItemName(); $item->mTitle = $wi->getItemTitle(); $item->mParentName = $wi->getName(); $item->mParentTitle = $wi->getTitle(); $item->mParent = $item->mParentTitle->getArticleId(); # Override item name if {{DISPLAYTITLE:...}} was used. $dtText = $editInfo->output->getDisplayTitle(); if ( $dtText ) { # Tags are stripped on purpose. $dtText = Sanitizer::stripAllTags( $dtText ); $dtParts = explode( '/', $dtText, 2 ); if ( count( $dtParts ) > 1 ) { $item->mName = $dtParts[1]; } } $item->resetID( $article->getId() ); # Check if we have any wikilog metadata available. if ( isset( $editInfo->output->mExtWikilog ) ) { $output = $editInfo->output->mExtWikilog; # Update entry in wikilog_posts table. # Entries in wikilog_authors and wikilog_tags are updated # during LinksUpdate process. $item->mPublish = $output->mPublish; $item->mUpdated = wfTimestamp( TS_MW ); $item->mPubDate = $output->mPublish ? $output->mPubDate : $item->mUpdated; $item->mAuthors = $output->mAuthors; $item->mTags = $output->mTags; $item->saveData(); } else { # Remove entry from tables. Entries in wikilog_authors and # wikilog_tags are removed during LinksUpdate process. $item->deleteData(); } # Invalidate cache of parent wikilog page. WikilogUtils::updateWikilog( $wi->getTitle() ); } else { # ::WikilogMainPage:: $dbw = wfGetDB( DB_MASTER ); $id = $article->getId(); # Check if we have any wikilog metadata available. if ( isset( $editInfo->output->mExtWikilog ) ) { $output = $editInfo->output->mExtWikilog; $subtitle = $output->mSummary ? array( 'html', $output->mSummary ) : ''; # Update entry in wikilog_wikilogs table. Entries in # wikilog_authors and wikilog_tags are updated during # LinksUpdate process. $dbw->replace( 'wikilog_wikilogs', 'wlw_page', array( 'wlw_page' => $id, 'wlw_subtitle' => serialize( $subtitle ), 'wlw_icon' => $output->mIcon ? $output->mIcon->getDBKey() : '', 'wlw_logo' => $output->mLogo ? $output->mLogo->getDBKey() : '', 'wlw_authors' => serialize( $output->mAuthors ), 'wlw_updated' => $dbw->timestamp() ), __METHOD__ ); } else { # Remove entry from tables. Entries in wikilog_authors and # wikilog_tags are removed during LinksUpdate process. $dbw->delete( 'wikilog_wikilogs', array( 'wlw_page' => $id ), __METHOD__ ); } } return true; }
/** * Append the debug info to given ApiResult * * @param $context IContextSource * @param $result ApiResult */ public static function appendDebugInfoToApiResult(IContextSource $context, ApiResult $result) { if (!self::$enabled) { return; } // output errors as debug info, when display_errors is on // this is necessary for all non html output of the api, because that clears all errors first $obContents = ob_get_contents(); if ($obContents) { $obContentArray = explode('<br />', $obContents); foreach ($obContentArray as $obContent) { if (trim($obContent)) { self::debugMsg(Sanitizer::stripAllTags($obContent)); } } } MWDebug::log('MWDebug output complete'); $debugInfo = self::getDebugInfo($context); $result->setIndexedTagName($debugInfo, 'debuginfo'); $result->setIndexedTagName($debugInfo['log'], 'line'); $result->setIndexedTagName($debugInfo['debugLog'], 'msg'); $result->setIndexedTagName($debugInfo['queries'], 'query'); $result->setIndexedTagName($debugInfo['includes'], 'queries'); $result->addValue(null, 'debuginfo', $debugInfo); }
protected function printRow($row, &$rownum, &$rows_in_cur_column, $rows_per_column, $format, $plainlist, $header, $footer, $rowstart, $rowend, &$result, $column_width, $res, $listsep, $finallistsep) { $rownum++; if ($this->mColumns > 1) { if ($rows_in_cur_column == $rows_per_column) { // If it's a numbered list, and it's split // into columns, add in the 'start=' // attribute so that each additional column // starts at the right place. This attribute // is actually deprecated, but it appears to // still be supported by the major browsers... if ($format == 'ol') { $header = "<ol start=\"" . ($rownum + 1) . "\">"; } $result .= <<<END \t\t\t\t{$footer} \t\t\t\t</div> \t\t\t\t<div style="float: left; width: {$column_width}%"> \t\t\t\t{$header} END; $rows_in_cur_column = 0; } $rows_in_cur_column++; } if ($rownum > 0 && $plainlist) { $result .= $rownum <= $res->getCount() ? $listsep : $finallistsep; // the comma between "rows" other than the last one } else { $result .= $rowstart; } if ($this->mTemplate !== '') { // build template code $this->hasTemplates = true; $wikitext = $this->mUserParam ? "|userparam={$this->mUserParam}" : ''; foreach ($row as $i => $field) { $wikitext .= '|' . ($this->mNamedArgs ? '?' . $field->getPrintRequest()->getLabel() : $i + 1) . '='; $first_value = true; while (($text = $field->getNextText(SMW_OUTPUT_WIKI, $this->getLinker($i == 0))) !== false) { if ($first_value) { $first_value = false; } else { $wikitext .= ', '; } $wikitext .= $text; } } $wikitext .= "|#={$rownum}"; $result .= '{{' . $this->mTemplate . $wikitext . '}}'; // str_replace('|', '|', // encode '|' for use in templates (templates fail otherwise) -- this is not the place for doing this, since even DV-Wikitexts contain proper "|"! } else { // build simple list $first_col = true; $found_values = false; // has anything but the first column been printed? foreach ($row as $field) { $first_value = true; while (($text = $field->getNextText(SMW_OUTPUT_WIKI, $this->getLinker($first_col))) !== false) { if (!$first_col && !$found_values) { // first values after first column $result .= ' ('; $found_values = true; } elseif ($found_values || !$first_value) { // any value after '(' or non-first values on first column $result .= "{$listsep} "; } if ($first_value) { // first value in any column, print header $first_value = false; if ($this->mShowHeaders != SMW_HEADERS_HIDE && $field->getPrintRequest()->getLabel() !== '') { $result .= $field->getPrintRequest()->getText(SMW_OUTPUT_WIKI, $this->mShowHeaders == SMW_HEADERS_PLAIN ? null : $this->mLinker) . ' '; } } if ($this->isPlainlist()) { $result .= $text; } else { $result .= Sanitizer::stripAllTags($text); // actual output value } } $first_col = false; } if ($found_values) { $result .= ')'; } } $result .= $rowend; }
/** * Parse image options text and use it to make an image */ function makeImage(&$nt, $options) { global $wgUseImageResize, $wgDjvuRenderer; $align = ''; # Check if the options text is of the form "options|alt text" # Options are: # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang # * left no resizing, just left align. label is used for alt= only # * right same, but right aligned # * none same, but not aligned # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox # * center center the image # * framed Keep original image size, no magnify-button. $part = explode('|', $options); $mwThumb =& MagicWord::get('img_thumbnail'); $mwManualThumb =& MagicWord::get('img_manualthumb'); $mwLeft =& MagicWord::get('img_left'); $mwRight =& MagicWord::get('img_right'); $mwNone =& MagicWord::get('img_none'); $mwWidth =& MagicWord::get('img_width'); $mwCenter =& MagicWord::get('img_center'); $mwFramed =& MagicWord::get('img_framed'); $mwPage =& MagicWord::get('img_page'); $caption = ''; $width = $height = $framed = $thumb = false; $page = null; $manual_thumb = ''; foreach ($part as $key => $val) { if ($wgUseImageResize && !is_null($mwThumb->matchVariableStartToEnd($val))) { $thumb = true; } elseif (!is_null($match = $mwManualThumb->matchVariableStartToEnd($val))) { # use manually specified thumbnail $thumb = true; $manual_thumb = $match; } elseif (!is_null($mwRight->matchVariableStartToEnd($val))) { # remember to set an alignment, don't render immediately $align = 'right'; } elseif (!is_null($mwLeft->matchVariableStartToEnd($val))) { # remember to set an alignment, don't render immediately $align = 'left'; } elseif (!is_null($mwCenter->matchVariableStartToEnd($val))) { # remember to set an alignment, don't render immediately $align = 'center'; } elseif (!is_null($mwNone->matchVariableStartToEnd($val))) { # remember to set an alignment, don't render immediately $align = 'none'; } elseif (isset($wgDjvuRenderer) && $wgDjvuRenderer && !is_null($match = $mwPage->matchVariableStartToEnd($val))) { # Select a page in a multipage document $page = $match; } elseif ($wgUseImageResize && !is_null($match = $mwWidth->matchVariableStartToEnd($val))) { wfDebug("img_width match: {$match}\n"); # $match is the image width in pixels if (preg_match('/^([0-9]*)x([0-9]*)$/', $match, $m)) { $width = intval($m[1]); $height = intval($m[2]); } else { $width = intval($match); } } elseif (!is_null($mwFramed->matchVariableStartToEnd($val))) { $framed = true; } else { $caption = $val; } } # Strip bad stuff out of the alt text $alt = $this->replaceLinkHoldersText($caption); # make sure there are no placeholders in thumbnail attributes # that are later expanded to html- so expand them now and # remove the tags $alt = $this->unstrip($alt, $this->mStripState); $alt = Sanitizer::stripAllTags($alt); # Linker does the rest $sk =& $this->mOptions->getSkin(); return $sk->makeImageLinkObj($nt, $caption, $alt, $align, $width, $height, $framed, $thumb, $manual_thumb, $page); }
/** * @param $caption * @param $holders LinkHolderArray * @return mixed|String */ protected function stripAltText($caption, $holders) { # Strip bad stuff out of the title (tooltip). We can't just use # replaceLinkHoldersText() here, because if this function is called # from replaceInternalLinks2(), mLinkHolders won't be up-to-date. if ($holders) { $tooltip = $holders->replaceText($caption); } else { $tooltip = $this->replaceLinkHoldersText($caption); } # make sure there are no placeholders in thumbnail attributes # that are later expanded to html- so expand them now and # remove the tags $tooltip = $this->mStripState->unstripBoth($tooltip); $tooltip = Sanitizer::stripAllTags($tooltip); return $tooltip; }
/** * Override the title of the page when viewed, provided we've been given a * title which will normalise to the canonical title * * @param $parser Parser: parent parser * @param string $text desired title text * @return String */ static function displaytitle($parser, $text = '') { global $wgRestrictDisplayTitle; // parse a limited subset of wiki markup (just the single quote items) $text = $parser->doQuotes($text); // remove stripped text (e.g. the UNIQ-QINU stuff) that was generated by tag extensions/whatever $text = preg_replace('/' . preg_quote($parser->uniqPrefix(), '/') . '.*?' . preg_quote(Parser::MARKER_SUFFIX, '/') . '/', '', $text); // list of disallowed tags for DISPLAYTITLE // these will be escaped even though they are allowed in normal wiki text $bad = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'blockquote', 'ol', 'ul', 'li', 'hr', 'table', 'tr', 'th', 'td', 'dl', 'dd', 'caption', 'p', 'ruby', 'rb', 'rt', 'rp', 'br'); // disallow some styles that could be used to bypass $wgRestrictDisplayTitle if ($wgRestrictDisplayTitle) { $htmlTagsCallback = function (&$params) { $decoded = Sanitizer::decodeTagAttributes($params); if (isset($decoded['style'])) { // this is called later anyway, but we need it right now for the regexes below to be safe // calling it twice doesn't hurt $decoded['style'] = Sanitizer::checkCss($decoded['style']); if (preg_match('/(display|user-select|visibility)\\s*:/i', $decoded['style'])) { $decoded['style'] = '/* attempt to bypass $wgRestrictDisplayTitle */'; } } $params = Sanitizer::safeEncodeTagAttributes($decoded); }; } else { $htmlTagsCallback = null; } // only requested titles that normalize to the actual title are allowed through // if $wgRestrictDisplayTitle is true (it is by default) // mimic the escaping process that occurs in OutputPage::setPageTitle $text = Sanitizer::normalizeCharReferences(Sanitizer::removeHTMLtags($text, $htmlTagsCallback, array(), array(), $bad)); $title = Title::newFromText(Sanitizer::stripAllTags($text)); if (!$wgRestrictDisplayTitle) { $parser->mOutput->setDisplayTitle($text); } elseif ($title instanceof Title && !$title->hasFragment() && $title->equals($parser->mTitle)) { $parser->mOutput->setDisplayTitle($text); } return ''; }
/** * "Page title" means the contents of \<h1\>. It is stored as a valid HTML * fragment. This function allows good tags like \<sup\> in the \<h1\> tag, * but not bad tags like \<script\>. This function automatically sets * \<title\> to the same content as \<h1\> but with all tags removed. Bad * tags that were escaped in \<h1\> will still be escaped in \<title\>, and * good tags like \<i\> will be dropped entirely. * * @param string|Message $name */ public function setPageTitle($name) { if ($name instanceof Message) { $name = $name->setContext($this->getContext())->text(); } # change "<script>foo&bar</script>" to "<script>foo&bar</script>" # but leave "<i>foobar</i>" alone $nameWithTags = Sanitizer::normalizeCharReferences(Sanitizer::removeHTMLtags($name)); $this->mPagetitle = $nameWithTags; # change "<i>foo&bar</i>" to "foo&bar" $this->setHTMLTitle($this->msg('pagetitle')->rawParams(Sanitizer::stripAllTags($nameWithTags))->inContentLanguage()); }
/** * Creates links for different groups by accessing group link pages. * Name of page is: $name_$group * * @return HTML */ function smwfCreateLinks($name) { global $wgUser, $wgTitle; $groups = $wgUser->getGroups(); $links = array(); foreach ($groups as $g) { $nav = new Article(Title::newFromText($name . '_' . $g, NS_MEDIAWIKI)); $content = $nav->fetchContent(0, false, false); $matches = array(); preg_match_all('/\\*\\s*([^|]+)\\|\\s*([^|\\n]*)(\\|.*)?/', $content, $matches); for ($i = 0; $i < count($matches[0]); $i++) { $links[$matches[2][$i]] = $matches[1][$i]; $extraAttributes[$matches[2][$i]] = isset($matches[3][$i]) ? substr(trim($matches[3][$i]), 1) : ""; } } $links = array_unique($links); $result = ""; foreach ($links as $name => $page_title) { $name = Sanitizer::stripAllTags($name); $page_title = Sanitizer::stripAllTags($page_title); $query = ""; if (stripos($page_title, "?") !== false) { $query = substr($page_title, stripos($page_title, "?") + 1); $page_title = substr($page_title, 0, stripos($page_title, "?")); } // Replace some variables: // PAGE_TITLE : Page title WITH namespace // PAGE_TITLE_WNS : Page title WITHOUT namespace // PAGE_NS : Page namespace as text $query = str_replace("{{{PAGE_TITLE}}}", $wgTitle->getPrefixedDBkey(), $query); $query = str_replace("{{{PAGE_NS}}}", $wgTitle->getNsText(), $query); $query = str_replace("{{{PAGE_TITLE_WNS}}}", $wgTitle->getDBkey(), $query); $page_title = str_replace("{{{PAGE_TITLE}}}", $wgTitle->getPrefixedDBkey(), $page_title); //Check if ontoskin is available else return code for new skins global $wgUser; if ($wgUser->getSkin() == 'ontoskin') { $result .= '<li><a href="' . Skin::makeUrl($page_title, $query) . '" ' . $extraAttributes[$name] . '>' . $name . '</a></li>'; } else { $result .= '<tr><td><div class="smwf_naviitem"><a href="' . Skin::makeUrl($page_title, $query) . '" ' . $extraAttributes[$name] . '>' . $name . '</a></div></td></tr>'; } } return $result; }