X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FParser.php;h=4b85c1a3e9940146ad3bb63fb78b0585eb3a485f;hb=113bb1c772d2ddb70345e5027676338ad00f1c2a;hp=68470c8bc14e46c456b4fd675792bae1d627e11d;hpb=52d2e48d2723b0b3e0cac1ba009f6b5a3aec2e98;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Parser.php b/includes/Parser.php index 68470c8bc1..4b85c1a3e9 100644 --- a/includes/Parser.php +++ b/includes/Parser.php @@ -2,8 +2,7 @@ /** * File for Parser and related classes * - * @package MediaWiki - * @subpackage Parser + * @addtogroup Parser */ /** @@ -57,9 +56,10 @@ define( 'MW_COLON_STATE_COMMENTDASH', 6 ); define( 'MW_COLON_STATE_COMMENTDASHDASH', 7 ); /** - * PHP Parser - * - * Processes wiki markup + * PHP Parser - Processes wiki markup (which uses a more user-friendly + * syntax, such as "[[link]]" for making links), and provides a one-way + * transformation of that wiki markup it into XHTML output / markup + * (which in turn the browser understands, and can display). * *
  * There are four main entry points into the Parser class:
@@ -86,10 +86,10 @@ define( 'MW_COLON_STATE_COMMENTDASHDASH', 7 );
  *  * only within ParserOptions
  * 
* - * @package MediaWiki */ class Parser { + const VERSION = MW_PARSER_VERSION; /**#@+ * @private */ @@ -723,7 +723,7 @@ class Parser $descriptorspec = array( 0 => array('pipe', 'r'), 1 => array('pipe', 'w'), - 2 => array('file', '/dev/null', 'a') + 2 => array('file', '/dev/null', 'a') // FIXME: this line in UNIX-specific, it generates a warning on Windows, because /dev/null is not a valid Windows file. ); $pipes = array(); $process = proc_open("$wgTidyBin -config $wgTidyConf $wgTidyOpts$opts", $descriptorspec, $pipes); @@ -1001,6 +1001,7 @@ class Parser $text = Sanitizer::removeHTMLtags( $text, array( &$this, 'attributeStripCallback' ) ); $text = $this->replaceVariables( $text, $args ); + wfRunHooks( 'InternalParseBeforeLinks', array( &$this, &$text ) ); // Tables need to come after variable replacement for things to work // properly; putting them before other transformations should keep @@ -1085,7 +1086,7 @@ class Parser } $url = wfMsg( $urlmsg, $id); - $sk =& $this->mOptions->getSkin(); + $sk = $this->mOptions->getSkin(); $la = $sk->getExternalLinkAttributes( $url, $keyword.$id ); $text = "{$keyword} {$id}"; } @@ -1286,7 +1287,8 @@ class Parser $output .= ''; if ($state == 'bi') $output .= ''; - if ($state == 'both') + # There might be lonely ''''', so make sure we have a buffer + if ($state == 'both' && $buffer) $output .= ''.$buffer.''; return $output; } @@ -1305,7 +1307,7 @@ class Parser $fname = 'Parser::replaceExternalLinks'; wfProfileIn( $fname ); - $sk =& $this->mOptions->getSkin(); + $sk = $this->mOptions->getSkin(); $bits = preg_split( EXT_LINK_BRACKETED, $text, -1, PREG_SPLIT_DELIM_CAPTURE ); @@ -1394,7 +1396,7 @@ class Parser $s = array_shift( $bits ); $i = 0; - $sk =& $this->mOptions->getSkin(); + $sk = $this->mOptions->getSkin(); while ( $i < count( $bits ) ){ $protocol = $bits[$i++]; @@ -1467,7 +1469,7 @@ class Parser * @param string * @return string * @static - * @fixme This can merge genuinely required bits in the path or query string, + * @todo This can merge genuinely required bits in the path or query string, * breaking legit URLs. A proper fix would treat the various parts of * the URL differently; as a workaround, just use the output for * statistical records, not for actual linking/output. @@ -1502,7 +1504,7 @@ class Parser * @private */ function maybeMakeExternalImage( $url ) { - $sk =& $this->mOptions->getSkin(); + $sk = $this->mOptions->getSkin(); $imagesfrom = $this->mOptions->getAllowExternalImagesFrom(); $imagesexception = !empty($imagesfrom); $text = false; @@ -1532,7 +1534,7 @@ class Parser # the % is needed to support urlencoded titles as well if ( !$tc ) { $tc = Title::legalChars() . '#%'; } - $sk =& $this->mOptions->getSkin(); + $sk = $this->mOptions->getSkin(); #split the entire text string on occurences of [[ $a = explode( '[[', ' ' . $s ); @@ -1625,7 +1627,7 @@ class Parser $might_be_img = true; $text = $m[2]; if ( strpos( $m[1], '%' ) !== false ) { - $m[1] = urldecode($m[1]); + $m[1] = urldecode($m[1]); } $trail = ""; } else { # Invalid form; output directly @@ -1722,8 +1724,8 @@ class Parser wfProfileIn( "$fname-interwiki" ); if( $iw && $this->mOptions->getInterwikiMagic() && $nottalk && $wgContLang->getLanguageName( $iw ) ) { $this->mOutput->addLanguageLink( $nt->getFullText() ); - $s = rtrim($s . "\n"); - $s .= trim($prefix . $trail, "\n") == '' ? '': $prefix . $trail; + $s = rtrim($s . $prefix); + $s .= trim($trail, "\n") == '' ? '': $prefix . $trail; wfProfileOut( "$fname-interwiki" ); continue; } @@ -1862,7 +1864,7 @@ class Parser */ function makeKnownLinkHolder( $nt, $text = '', $query = '', $trail = '', $prefix = '' ) { list( $inside, $trail ) = Linker::splitTrail( $trail ); - $sk =& $this->mOptions->getSkin(); + $sk = $this->mOptions->getSkin(); $link = $sk->makeKnownLinkObj( $nt, $text, $query, $inside, $prefix ); return $this->armorLinks( $link ) . $trail; } @@ -1923,9 +1925,9 @@ class Parser # Look at the first character if( $target != '' && $target{0} == '/' ) { # / at end means we don't want the slash to be shown - if( substr( $target, -1, 1 ) == '/' ) { - $target = substr( $target, 1, -1 ); - $noslash = $target; + $trailingSlashes = preg_match_all( '%(/+)$%', $target, $m ); + if( $trailingSlashes ) { + $noslash = $target = substr( $target, 1, -strlen($m[0][0]) ); } else { $noslash = substr( $target, 1 ); } @@ -2888,7 +2890,7 @@ class Parser * @private */ function braceSubstitution( $piece ) { - global $wgContLang, $wgLang, $wgAllowDisplayTitle; + global $wgContLang, $wgLang, $wgAllowDisplayTitle, $wgNonincludableNamespaces; $fname = __METHOD__ /*. '-L' . count( $this->mArgStack )*/; wfProfileIn( $fname ); wfProfileIn( __METHOD__.'-setup' ); @@ -3031,6 +3033,19 @@ class Parser } else { # set $text to cached message. $text = $linestart . $this->mTemplates[$piece['title']]; + #treat title for cached page the same as others + $ns = NS_TEMPLATE; + $subpage = ''; + $part1 = $this->maybeDoSubpageLink( $part1, $subpage ); + if ($subpage !== '') { + $ns = $this->mTitle->getNamespace(); + } + $title = Title::newFromText( $part1, $ns ); + //used by include size checking + $titleText = $title->getPrefixedText(); + //used by edit section links + $replaceHeadings = true; + } } @@ -3066,6 +3081,9 @@ class Parser $isHTML = true; $this->disableCache(); } + } else if ( $wgNonincludableNamespaces && in_array( $title->getNamespace(), $wgNonincludableNamespaces ) ) { + $found = false; //access denied + wfDebug( "$fname: template inclusion denied for " . $title->getPrefixedDBkey() ); } else { $articleContent = $this->fetchTemplate( $title ); if ( $articleContent !== false ) { @@ -3279,7 +3297,7 @@ class Parser function fetchScaryTemplateMaybeFromCache($url) { global $wgTranscludeCacheExpiry; - $dbr =& wfGetDB(DB_SLAVE); + $dbr = wfGetDB(DB_SLAVE); $obj = $dbr->selectRow('transcache', array('tc_time', 'tc_contents'), array('tc_url' => $url)); if ($obj) { @@ -3294,7 +3312,7 @@ class Parser if (!$text) return wfMsg('scarytranscludefailed', $url); - $dbw =& wfGetDB(DB_MASTER); + $dbw = wfGetDB(DB_MASTER); $dbw->replace('transcache', array('tc_url'), array( 'tc_url' => $url, 'tc_time' => time(), @@ -3437,7 +3455,7 @@ class Parser } # We need this to perform operations on the HTML - $sk =& $this->mOptions->getSkin(); + $sk = $this->mOptions->getSkin(); # headline counter $headlineCount = 0; @@ -3962,12 +3980,12 @@ class Parser $pdbks = array(); $colours = array(); - $sk =& $this->mOptions->getSkin(); + $sk = $this->mOptions->getSkin(); $linkCache =& LinkCache::singleton(); if ( !empty( $this->mLinkHolders['namespaces'] ) ) { wfProfileIn( $fname.'-check' ); - $dbr =& wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE ); $page = $dbr->tableName( 'page' ); $threshold = $wgUser->getOption('stubthreshold'); @@ -4299,6 +4317,7 @@ class Parser */ function renderImageGallery( $text, $params ) { $ig = new ImageGallery(); + $ig->setContextTitle( $this->mTitle ); $ig->setShowBytes( false ); $ig->setShowFilename( false ); $ig->setParsing(); @@ -4310,6 +4329,15 @@ class Parser $caption = $this->replaceInternalLinks( $caption ); $ig->setCaptionHtml( $caption ); } + if( isset( $params['perrow'] ) ) { + $ig->setPerRow( $params['perrow'] ); + } + if( isset( $params['widths'] ) ) { + $ig->setWidths( $params['widths'] ); + } + if( isset( $params['heights'] ) ) { + $ig->setHeights( $params['heights'] ); + } $lines = explode( "\n", $text ); foreach ( $lines as $line ) { @@ -4357,8 +4385,6 @@ class Parser 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 @@ -4368,16 +4394,26 @@ class Parser # * ___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); - + # 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' ); - $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 = ''; @@ -4385,6 +4421,7 @@ class Parser $width = $height = $framed = $thumb = false; $page = null; $manual_thumb = '' ; + $align = $valign = ''; foreach( $part as $val ) { if ( $wgUseImageResize && ! is_null( $mwThumb->matchVariableStartToEnd($val) ) ) { @@ -4393,36 +4430,37 @@ class Parser # 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 && !$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 ) ) { - $width = intval( $m[1] ); - $height = intval( $m[2] ); + } 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 ( isset( $wgDjvuRenderer ) && $wgDjvuRenderer + && ! is_null( $match = $mwPage->matchVariableStartToEnd($val) ) ) { + # Select a page in a multipage document + $page = $match; + } elseif ( $wgUseImageResize && !$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 ) ) { + $width = intval( $m[1] ); + $height = intval( $m[2] ); + } else { + $width = intval($match); + } + } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) { + $framed=true; } else { - $width = intval($match); + $caption = $val; } - } elseif ( ! is_null( $mwFramed->matchVariableStartToEnd($val) ) ) { - $framed=true; - } else { - $caption = $val; } } # Strip bad stuff out of the alt text @@ -4435,8 +4473,8 @@ class Parser $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 ); + $sk = $this->mOptions->getSkin(); + return $sk->makeImageLinkObj( $nt, $caption, $alt, $align, $width, $height, $framed, $thumb, $manual_thumb, $page, $valign ); } /** @@ -4514,24 +4552,6 @@ class Parser $uniq = preg_quote( $this->uniqPrefix(), '/' ); $comment = "(?:$uniq-!--.*?QINU)"; $secs = preg_split( - /* - "/ - ^( - (?:$comment|<\/?noinclude>)* # Initial comments will be stripped - (?: - (=+) # Should this be limited to 6? - .+? # Section title... - \\2 # Ending = count must match start - | - ^ - - .*? - <\/h\\3\s*> - ) - (?:$comment|<\/?noinclude>|\s+)* # Trailing whitespace ok - )$ - /mix", - */ "/ ( ^ @@ -4555,7 +4575,8 @@ class Parser // "Section 0" returns the content before any other section. $rv = $secs[0]; } else { - $rv = ""; + //track missing section, will replace if found. + $rv = $newtext; } } elseif( $mode == "replace" ) { if( $section == 0 ) { @@ -4610,8 +4631,10 @@ class Parser } } } - # reinsert stripped tags - $rv = trim( $stripState->unstripBoth( $rv ) ); + if (is_string($rv)) + # reinsert stripped tags + $rv = trim( $stripState->unstripBoth( $rv ) ); + return $rv; } @@ -4624,13 +4647,14 @@ class Parser * * @param $text String: text to look in * @param $section Integer: section number + * @param $deftext: default to return if section is not found * @return string text of the requested section */ - function getSection( $text, $section ) { - return $this->extractSections( $text, $section, "get" ); + public function getSection( $text, $section, $deftext='' ) { + return $this->extractSections( $text, $section, "get", $deftext ); } - function replaceSection( $oldtext, $section, $text ) { + public function replaceSection( $oldtext, $section, $text ) { return $this->extractSections( $oldtext, $section, "replace", $text ); } @@ -4642,7 +4666,7 @@ class Parser if ( is_null( $this->mRevisionTimestamp ) ) { wfProfileIn( __METHOD__ ); global $wgContLang; - $dbr =& wfGetDB( DB_SLAVE ); + $dbr = wfGetDB( DB_SLAVE ); $timestamp = $dbr->selectField( 'revision', 'rev_timestamp', array( 'rev_id' => $this->mRevisionId ), __METHOD__ ); @@ -4692,6 +4716,9 @@ class Parser } +/** + * @todo document, briefly. + */ class OnlyIncludeReplacer { var $output = ''; @@ -4704,6 +4731,9 @@ class OnlyIncludeReplacer { } } +/** + * @todo document, briefly. + */ class StripState { var $general, $nowiki;