ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
Parser Class Reference
+ Inheritance diagram for Parser:
+ Collaboration diagram for Parser:

Public Member Functions

 __construct ()
 #- More...
 
 firstCallInit ()
 Do various kinds of initialisation on the first call of the parser. More...
 
 clearState ()
 Clear Parser state. More...
 
 setOutputType ($ot)
 
 uniqPrefix ()
 Accessor for mUniqPrefix. More...
 
 parse ($text, &$title, $options, $linestart=true, $clearState=true, $revid=null)
 Convert wikitext to HTML Do not call this function recursively. More...
 
 recursiveTagParse ($text)
 Recursive parser entry point that can be called from an extension tag hook. More...
 
 preprocess ($text, $title, $options)
 Expand templates and variables in the text, producing valid, static wikitext. More...
 
getTitle ()
 
 getOptions ()
 
 getFunctionLang ()
 
 strip ($text, $state, $stripcomments=false, $dontstrip=array())
 Strips and renders nowiki, pre, math, hiero If $render is set, performs necessary rendering operations on plugins Returns the text, and fills an array with data needed in unstrip() More...
 
 unstrip ($text, $state)
 Restores pre, math, and other extensions removed by strip() More...
 
 unstripNoWiki ($text, $state)
 Always call this after unstrip() to preserve the order. More...
 
 unstripForHTML ($text)
 
 insertStripItem ($text, &$state)
 Add an item to the strip state Returns the unique tag which must be inserted into the stripped text The tag will be replaced with the original text in unstrip() More...
 
 doTableStuff ($text)
 parse the wiki syntax used to render tables More...
 
 internalParse ($text)
 Helper function for parse() that transforms wiki markup into HTML. More...
 
doMagicLinks (&$text)
 Replace special strings like "ISBN xxx" and "RFC xxx" with magic external links. More...
 
 magicLinkCallback ($m)
 
 doHeadings ($text)
 Parse headers and return html. More...
 
 doAllQuotes ($text)
 Replace single quotes with HTML markup. More...
 
 doQuotes ($text)
 Helper function for doAllQuotes() More...
 
 replaceExternalLinks ($text)
 Replace external links. More...
 
 replaceFreeExternalLinks ($text)
 Replace anything that looks like a URL with a link. More...
 
 maybeMakeExternalImage ($url)
 make an image if it's allowed, either through the global option or through the exception More...
 
 replaceInternalLinks ($s)
 Process [[ ]] wikilinks. More...
 
 makeLinkHolder (&$nt, $text='', $query='', $trail='', $prefix='')
 Make a link placeholder. More...
 
 makeKnownLinkHolder ($nt, $text='', $query='', $trail='', $prefix='')
 Render a forced-blue link inline; protect against double expansion of URLs if we're in a mode that prepends full URL prefixes to internal links. More...
 
 armorLinks ($text)
 Insert a NOPARSE hacky thing into any inline links in a chunk that's going to go through further parsing steps before inline URL expansion. More...
 
 areSubpagesAllowed ()
 Return true if subpage links should be expanded on this page. More...
 
 maybeDoSubpageLink ($target, &$text)
 Handle link to subpage if necessary. More...
 
 closeParagraph ()
 #+ Used by doBlockLevels() More...
 
 getCommon ($st1, $st2)
 
 openList ($char)
 
 nextItem ($char)
 
 closeList ($char)
 
 doBlockLevels ($text, $linestart)
 #- More...
 
 findColonNoLinks ($str, &$before, &$after)
 Split up a string on ':', ignoring any occurences inside tags to prevent illegal overlapping. More...
 
 getVariableValue ($index)
 Return value of a magic variable (like PAGENAME) More...
 
 initialiseVariables ()
 initialise the magic variables (like CURRENTMONTHNAME) More...
 
 replace_callback ($text, $callbacks)
 parse any parentheses in format ((title|part|part)) and call callbacks to get a replacement text for any found piece More...
 
 replaceVariables ($text, $args=array(), $argsOnly=false)
 Replace magic variables, templates, and template arguments with the appropriate text. More...
 
 variableSubstitution ($matches)
 Replace magic variables. More...
 
 braceSubstitution ($piece)
 Return the text of a template, after recursively replacing any variables or templates within the template. More...
 
 fetchTemplate ($title)
 Fetch the unparsed text of a template and register a reference to it. More...
 
 interwikiTransclude ($title, $action)
 Transclude an interwiki link. More...
 
 fetchScaryTemplateMaybeFromCache ($url)
 
 argSubstitution ($matches)
 Triple brace replacement – used for template arguments. More...
 
 incrementIncludeSize ($type, $size)
 Increment an include size counter. More...
 
 stripNoGallery (&$text)
 Detect NOGALLERY magic word and set a placeholder. More...
 
 stripToc ($text)
 Detect TOC magic word and set a placeholder. More...
 
 formatHeadings ($text, $isMain=true)
 This function accomplishes several tasks: 1) Auto-number headings if that option is enabled 2) Add an [edit] link to sections for logged in users who have enabled the option 3) Add a Table of contents on the top for users who have enabled the option 4) Auto-anchor headings. More...
 
 preSaveTransform ($text, &$title, $user, $options, $clearState=true)
 Transform wiki markup when saving a page by doing
->
conversion, substitting signatures, {{subst:}} templates, etc. More...
 
 pstPass2 ($text, &$stripState, $user)
 Pre-save transform helper function. More...
 
 getUserSig (&$user)
 Fetch the user's signature text, if any, and normalize to validated, ready-to-insert wikitext. More...
 
 validateSig ($text)
 Check that the user's signature contains no bad XML. More...
 
 cleanSig ($text, $parsing=false)
 Clean up signature text. More...
 
 cleanSigInSig ($text)
 Strip ~~~, ~~~~ and ~~~~~ out of signatures. More...
 
 startExternalParse (&$title, $options, $outputType, $clearState=true)
 Set up some variables which are usually set up in parse() so that an external function can call some class members with confidence. More...
 
 transformMsg ($text, $options)
 Transform a MediaWiki message by replacing magic variables. More...
 
 setHook ($tag, $callback)
 Create an HTML-style tag, e.g. More...
 
 setFunctionHook ($id, $callback, $flags=0)
 Create a function, e.g. More...
 
 getFunctionHooks ()
 Get all registered function hook identifiers. More...
 
 replaceLinkHolders (&$text, $options=0)
 Replace link placeholders with actual links, in the buffer Placeholders created in Skin::makeLinkObj() Returns an array of links found, indexed by PDBK: 0 - broken 1 - normal link 2 - stub $options is a bit field, RLH_FOR_UPDATE to select for update. More...
 
 replaceLinkHoldersText ($text)
 Replace link placeholders with plain text of links (not HTML-formatted). More...
 
 replaceLinkHoldersTextCallback ($matches)
 
 renderPreTag ($text, $attribs)
 Tag hook handler for 'pre'. More...
 
 renderImageGallery ($text, $params)
 Renders an image gallery from a text with one line per image. More...
 
 makeImage ($nt, $options)
 Parse image options text and use it to make an image. More...
 
 disableCache ()
 Set a flag in the output object indicating that the content is dynamic and shouldn't be cached. More...
 
 attributeStripCallback (&$text, $args)
 #+ Callback from the Sanitizer for expanding items found in HTML attribute values, so they can be safely tested and escaped. More...
 
 Title ($x=null)
 #- More...
 
 Options ($x=null)
 
 OutputType ($x=null)
 
 getTags ()
 #- More...
 
 getSection ($text, $section, $deftext='')
 This function returns the text of a section, specified by a number ($section). More...
 
 replaceSection ($oldtext, $section, $text)
 
 getRevisionTimestamp ()
 Get the timestamp associated with the current revision, adjusted for the default server-local timestamp. More...
 
 setDefaultSort ($sort)
 Mutator for $mDefaultSort. More...
 
 getDefaultSort ()
 Accessor for $mDefaultSort Will use the title/prefixed title if none is set. More...
 

Static Public Member Functions

 getRandomString ()
 Get a random string. More...
 
 extractTagsAndParams ($elements, $text, &$matches, $uniq_prefix='')
 Replaces all occurrences of HTML-style comments and the given tags in the text with a random marker and returns teh next text. More...
 
 tidy ($text)
 Interface with html tidy, used if $wgUseTidy = true. More...
 
 externalTidy ($text)
 Spawn an external HTML tidy process and get corrected markup back from it. More...
 
 internalTidy ($text)
 Use the HTML tidy PECL extension to use the tidy library in-process, saving the overhead of spawning a new process. More...
 
static replaceUnusualEscapes ($url)
 Replace unusual URL escape codes with their equivalent characters. More...
 
static createAssocArgs ($args)
 Clean up argument array - refactored in 1.9 so parserfunctions can use it, too. More...
 

Data Fields

const VERSION = MW_PARSER_VERSION
 
 $mTagHooks
 #+ More...
 
 $mFunctionHooks
 
 $mFunctionSynonyms
 
 $mVariables
 
 $mOutput
 
 $mAutonumber
 
 $mDTopen
 
 $mStripState
 
 $mIncludeCount
 
 $mArgStack
 
 $mLastSection
 
 $mInPre
 
 $mInterwikiLinkHolders
 
 $mLinkHolders
 
 $mUniqPrefix
 
 $mIncludeSizes
 
 $mDefaultSort
 
 $mTemplates
 
 $mTemplatePath
 
 $mOptions
 
 $mTitle
 
 $mOutputType
 
 $ot
 
 $mRevisionId
 
 $mRevisionTimestamp
 
 $mRevIdForTs
 

Private Member Functions

 extractSections ($text, $section, $mode, $newtext='')
 #- More...
 

Static Private Member Functions

static replaceUnusualEscapesCallback ($matches)
 Callback function used in replaceUnusualEscapes(). More...
 

Detailed Description

Definition at line 90 of file Parser.php.

Constructor & Destructor Documentation

◆ __construct()

Parser::__construct ( )

#-

Constructor

Definition at line 145 of file Parser.php.

148  {
149  $this->mTagHooks = array();
150  $this->mFunctionHooks = array();
151  $this->mFunctionSynonyms = array( 0 => array(), 1 => array() );
Create styles array
The data for the language used.

Member Function Documentation

◆ areSubpagesAllowed()

Parser::areSubpagesAllowed ( )

Return true if subpage links should be expanded on this page.

Returns
bool

Definition at line 1990 of file Parser.php.

Referenced by magicLinkCallback().

1993  {
1994  # Some namespaces don't allow subpages
1995  global $wgNamespacesWithSubpages;
+ Here is the caller graph for this function:

◆ argSubstitution()

Parser::argSubstitution (   $matches)

Triple brace replacement – used for template arguments.

Definition at line 3494 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

3497  {
3498  $arg = trim($matches['title']);
3499  $text = $matches['text'];
3500  $inputArgs = end($this->mArgStack);
3501 
3502  if (array_key_exists($arg, $inputArgs)) {
3503  $text = $inputArgs[$arg];
3504  } elseif (($this->mOutputType == OT_HTML || $this->mOutputType == OT_PREPROCESS) &&
3505  null != $matches['parts'] && count($matches['parts']) > 0) {
3506  $text = $matches['parts'][0];
3507  }
3508  if (!$this->incrementIncludeSize('arg', strlen($text))) {
3509  $text = $matches['text'] .
3510  '<!-- WARNING: argument omitted, expansion size too large -->';
3511  }
3512 
const OT_HTML
Definition: Parser.php:18
incrementIncludeSize($type, $size)
Increment an include size counter.
Definition: Parser.php:3521
$text
Definition: errorreport.php:18
const OT_PREPROCESS
Definition: Parser.php:21
+ Here is the caller graph for this function:

◆ armorLinks()

Parser::armorLinks (   $text)

Insert a NOPARSE hacky thing into any inline links in a chunk that's going to go through further parsing steps before inline URL expansion.

In particular this is important when using action=render, which causes full URLs to be included.

Oh man I hate our multi-layer parser!

Parameters
stringmore-or-less HTML
Returns
string less-or-more HTML with NOPARSE bits

Definition at line 1977 of file Parser.php.

Referenced by magicLinkCallback().

1980  {
1981  return preg_replace(
1982  '/\b(' . wfUrlProtocols() . ')/',
1983  "{$this->mUniqPrefix}NOPARSE$1",
1984  $text
$text
Definition: errorreport.php:18
wfUrlProtocols()
Returns a regular expression of url protocols.
+ Here is the caller graph for this function:

◆ attributeStripCallback()

Parser::attributeStripCallback ( $text,
  $args 
)

#+ Callback from the Sanitizer for expanding items found in HTML attribute values, so they can be safely tested and escaped.

Parameters
string$text
array$args
Returns
string

Definition at line 4712 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

4715  {
4716  $text = $this->replaceVariables($text, $args);
4717  $text = $this->mStripState->unstripBoth($text);
$text
Definition: errorreport.php:18
replaceVariables($text, $args=array(), $argsOnly=false)
Replace magic variables, templates, and template arguments with the appropriate text.
Definition: Parser.php:2921
+ Here is the caller graph for this function:

◆ braceSubstitution()

Parser::braceSubstitution (   $piece)

Return the text of a template, after recursively replacing any variables or templates within the template.

Parameters
array$pieceThe parts of the template $piece['text']: matched text $piece['title']: the title, i.e. the part before the | $piece['parts']: the parameter array
Returns
string the text of the template

Definition at line 3038 of file Parser.php.

Referenced by createAssocArgs().

3041  {
3042  global $wgContLang, $wgLang, $wgAllowDisplayTitle, $wgNonincludableNamespaces;
3043  $fname = __METHOD__ /*. '-L' . count( $this->mArgStack )*/;
3044  wfProfileIn($fname);
3045  wfProfileIn(__METHOD__ . '-setup');
3046 
3047  # Flags
3048  $found = false; # $text has been filled
3049  $nowiki = false; # wiki markup in $text should be escaped
3050  $noparse = false; # Unsafe HTML tags should not be stripped, etc.
3051  $noargs = false; # Don't replace triple-brace arguments in $text
3052  $replaceHeadings = false; # Make the edit section links go to the template not the article
3053  $headingOffset = 0; # Skip headings when number, to account for those that weren't transcluded.
3054  $isHTML = false; # $text is HTML, armour it against wikitext transformation
3055  $forceRawInterwiki = false; # Force interwiki transclusion to be done in raw mode not rendered
3056 
3057  # Title object, where $text came from
3058  $title = null;
3059 
3060  $linestart = '';
3061 
3062 
3063  # $part1 is the bit before the first |, and must contain only title characters
3064  # $args is a list of arguments, starting from index 0, not including $part1
3065 
3066  $titleText = $part1 = $piece['title'];
3067  # If the third subpattern matched anything, it will start with |
3068 
3069  if (null == $piece['parts']) {
3070  $replaceWith = $this->variableSubstitution(array($piece['text'], $piece['title']));
3071  if ($replaceWith != $piece['text']) {
3072  $text = $replaceWith;
3073  $found = true;
3074  $noparse = true;
3075  $noargs = true;
3076  }
3077  }
3078 
3079  $args = (null == $piece['parts']) ? array() : $piece['parts'];
3080  wfProfileOut(__METHOD__ . '-setup');
3081 
3082  # SUBST
3083  wfProfileIn(__METHOD__ . '-modifiers');
3084  if (!$found) {
3085  $mwSubst =&MagicWord::get('subst');
3086  if ($mwSubst->matchStartAndRemove($part1) xor $this->ot['wiki']) {
3087  # One of two possibilities is true:
3088  # 1) Found SUBST but not in the PST phase
3089  # 2) Didn't find SUBST and in the PST phase
3090  # In either case, return without further processing
3091  $text = $piece['text'];
3092  $found = true;
3093  $noparse = true;
3094  $noargs = true;
3095  }
3096  }
3097 
3098  # MSG, MSGNW and RAW
3099  if (!$found) {
3100  # Check for MSGNW:
3101  $mwMsgnw =&MagicWord::get('msgnw');
3102  if ($mwMsgnw->matchStartAndRemove($part1)) {
3103  $nowiki = true;
3104  } else {
3105  # Remove obsolete MSG:
3106  $mwMsg =&MagicWord::get('msg');
3107  $mwMsg->matchStartAndRemove($part1);
3108  }
3109 
3110  # Check for RAW:
3111  $mwRaw =&MagicWord::get('raw');
3112  if ($mwRaw->matchStartAndRemove($part1)) {
3113  $forceRawInterwiki = true;
3114  }
3115  }
3116  wfProfileOut(__METHOD__ . '-modifiers');
3117 
3118  //save path level before recursing into functions & templates.
3119  $lastPathLevel = $this->mTemplatePath;
3120 
3121  # Parser functions
3122  if (!$found) {
3123  wfProfileIn(__METHOD__ . '-pfunc');
3124 
3125  $colonPos = strpos($part1, ':');
3126  if ($colonPos !== false) {
3127  # Case sensitive functions
3128  $function = substr($part1, 0, $colonPos);
3129  if (isset($this->mFunctionSynonyms[1][$function])) {
3130  $function = $this->mFunctionSynonyms[1][$function];
3131  } else {
3132  # Case insensitive functions
3133  $function = strtolower($function);
3134  if (isset($this->mFunctionSynonyms[0][$function])) {
3135  $function = $this->mFunctionSynonyms[0][$function];
3136  } else {
3137  $function = false;
3138  }
3139  }
3140  if ($function) {
3141  $funcArgs = array_map('trim', $args);
3142  $funcArgs = array_merge(array( &$this, trim(substr($part1, $colonPos + 1)) ), $funcArgs);
3143  $result = call_user_func_array($this->mFunctionHooks[$function], $funcArgs);
3144  $found = true;
3145 
3146  // The text is usually already parsed, doesn't need triple-brace tags expanded, etc.
3147  //$noargs = true;
3148  //$noparse = true;
3149 
3150  if (is_array($result)) {
3151  if (isset($result[0])) {
3152  $text = $linestart . $result[0];
3153  unset($result[0]);
3154  }
3155 
3156  // Extract flags into the local scope
3157  // This allows callers to set flags such as nowiki, noparse, found, etc.
3158  extract($result);
3159  } else {
3160  $text = $linestart . $result;
3161  }
3162  }
3163  }
3164  wfProfileOut(__METHOD__ . '-pfunc');
3165  }
3166 
3167  # Template table test
3168 
3169  # Did we encounter this template already? If yes, it is in the cache
3170  # and we need to check for loops.
3171  if (!$found && isset($this->mTemplates[$piece['title']])) {
3172  $found = true;
3173 
3174  # Infinite loop test
3175  if (isset($this->mTemplatePath[$part1])) {
3176  $noparse = true;
3177  $noargs = true;
3178  $found = true;
3179  $text = $linestart .
3180  "[[$part1]]<!-- WARNING: template loop detected -->";
3181  wfDebug(__METHOD__ . ": template loop broken at '$part1'\n");
3182  } else {
3183  # set $text to cached message.
3184  $text = $linestart . $this->mTemplates[$piece['title']];
3185  #treat title for cached page the same as others
3186  $ns = NS_TEMPLATE;
3187  $subpage = '';
3188  $part1 = $this->maybeDoSubpageLink($part1, $subpage);
3189  if ($subpage !== '') {
3190  $ns = $this->mTitle->getNamespace();
3191  }
3192  $title = Title::newFromText($part1, $ns);
3193  //used by include size checking
3194  $titleText = $title->getPrefixedText();
3195  //used by edit section links
3196  $replaceHeadings = true;
3197  }
3198  }
3199 
3200  # Load from database
3201  if (!$found) {
3202  wfProfileIn(__METHOD__ . '-loadtpl');
3203  $ns = NS_TEMPLATE;
3204  # declaring $subpage directly in the function call
3205  # does not work correctly with references and breaks
3206  # {{/subpage}}-style inclusions
3207  $subpage = '';
3208  $part1 = $this->maybeDoSubpageLink($part1, $subpage);
3209  if ($subpage !== '') {
3210  $ns = $this->mTitle->getNamespace();
3211  }
3212  $title = Title::newFromText($part1, $ns);
3213 
3214 
3215  if (!is_null($title)) {
3216  $titleText = $title->getPrefixedText();
3217  # Check for language variants if the template is not found
3218  if ($wgContLang->hasVariants() && $title->getArticleID() == 0) {
3219  $wgContLang->findVariantLink($part1, $title);
3220  }
3221 
3222  if (!$title->isExternal()) {
3223  if ($title->getNamespace() == NS_SPECIAL && $this->mOptions->getAllowSpecialInclusion() && $this->ot['html']) {
3224  $text = SpecialPage::capturePath($title);
3225  if (is_string($text)) {
3226  $found = true;
3227  $noparse = true;
3228  $noargs = true;
3229  $isHTML = true;
3230  $this->disableCache();
3231  }
3232  } elseif ($wgNonincludableNamespaces && in_array($title->getNamespace(), $wgNonincludableNamespaces)) {
3233  $found = false; //access denied
3234  wfDebug("$fname: template inclusion denied for " . $title->getPrefixedDBkey());
3235  } else {
3236  $articleContent = $this->fetchTemplate($title);
3237  if ($articleContent !== false) {
3238  $found = true;
3239  $text = $articleContent;
3240  $replaceHeadings = true;
3241  }
3242  }
3243 
3244  # If the title is valid but undisplayable, make a link to it
3245  if (!$found && ($this->ot['html'] || $this->ot['pre'])) {
3246  $text = "[[:$titleText]]";
3247  $found = true;
3248  }
3249  } elseif ($title->isTrans()) {
3250  // Interwiki transclusion
3251  if ($this->ot['html'] && !$forceRawInterwiki) {
3252  $text = $this->interwikiTransclude($title, 'render');
3253  $isHTML = true;
3254  $noparse = true;
3255  } else {
3256  $text = $this->interwikiTransclude($title, 'raw');
3257  $replaceHeadings = true;
3258  }
3259  $found = true;
3260  }
3261 
3262  # Template cache array insertion
3263  # Use the original $piece['title'] not the mangled $part1, so that
3264  # modifiers such as RAW: produce separate cache entries
3265  if ($found) {
3266  if ($isHTML) {
3267  // A special page; don't store it in the template cache.
3268  } else {
3269  $this->mTemplates[$piece['title']] = $text;
3270  }
3271  $text = $linestart . $text;
3272  }
3273  }
3274  wfProfileOut(__METHOD__ . '-loadtpl');
3275  }
3276 
3277  if ($found && !$this->incrementIncludeSize('pre-expand', strlen($text))) {
3278  # Error, oversize inclusion
3279  $text = $linestart .
3280  "[[$titleText]]<!-- WARNING: template omitted, pre-expand include size too large -->";
3281  $noparse = true;
3282  $noargs = true;
3283  }
3284 
3285  # Recursive parsing, escaping and link table handling
3286  # Only for HTML output
3287  if ($nowiki && $found && ($this->ot['html'] || $this->ot['pre'])) {
3288  $text = wfEscapeWikiText($text);
3289  } elseif (!$this->ot['msg'] && $found) {
3290  if ($noargs) {
3291  $assocArgs = array();
3292  } else {
3293  # Clean up argument array
3294  $assocArgs = self::createAssocArgs($args);
3295  # Add a new element to the templace recursion path
3296  $this->mTemplatePath[$part1] = 1;
3297  }
3298 
3299  if (!$noparse) {
3300  # If there are any <onlyinclude> tags, only include them
3301  if (in_string('<onlyinclude>', $text) && in_string('</onlyinclude>', $text)) {
3302  $replacer = new OnlyIncludeReplacer;
3303  StringUtils::delimiterReplaceCallback(
3304  '<onlyinclude>',
3305  '</onlyinclude>',
3306  array( &$replacer, 'replace' ),
3307  $text
3308  );
3309  $text = $replacer->output;
3310  }
3311  # Remove <noinclude> sections and <includeonly> tags
3312  $text = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $text);
3313  $text = strtr($text, array( '<includeonly>' => '' , '</includeonly>' => '' ));
3314 
3315  if ($this->ot['html'] || $this->ot['pre']) {
3316  # Strip <nowiki>, <pre>, etc.
3317  $text = $this->strip($text, $this->mStripState);
3318  if ($this->ot['html']) {
3319  $text = Sanitizer::removeHTMLtags($text, array( &$this, 'replaceVariables' ), $assocArgs);
3320  } elseif ($this->ot['pre'] && $this->mOptions->getRemoveComments()) {
3322  }
3323  }
3324  $text = $this->replaceVariables($text, $assocArgs);
3325 
3326  # If the template begins with a table or block-level
3327  # element, it should be treated as beginning a new line.
3328  if (!$piece['lineStart'] && preg_match('/^(?:{\\||:|;|#|\*)/', $text)) /*}*/{
3329  $text = "\n" . $text;
3330  }
3331  } elseif (!$noargs) {
3332  # $noparse and !$noargs
3333  # Just replace the arguments, not any double-brace items
3334  # This is used for rendered interwiki transclusion
3335  $text = $this->replaceVariables($text, $assocArgs, true);
3336  }
3337  }
3338  # Prune lower levels off the recursion check path
3339  $this->mTemplatePath = $lastPathLevel;
3340 
3341  if ($found && !$this->incrementIncludeSize('post-expand', strlen($text))) {
3342  # Error, oversize inclusion
3343  $text = $linestart .
3344  "[[$titleText]]<!-- WARNING: template omitted, post-expand include size too large -->";
3345  $noparse = true;
3346  $noargs = true;
3347  }
3348 
3349  if (!$found) {
3350  wfProfileOut($fname);
3351  return $piece['text'];
3352  } else {
3353  wfProfileIn(__METHOD__ . '-placeholders');
3354  if ($isHTML) {
3355  # Replace raw HTML by a placeholder
3356  # Add a blank line preceding, to prevent it from mucking up
3357  # immediately preceding headings
3358  $text = "\n\n" . $this->insertStripItem($text, $this->mStripState);
3359  } else {
3360  # replace ==section headers==
3361  # XXX this needs to go away once we have a better parser.
3362  if (!$this->ot['wiki'] && !$this->ot['pre'] && $replaceHeadings) {
3363  if (!is_null($title)) {
3364  $encodedname = base64_encode($title->getPrefixedDBkey());
3365  } else {
3366  $encodedname = base64_encode("");
3367  }
3368  $m = preg_split(
3369  '/(^={1,6}.*?={1,6}\s*?$)/m',
3370  $text,
3371  -1,
3372  PREG_SPLIT_DELIM_CAPTURE
3373  );
3374  $text = '';
3375  $nsec = $headingOffset;
3376  for ($i = 0; $i < count($m); $i += 2) {
3377  $text .= $m[$i];
3378  if (!isset($m[$i + 1]) || $m[$i + 1] == "") {
3379  continue;
3380  }
3381  $hl = $m[$i + 1];
3382  if (strstr($hl, "<!--MWTEMPLATESECTION")) {
3383  $text .= $hl;
3384  continue;
3385  }
3386  $m2 = array();
3387  preg_match('/^(={1,6})(.*?)(={1,6})\s*?$/m', $hl, $m2);
3388  $text .= $m2[1] . $m2[2] . "<!--MWTEMPLATESECTION="
3389  . $encodedname . "&" . base64_encode("$nsec") . "-->" . $m2[3];
3390 
3391  $nsec++;
3392  }
3393  }
3394  }
3395  wfProfileOut(__METHOD__ . '-placeholders');
3396  }
3397 
3398  # Prune lower levels off the recursion check path
3399  $this->mTemplatePath = $lastPathLevel;
3400 
3401  if (!$found) {
3402  wfProfileOut($fname);
3403  return $piece['text'];
3404  } else {
3405  wfProfileOut($fname);
3406  return $text;
File written to
Sum of both Ranges is
Definition: 03formulas.php:77
$result
interwikiTransclude($title, $action)
Transclude an interwiki link.
Definition: Parser.php:3443
$mTemplatePath
Definition: Parser.php:119
static newFromText($text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:124
maybeDoSubpageLink($target, &$text)
Handle link to subpage if necessary.
Definition: Parser.php:2004
insertStripItem($text, &$state)
Add an item to the strip state Returns the unique tag which must be inserted into the stripped text T...
Definition: Parser.php:720
disableCache()
Set a flag in the output object indicating that the content is dynamic and shouldn&#39;t be cached...
Definition: Parser.php:4698
static removeHTMLtags($text, $processCallback=null, $args=array())
Cleans up HTML, removes dangerous tags and attributes, and removes HTML comments. ...
Definition: Sanitizer.php:343
variableSubstitution($matches)
Replace magic variables.
Definition: Parser.php:2968
incrementIncludeSize($type, $size)
Increment an include size counter.
Definition: Parser.php:3521
const NS_SPECIAL
Definition: Title.php:16
$text
Definition: errorreport.php:18
fetchTemplate($title)
Fetch the unparsed text of a template and register a reference to it.
Definition: Parser.php:3411
Create styles array
The data for the language used.
replaceVariables($text, $args=array(), $argsOnly=false)
Replace magic variables, templates, and template arguments with the appropriate text.
Definition: Parser.php:2921
strip($text, $state, $stripcomments=false, $dontstrip=array())
Strips and renders nowiki, pre, math, hiero If $render is set, performs necessary rendering operation...
Definition: Parser.php:570
$function
Definition: cas.php:28
$i
Definition: disco.tpl.php:19
static removeHTMLcomments($text)
Remove &#39;&#39;, and everything between.
Definition: Sanitizer.php:533
+ Here is the caller graph for this function:

◆ cleanSig()

Parser::cleanSig (   $text,
  $parsing = false 
)

Clean up signature text.

1) Strip ~~~, ~~~~ and ~~~~~ out of signatures

See also
cleanSigInSig 2) Substitute all transclusions
Parameters
string$text
$parsingWhether we're cleaning (preferences save) or parsing
Returns
string Signature text

Definition at line 3984 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

3987  {
3988  global $wgTitle;
3989  $this->startExternalParse($wgTitle, new ParserOptions(), $parsing ? OT_WIKI : OT_MSG);
3990 
3991  $substWord = MagicWord::get('subst');
3992  $substRegex = '/\{\{(?!(?:' . $substWord->getBaseRegex() . '))/x' . $substWord->getRegexCase();
3993  $substText = '{{' . $substWord->getSynonym(0);
3994 
3995  $text = preg_replace($substRegex, $substText, $text);
3996  $text = $this->cleanSigInSig($text);
3997  $text = $this->replaceVariables($text);
3998 
3999  $this->clearState();
clearState()
Clear Parser state.
Definition: Parser.php:211
startExternalParse(&$title, $options, $outputType, $clearState=true)
Set up some variables which are usually set up in parse() so that an external function can call some ...
Definition: Parser.php:4017
const OT_WIKI
Definition: Parser.php:19
$text
Definition: errorreport.php:18
const OT_MSG
Definition: Parser.php:20
replaceVariables($text, $args=array(), $argsOnly=false)
Replace magic variables, templates, and template arguments with the appropriate text.
Definition: Parser.php:2921
cleanSigInSig($text)
Strip ~~~, ~~~~ and ~~~~~ out of signatures.
Definition: Parser.php:4006
+ Here is the caller graph for this function:

◆ cleanSigInSig()

Parser::cleanSigInSig (   $text)

Strip ~~~, ~~~~ and ~~~~~ out of signatures.

Parameters
string$text
Returns
string Signature text with /~{3,5}/ removed

Definition at line 4006 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

4006  {3,5}/ removed
4007  */
4008  public function cleanSigInSig($text)
4009  {
4010  $text = preg_replace('/~{3,5}/', '', $text);
$text
Definition: errorreport.php:18
cleanSigInSig($text)
Strip ~~~, ~~~~ and ~~~~~ out of signatures.
Definition: Parser.php:4006
+ Here is the caller graph for this function:

◆ clearState()

Parser::clearState ( )

Clear Parser state.

Prefix for temporary replacement strings for the multipass parser. should never appear in input as it's disallowed in XML. Using it at the front also gives us a little extra robustness since it shouldn't match when butted up against identifier-like string constructs.

Definition at line 211 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache(), and setOutputType().

214  {
215  wfProfileIn(__METHOD__);
216  if ($this->mFirstCall) {
217  $this->firstCallInit();
218  }
219  $this->mOutput = new ParserOutput;
220  $this->mAutonumber = 0;
221  $this->mLastSection = '';
222  $this->mDTopen = false;
223  $this->mIncludeCount = array();
224  $this->mStripState = new StripState;
225  $this->mArgStack = array();
226  $this->mInPre = false;
227  $this->mInterwikiLinkHolders = array(
228  'texts' => array(),
229  'titles' => array()
230  );
231  $this->mLinkHolders = array(
232  'namespaces' => array(),
233  'dbkeys' => array(),
234  'queries' => array(),
235  'texts' => array(),
236  'titles' => array()
237  );
238  $this->mRevisionTimestamp = $this->mRevisionId = null;
239 
247  $this->mUniqPrefix = "\x07UNIQ" . Parser::getRandomString();
248 
249  # Clear these on every parse, bug 4549
250  $this->mTemplates = array();
251  $this->mTemplatePath = array();
252 
253  $this->mShowToc = true;
254  $this->mForceTocPosition = false;
255  $this->mIncludeSizes = array(
256  'pre-expand' => 0,
257  'post-expand' => 0,
258  'arg' => 0
259  );
260  $this->mDefaultSort = false;
261 
262  wfRunHooks('ParserClearState', array( &$this ));
firstCallInit()
Do various kinds of initialisation on the first call of the parser.
Definition: Parser.php:156
Create styles array
The data for the language used.
getRandomString()
Get a random string.
Definition: Parser.php:452
+ Here is the caller graph for this function:

◆ closeList()

Parser::closeList (   $char)

Definition at line 2145 of file Parser.php.

References $i, $id, $index, $mRevisionId, $output, $ret, $rule, $state, $t, $text, array, closeParagraph(), date, doBlockLevels(), findColonNoLinks(), getCommon(), getRevisionTimestamp(), getVariableValue(), images, initialiseVariables(), MW_COLON_STATE_CLOSETAG, MW_COLON_STATE_COMMENT, MW_COLON_STATE_COMMENTDASH, MW_COLON_STATE_COMMENTDASHDASH, MW_COLON_STATE_TAG, MW_COLON_STATE_TAGSLASH, MW_COLON_STATE_TAGSTART, MW_COLON_STATE_TEXT, nextItem(), openList(), OT_MSG, OT_WIKI, replace_callback(), replaceVariables(), time, and variableSubstitution().

2148  {
2149  if ('*' == $char) {
2150  $text = '</li></ul>';
2151  } elseif ('#' == $char) {
2152  $text = '</li></ol>';
2153  } elseif (':' == $char) {
2154  if ($this->mDTopen) {
2155  $this->mDTopen = false;
2156  $text = '</dt></dl>';
2157  } else {
2158  $text = '</dd></dl>';
2159  }
2160  } else {
2161  return '<!-- ERR 3 -->';
2162  }
$text
Definition: errorreport.php:18
+ Here is the call graph for this function:

◆ closeParagraph()

Parser::closeParagraph ( )

#+ Used by doBlockLevels()

Definition at line 2074 of file Parser.php.

Referenced by closeList(), magicLinkCallback(), and openList().

2077  {
2078  $result = '';
2079  if ('' != $this->mLastSection) {
2080  $result = '</' . $this->mLastSection . ">\n";
2081  }
2082  $this->mInPre = false;
2083  $this->mLastSection = '';
$result
+ Here is the caller graph for this function:

◆ createAssocArgs()

static Parser::createAssocArgs (   $args)
static

Clean up argument array - refactored in 1.9 so parserfunctions can use it, too.

Definition at line 3004 of file Parser.php.

References $action, $function, $i, $index, $m, $message, $mTemplatePath, $name, $result, $text, $title, $url, array, braceSubstitution(), disableCache(), fetchScaryTemplateMaybeFromCache(), fetchTemplate(), incrementIncludeSize(), insertStripItem(), interwikiTransclude(), is, maybeDoSubpageLink(), Title\newFromRedirect(), Title\newFromText(), NS_SPECIAL, Sanitizer\removeHTMLcomments(), Sanitizer\removeHTMLtags(), replaceVariables(), strip(), to, variableSubstitution(), and wfMsg().

3007  {
3008  $assocArgs = array();
3009  $index = 1;
3010  foreach ($args as $arg) {
3011  $eqpos = strpos($arg, '=');
3012  if ($eqpos === false) {
3013  $assocArgs[$index++] = $arg;
3014  } else {
3015  $name = trim(substr($arg, 0, $eqpos));
3016  $value = trim(substr($arg, $eqpos+1));
3017  if ($value === false) {
3018  $value = '';
3019  }
3020  if ($name !== false) {
3021  $assocArgs[$name] = $value;
3022  }
3023  }
3024  }
3025 
$index
Definition: metadata.php:60
if($format !==null) $name
Definition: metadata.php:146
Create styles array
The data for the language used.
+ Here is the call graph for this function:

◆ disableCache()

Parser::disableCache ( )

Set a flag in the output object indicating that the content is dynamic and shouldn't be cached.

Definition at line 4698 of file Parser.php.

Referenced by createAssocArgs(), and fetchScaryTemplateMaybeFromCache().

4701  {
4702  wfDebug("Parser output marked as uncacheable.\n");
+ Here is the caller graph for this function:

◆ doAllQuotes()

Parser::doAllQuotes (   $text)

Replace single quotes with HTML markup.

Returns
string the altered text

Definition at line 1176 of file Parser.php.

Referenced by magicLinkCallback().

1179  {
1180  $fname = 'Parser::doAllQuotes';
1181  wfProfileIn($fname);
1182  $outtext = '';
1183  $lines = explode("\n", $text);
1184  foreach ($lines as $line) {
1185  $outtext .= $this->doQuotes($line) . "\n";
1186  }
1187  $outtext = substr($outtext, 0, -1);
1188  wfProfileOut($fname);
doQuotes($text)
Helper function for doAllQuotes()
Definition: Parser.php:1194
$text
Definition: errorreport.php:18
+ Here is the caller graph for this function:

◆ doBlockLevels()

Parser::doBlockLevels (   $text,
  $linestart 
)

#-

Make lists from lines starting with ':', '*', '#', etc.

Returns
string the lists rendered as HTML

Definition at line 2171 of file Parser.php.

Referenced by closeList(), and setOutputType().

2174  {
2175  $fname = 'Parser::doBlockLevels';
2176  wfProfileIn($fname);
2177 
2178  # Parsing through the text line by line. The main thing
2179  # happening here is handling of block-level elements p, pre,
2180  # and making lists from lines starting with * # : etc.
2181  #
2182  $textLines = explode("\n", $text);
2183 
2184  $lastPrefix = $output = '';
2185  $this->mDTopen = $inBlockElem = false;
2186  $prefixLength = 0;
2187  $paragraphStack = false;
2188 
2189  if (!$linestart) {
2190  $output .= array_shift($textLines);
2191  }
2192  foreach ($textLines as $oLine) {
2193  $lastPrefixLength = strlen($lastPrefix);
2194  $preCloseMatch = preg_match('/<\\/pre/i', $oLine);
2195  $preOpenMatch = preg_match('/<pre/i', $oLine);
2196  if (!$this->mInPre) {
2197  # Multiple prefixes may abut each other for nested lists.
2198  $prefixLength = strspn($oLine, '*#:;');
2199  $pref = substr($oLine, 0, $prefixLength);
2200 
2201  # eh?
2202  $pref2 = str_replace(';', ':', $pref);
2203  $t = substr($oLine, $prefixLength);
2204  $this->mInPre = !empty($preOpenMatch);
2205  } else {
2206  # Don't interpret any other prefixes in preformatted text
2207  $prefixLength = 0;
2208  $pref = $pref2 = '';
2209  $t = $oLine;
2210  }
2211 
2212  # List generation
2213  if ($prefixLength && 0 == strcmp($lastPrefix, $pref2)) {
2214  # Same as the last item, so no need to deal with nesting or opening stuff
2215  $output .= $this->nextItem(substr($pref, -1));
2216  $paragraphStack = false;
2217 
2218  if (substr($pref, -1) == ';') {
2219  # The one nasty exception: definition lists work like this:
2220  # ; title : definition text
2221  # So we check for : in the remainder text to split up the
2222  # title and definition, without b0rking links.
2223  $term = $t2 = '';
2224  if ($this->findColonNoLinks($t, $term, $t2) !== false) {
2225  $t = $t2;
2226  $output .= $term . $this->nextItem(':');
2227  }
2228  }
2229  } elseif ($prefixLength || $lastPrefixLength) {
2230  # Either open or close a level...
2231  $commonPrefixLength = $this->getCommon($pref, $lastPrefix);
2232  $paragraphStack = false;
2233 
2234  while ($commonPrefixLength < $lastPrefixLength) {
2235  $output .= $this->closeList($lastPrefix{$lastPrefixLength-1});
2236  --$lastPrefixLength;
2237  }
2238  if ($prefixLength <= $commonPrefixLength && $commonPrefixLength > 0) {
2239  $output .= $this->nextItem($pref{$commonPrefixLength-1});
2240  }
2241  while ($prefixLength > $commonPrefixLength) {
2242  $char = substr($pref, $commonPrefixLength, 1);
2243  $output .= $this->openList($char);
2244 
2245  if (';' == $char) {
2246  # FIXME: This is dupe of code above
2247  if ($this->findColonNoLinks($t, $term, $t2) !== false) {
2248  $t = $t2;
2249  $output .= $term . $this->nextItem(':');
2250  }
2251  }
2252  ++$commonPrefixLength;
2253  }
2254  $lastPrefix = $pref2;
2255  }
2256  if (0 == $prefixLength) {
2257  wfProfileIn("$fname-paragraph");
2258  # No prefix (not in list)--go to paragraph mode
2259  // XXX: use a stack for nestable elements like span, table and div
2260  $openmatch = preg_match('/(?:<table|<blockquote|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|<p|<ul|<ol|<li|<\\/tr|<\\/td|<\\/th)/iS', $t);
2261  $closematch = preg_match(
2262  '/(?:<\\/table|<\\/blockquote|<\\/h1|<\\/h2|<\\/h3|<\\/h4|<\\/h5|<\\/h6|' .
2263  '<td|<th|<\\/?div|<hr|<\\/pre|<\\/p|' . $this->mUniqPrefix . '-pre|<\\/li|<\\/ul|<\\/ol|<\\/?center)/iS',
2264  $t
2265  );
2266  if ($openmatch or $closematch) {
2267  $paragraphStack = false;
2268  # TODO bug 5718: paragraph closed
2269  $output .= $this->closeParagraph();
2270  if ($preOpenMatch and !$preCloseMatch) {
2271  $this->mInPre = true;
2272  }
2273  if ($closematch) {
2274  $inBlockElem = false;
2275  } else {
2276  $inBlockElem = true;
2277  }
2278  } elseif (!$inBlockElem && !$this->mInPre) {
2279  if (' ' == $t{0} and ($this->mLastSection == 'pre' or trim($t) != '')) {
2280  // pre
2281  if ($this->mLastSection != 'pre') {
2282  $paragraphStack = false;
2283  $output .= $this->closeParagraph() . '<pre>';
2284  $this->mLastSection = 'pre';
2285  }
2286  $t = substr($t, 1);
2287  } else {
2288  // paragraph
2289  if ('' == trim($t)) {
2290  if ($paragraphStack) {
2291  $output .= $paragraphStack . '<br />';
2292  $paragraphStack = false;
2293  $this->mLastSection = 'p';
2294  } else {
2295  if ($this->mLastSection != 'p') {
2296  $output .= $this->closeParagraph();
2297  $this->mLastSection = '';
2298  $paragraphStack = '<p>';
2299  } else {
2300  $paragraphStack = '</p><p>';
2301  }
2302  }
2303  } else {
2304  if ($paragraphStack) {
2305  $output .= $paragraphStack;
2306  $paragraphStack = false;
2307  $this->mLastSection = 'p';
2308  } elseif ($this->mLastSection != 'p') {
2309  $output .= $this->closeParagraph() . '<p>';
2310  $this->mLastSection = 'p';
2311  }
2312  }
2313  }
2314  }
2315  wfProfileOut("$fname-paragraph");
2316  }
2317  // somewhere above we forget to get out of pre block (bug 785)
2318  if ($preCloseMatch && $this->mInPre) {
2319  $this->mInPre = false;
2320  }
2321  if ($paragraphStack === false) {
2322  $output .= $t . "\n";
2323  }
2324  }
2325  while ($prefixLength) {
2326  $output .= $this->closeList($pref2{$prefixLength-1});
2327  --$prefixLength;
2328  }
2329  if ('' != $this->mLastSection) {
2330  $output .= '</' . $this->mLastSection . '>';
2331  $this->mLastSection = '';
2332  }
2333 
2334  wfProfileOut($fname);
findColonNoLinks($str, &$before, &$after)
Split up a string on &#39;:&#39;, ignoring any occurences inside tags to prevent illegal overlapping.
Definition: Parser.php:2344
openList($char)
Definition: Parser.php:2105
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\+" &#(? foreach( $entity_files as $file) $output
closeList($char)
Definition: Parser.php:2145
closeParagraph()
#+ Used by doBlockLevels()
Definition: Parser.php:2074
nextItem($char)
Definition: Parser.php:2125
$text
Definition: errorreport.php:18
getCommon($st1, $st2)
Definition: Parser.php:2087
+ Here is the caller graph for this function:

◆ doHeadings()

Parser::doHeadings (   $text)

Parse headers and return html.

Definition at line 1155 of file Parser.php.

Referenced by magicLinkCallback().

1158  {
1159  $fname = 'Parser::doHeadings';
1160  wfProfileIn($fname);
1161  for ($i = 6; $i >= 1; --$i) {
1162  $h = str_repeat('=', $i);
1163  $text = preg_replace(
1164  "/^{$h}(.+){$h}\\s*$/m",
1165  "<h{$i}>\\1</h{$i}>\\2",
1166  $text
1167  );
1168  }
1169  wfProfileOut($fname);
$h
$text
Definition: errorreport.php:18
$i
Definition: disco.tpl.php:19
+ Here is the caller graph for this function:

◆ doMagicLinks()

& Parser::doMagicLinks ( $text)

Replace special strings like "ISBN xxx" and "RFC xxx" with magic external links.

Definition at line 1091 of file Parser.php.

1094  {
1095  wfProfileIn(__METHOD__);
1096  $text = preg_replace_callback(
1097  '!(?: # Start cases
1098  <a.*?</a> | # Skip link text
1099  <.*?> | # Skip stuff inside HTML elements
1100  (?:RFC|PMID)\s+([0-9]+) | # RFC or PMID, capture number as m[1]
1101  ISBN\s+(\b # ISBN, capture number as m[2]
1102  (?: 97[89] [\ \-]? )? # optional 13-digit ISBN prefix
1103  (?: [0-9] [\ \-]? ){9} # 9 digits with opt. delimiters
1104  [0-9Xx] # check digit
1105  \b)
1106  )!x',
1107  array( &$this, 'magicLinkCallback' ),
1108  $text
1109  );
1110  wfProfileOut(__METHOD__);
$text
Definition: errorreport.php:18
Create styles array
The data for the language used.

◆ doQuotes()

Parser::doQuotes (   $text)

Helper function for doAllQuotes()

Definition at line 1194 of file Parser.php.

Referenced by magicLinkCallback().

1197  {
1198  $arr = preg_split("/(''+)/", $text, -1, PREG_SPLIT_DELIM_CAPTURE);
1199  if (count($arr) == 1) {
1200  return $text;
1201  } else {
1202  # First, do some preliminary work. This may shift some apostrophes from
1203  # being mark-up to being text. It also counts the number of occurrences
1204  # of bold and italics mark-ups.
1205  $i = 0;
1206  $numbold = 0;
1207  $numitalics = 0;
1208  foreach ($arr as $r) {
1209  if (($i % 2) == 1) {
1210  # If there are ever four apostrophes, assume the first is supposed to
1211  # be text, and the remaining three constitute mark-up for bold text.
1212  if (strlen($arr[$i]) == 4) {
1213  $arr[$i-1] .= "'";
1214  $arr[$i] = "'''";
1215  }
1216  # If there are more than 5 apostrophes in a row, assume they're all
1217  # text except for the last 5.
1218  elseif (strlen($arr[$i]) > 5) {
1219  $arr[$i-1] .= str_repeat("'", strlen($arr[$i]) - 5);
1220  $arr[$i] = "'''''";
1221  }
1222  # Count the number of occurrences of bold and italics mark-ups.
1223  # We are not counting sequences of five apostrophes.
1224  if (strlen($arr[$i]) == 2) {
1225  $numitalics++;
1226  } elseif (strlen($arr[$i]) == 3) {
1227  $numbold++;
1228  } elseif (strlen($arr[$i]) == 5) {
1229  $numitalics++;
1230  $numbold++;
1231  }
1232  }
1233  $i++;
1234  }
1235 
1236  # If there is an odd number of both bold and italics, it is likely
1237  # that one of the bold ones was meant to be an apostrophe followed
1238  # by italics. Which one we cannot know for certain, but it is more
1239  # likely to be one that has a single-letter word before it.
1240  if (($numbold % 2 == 1) && ($numitalics % 2 == 1)) {
1241  $i = 0;
1242  $firstsingleletterword = -1;
1243  $firstmultiletterword = -1;
1244  $firstspace = -1;
1245  foreach ($arr as $r) {
1246  if (($i % 2 == 1) and (strlen($r) == 3)) {
1247  $x1 = substr($arr[$i-1], -1);
1248  $x2 = substr($arr[$i-1], -2, 1);
1249  if ($x1 == ' ') {
1250  if ($firstspace == -1) {
1251  $firstspace = $i;
1252  }
1253  } elseif ($x2 == ' ') {
1254  if ($firstsingleletterword == -1) {
1255  $firstsingleletterword = $i;
1256  }
1257  } else {
1258  if ($firstmultiletterword == -1) {
1259  $firstmultiletterword = $i;
1260  }
1261  }
1262  }
1263  $i++;
1264  }
1265 
1266  # If there is a single-letter word, use it!
1267  if ($firstsingleletterword > -1) {
1268  $arr [ $firstsingleletterword ] = "''";
1269  $arr [ $firstsingleletterword-1 ] .= "'";
1270  }
1271  # If not, but there's a multi-letter word, use that one.
1272  elseif ($firstmultiletterword > -1) {
1273  $arr [ $firstmultiletterword ] = "''";
1274  $arr [ $firstmultiletterword-1 ] .= "'";
1275  }
1276  # ... otherwise use the first one that has neither.
1277  # (notice that it is possible for all three to be -1 if, for example,
1278  # there is only one pentuple-apostrophe in the line)
1279  elseif ($firstspace > -1) {
1280  $arr [ $firstspace ] = "''";
1281  $arr [ $firstspace-1 ] .= "'";
1282  }
1283  }
1284 
1285  # Now let's actually convert our apostrophic mush to HTML!
1286  $output = '';
1287  $buffer = '';
1288  $state = '';
1289  $i = 0;
1290  foreach ($arr as $r) {
1291  if (($i % 2) == 0) {
1292  if ($state == 'both') {
1293  $buffer .= $r;
1294  } else {
1295  $output .= $r;
1296  }
1297  } else {
1298  if (strlen($r) == 2) {
1299  if ($state == 'i') {
1300  $output .= '</i>';
1301  $state = '';
1302  } elseif ($state == 'bi') {
1303  $output .= '</i>';
1304  $state = 'b';
1305  } elseif ($state == 'ib') {
1306  $output .= '</b></i><b>';
1307  $state = 'b';
1308  } elseif ($state == 'both') {
1309  $output .= '<b><i>' . $buffer . '</i>';
1310  $state = 'b';
1311  } else { # $state can be 'b' or ''
1312  $output .= '<i>';
1313  $state .= 'i';
1314  }
1315  } elseif (strlen($r) == 3) {
1316  if ($state == 'b') {
1317  $output .= '</b>';
1318  $state = '';
1319  } elseif ($state == 'bi') {
1320  $output .= '</i></b><i>';
1321  $state = 'i';
1322  } elseif ($state == 'ib') {
1323  $output .= '</b>';
1324  $state = 'i';
1325  } elseif ($state == 'both') {
1326  $output .= '<i><b>' . $buffer . '</b>';
1327  $state = 'i';
1328  } else { # $state can be 'i' or ''
1329  $output .= '<b>';
1330  $state .= 'b';
1331  }
1332  } elseif (strlen($r) == 5) {
1333  if ($state == 'b') {
1334  $output .= '</b><i>';
1335  $state = 'i';
1336  } elseif ($state == 'i') {
1337  $output .= '</i><b>';
1338  $state = 'b';
1339  } elseif ($state == 'bi') {
1340  $output .= '</i></b>';
1341  $state = '';
1342  } elseif ($state == 'ib') {
1343  $output .= '</b></i>';
1344  $state = '';
1345  } elseif ($state == 'both') {
1346  $output .= '<i><b>' . $buffer . '</b></i>';
1347  $state = '';
1348  } else { # ($state == '')
1349  $buffer = '';
1350  $state = 'both';
1351  }
1352  }
1353  }
1354  $i++;
1355  }
1356  # Now close all remaining tags. Notice that the order is important.
1357  if ($state == 'b' || $state == 'ib') {
1358  $output .= '</b>';
1359  }
1360  if ($state == 'i' || $state == 'bi' || $state == 'ib') {
1361  $output .= '</i>';
1362  }
1363  if ($state == 'bi') {
1364  $output .= '</b>';
1365  }
1366  # There might be lonely ''''', so make sure we have a buffer
1367  if ($state == 'both' && $buffer) {
1368  $output .= '<b><i>' . $buffer . '</i></b>';
1369  }
1370  return $output;
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\+" &#(? foreach( $entity_files as $file) $output
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Definition: linkback.php:10
$r
Definition: example_031.php:79
$text
Definition: errorreport.php:18
$i
Definition: disco.tpl.php:19
+ Here is the caller graph for this function:

◆ doTableStuff()

Parser::doTableStuff (   $text)

parse the wiki syntax used to render tables

Definition at line 843 of file Parser.php.

846  {
847  $fname = 'Parser::doTableStuff';
848  wfProfileIn($fname);
849 
850  $lines = explode("\n", $text);
851  $td_history = array(); // Is currently a td tag open?
852  $last_tag_history = array(); // Save history of last lag activated (td, th or caption)
853  $tr_history = array(); // Is currently a tr tag open?
854  $tr_attributes = array(); // history of tr attributes
855  $has_opened_tr = array(); // Did this table open a <tr> element?
856  $indent_level = 0; // indent level of the table
857  foreach ($lines as $key => $line) {
858  $line = trim($line);
859 
860  if ($line == '') { // empty line, go to next line
861  continue;
862  }
863  $first_character = $line{0};
864  $matches = array();
865 
866  if (preg_match('/^(:*)\{\|(.*)$/', $line, $matches)) {
867  // First check if we are starting a new table
868  $indent_level = strlen($matches[1]);
869 
870  $attributes = $this->mStripState->unstripBoth($matches[2]);
872 
873  $lines[$key] = str_repeat('<dl><dd>', $indent_level) . "<table{$attributes}>";
874  array_push($td_history, false);
875  array_push($last_tag_history, '');
876  array_push($tr_history, false);
877  array_push($tr_attributes, '');
878  array_push($has_opened_tr, false);
879  } elseif (count($td_history) == 0) {
880  // Don't do any of the following
881  continue;
882  } elseif (substr($line, 0, 2) == '|}') {
883  // We are ending a table
884  $line = '</table>' . substr($line, 2);
885  $last_tag = array_pop($last_tag_history);
886 
887  if (!array_pop($has_opened_tr)) {
888  $line = "<tr><td></td></tr>{$line}";
889  }
890 
891  if (array_pop($tr_history)) {
892  $line = "</tr>{$line}";
893  }
894 
895  if (array_pop($td_history)) {
896  $line = "</{$last_tag}>{$line}";
897  }
898  array_pop($tr_attributes);
899  $lines[$key] = $line . str_repeat('</dd></dl>', $indent_level);
900  } elseif (substr($line, 0, 2) == '|-') {
901  // Now we have a table row
902  $line = preg_replace('#^\|-+#', '', $line);
903 
904  // Whats after the tag is now only attributes
905  $attributes = $this->mStripState->unstripBoth($line);
907  array_pop($tr_attributes);
908  array_push($tr_attributes, $attributes);
909 
910  $line = '';
911  $last_tag = array_pop($last_tag_history);
912  array_pop($has_opened_tr);
913  array_push($has_opened_tr, true);
914 
915  if (array_pop($tr_history)) {
916  $line = '</tr>';
917  }
918 
919  if (array_pop($td_history)) {
920  $line = "</{$last_tag}>{$line}";
921  }
922 
923  $lines[$key] = $line;
924  array_push($tr_history, false);
925  array_push($td_history, false);
926  array_push($last_tag_history, '');
927  } elseif ($first_character == '|' || $first_character == '!' || substr($line, 0, 2) == '|+') {
928  // This might be cell elements, td, th or captions
929  if (substr($line, 0, 2) == '|+') {
930  $first_character = '+';
931  $line = substr($line, 1);
932  }
933 
934  $line = substr($line, 1);
935 
936  if ($first_character == '!') {
937  $line = str_replace('!!', '||', $line);
938  }
939 
940  // Split up multiple cells on the same line.
941  // FIXME : This can result in improper nesting of tags processed
942  // by earlier parser steps, but should avoid splitting up eg
943  // attribute values containing literal "||".
944  $cells = StringUtils::explodeMarkup('||', $line);
945 
946  $lines[$key] = '';
947 
948  // Loop through each table cell
949  foreach ($cells as $cell) {
950  $previous = '';
951  if ($first_character != '+') {
952  $tr_after = array_pop($tr_attributes);
953  if (!array_pop($tr_history)) {
954  $previous = "<tr{$tr_after}>\n";
955  }
956  array_push($tr_history, true);
957  array_push($tr_attributes, '');
958  array_pop($has_opened_tr);
959  array_push($has_opened_tr, true);
960  }
961 
962  $last_tag = array_pop($last_tag_history);
963 
964  if (array_pop($td_history)) {
965  $previous = "</{$last_tag}>{$previous}";
966  }
967 
968  if ($first_character == '|') {
969  $last_tag = 'td';
970  } elseif ($first_character == '!') {
971  $last_tag = 'th';
972  } elseif ($first_character == '+') {
973  $last_tag = 'caption';
974  } else {
975  $last_tag = '';
976  }
977 
978  array_push($last_tag_history, $last_tag);
979 
980  // A cell could contain both parameters and data
981  $cell_data = explode('|', $cell, 2);
982 
983  // Bug 553: Note that a '|' inside an invalid link should not
984  // be mistaken as delimiting cell parameters
985  if (strpos($cell_data[0], '[[') !== false) {
986  $cell = "{$previous}<{$last_tag}>{$cell}";
987  } elseif (count($cell_data) == 1) {
988  $cell = "{$previous}<{$last_tag}>{$cell_data[0]}";
989  } else {
990  $attributes = $this->mStripState->unstripBoth($cell_data[0]);
992  $cell = "{$previous}<{$last_tag}{$attributes}>{$cell_data[1]}";
993  }
994 
995  $lines[$key] .= $cell;
996  array_push($td_history, true);
997  }
998  }
999  }
1000 
1001  // Closing open td, tr && table
1002  while (count($td_history) > 0) {
1003  if (array_pop($td_history)) {
1004  $lines[] = '</td>' ;
1005  }
1006  if (array_pop($tr_history)) {
1007  $lines[] = '</tr>' ;
1008  }
1009  if (!array_pop($has_opened_tr)) {
1010  $lines[] = "<tr><td></td></tr>" ;
1011  }
1012 
1013  $lines[] = '</table>' ;
1014  }
1015 
1016  $output = implode("\n", $lines) ;
1017 
1018  // special case: don't return empty table
1019  if ($output == "<table>\n<tr><td></td></tr>\n</table>") {
1020  $output = '';
1021  }
1022 
1023  wfProfileOut($fname);
1024 
$attributes
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\+" &#(? foreach( $entity_files as $file) $output
$text
Definition: errorreport.php:18
Create styles array
The data for the language used.
static fixTagAttributes($text, $element)
Take a tag soup fragment listing an HTML element&#39;s attributes and normalize it to well-formed XML...
Definition: Sanitizer.php:669
$key
Definition: croninfo.php:18

◆ externalTidy()

Parser::externalTidy (   $text)
static

Spawn an external HTML tidy process and get corrected markup back from it.

Definition at line 765 of file Parser.php.

768  {
769  global $wgTidyConf, $wgTidyBin, $wgTidyOpts;
770  $fname = 'Parser::externalTidy';
771  wfProfileIn($fname);
772 
773  $cleansource = '';
774  $opts = ' -utf8';
775 
776  $descriptorspec = array(
777  0 => array('pipe', 'r'),
778  1 => array('pipe', 'w'),
779  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.
780  );
781  $pipes = array();
782  $process = proc_open("$wgTidyBin -config $wgTidyConf $wgTidyOpts$opts", $descriptorspec, $pipes);
783  if (is_resource($process)) {
784  // Theoretically, this style of communication could cause a deadlock
785  // here. If the stdout buffer fills up, then writes to stdin could
786  // block. This doesn't appear to happen with tidy, because tidy only
787  // writes to stdout after it's finished reading from stdin. Search
788  // for tidyParseStdin and tidySaveStdout in console/tidy.c
789  fwrite($pipes[0], $text);
790  fclose($pipes[0]);
791  while (!feof($pipes[1])) {
792  $cleansource .= fgets($pipes[1], 1024);
793  }
794  fclose($pipes[1]);
795  proc_close($process);
796  }
797 
798  wfProfileOut($fname);
799 
800  if ($cleansource == '' && $text != '') {
801  // Some kind of error happened, so we couldn't get the corrected text.
802  // Just give up; we'll use the source text and append a warning.
803  return null;
804  } else {
805  return $cleansource;
$text
Definition: errorreport.php:18
Create styles array
The data for the language used.

◆ extractSections()

Parser::extractSections (   $text,
  $section,
  $mode,
  $newtext = '' 
)
private

#-

Break wikitext input into sections, and either pull or replace some particular section's text.

External callers should use the getSection and replaceSection methods.

Parameters
$textPage wikitext
$sectionNumbered section. 0 pulls the text before the first heading; other numbers will pull the given section along with its lower-level subsections.
$modeOne of "get" or "replace"
$newtextReplacement text for section data.
Returns
string for "get", the extracted section text. for "replace", the whole page with the section replaced.

Definition at line 4763 of file Parser.php.

Referenced by replaceSection().

4766  {
4767  # strip NOWIKI etc. to avoid confusion (true-parameter causes HTML
4768  # comments to be stripped as well)
4769  $stripState = new StripState;
4770 
4771  $oldOutputType = $this->mOutputType;
4772  $oldOptions = $this->mOptions;
4773  $this->mOptions = new ParserOptions();
4774  $this->setOutputType(OT_WIKI);
4775 
4776  $striptext = $this->strip($text, $stripState, true);
4777 
4778  $this->setOutputType($oldOutputType);
4779  $this->mOptions = $oldOptions;
4780 
4781  # now that we can be sure that no pseudo-sections are in the source,
4782  # split it up by section
4783  $uniq = preg_quote($this->uniqPrefix(), '/');
4784  $comment = "(?:$uniq-!--.*?QINU)";
4785  $secs = preg_split(
4786  "/
4787  (
4788  ^
4789  (?:$comment|<\/?noinclude>)* # Initial comments will be stripped
4790  (=+) # Should this be limited to 6?
4791  .+? # Section title...
4792  \\2 # Ending = count must match start
4793  (?:$comment|<\/?noinclude>|[ \\t]+)* # Trailing whitespace ok
4794  $
4795  |
4796  <h([1-6])\b.*?>
4797  .*?
4798  <\/h\\3\s*>
4799  )
4800  /mix",
4801  $striptext,
4802  -1,
4803  PREG_SPLIT_DELIM_CAPTURE
4804  );
4805 
4806  if ($mode == "get") {
4807  if ($section == 0) {
4808  // "Section 0" returns the content before any other section.
4809  $rv = $secs[0];
4810  } else {
4811  //track missing section, will replace if found.
4812  $rv = $newtext;
4813  }
4814  } elseif ($mode == "replace") {
4815  if ($section == 0) {
4816  $rv = $newtext . "\n\n";
4817  $remainder = true;
4818  } else {
4819  $rv = $secs[0];
4820  $remainder = false;
4821  }
4822  }
4823  $count = 0;
4824  $sectionLevel = 0;
4825  for ($index = 1; $index < count($secs);) {
4826  $headerLine = $secs[$index++];
4827  if ($secs[$index]) {
4828  // A wiki header
4829  $headerLevel = strlen($secs[$index++]);
4830  } else {
4831  // An HTML header
4832  $index++;
4833  $headerLevel = intval($secs[$index++]);
4834  }
4835  $content = $secs[$index++];
4836 
4837  $count++;
4838  if ($mode == "get") {
4839  if ($count == $section) {
4840  $rv = $headerLine . $content;
4841  $sectionLevel = $headerLevel;
4842  } elseif ($count > $section) {
4843  if ($sectionLevel && $headerLevel > $sectionLevel) {
4844  $rv .= $headerLine . $content;
4845  } else {
4846  // Broke out to a higher-level section
4847  break;
4848  }
4849  }
4850  } elseif ($mode == "replace") {
4851  if ($count < $section) {
4852  $rv .= $headerLine . $content;
4853  } elseif ($count == $section) {
4854  $rv .= $newtext . "\n\n";
4855  $sectionLevel = $headerLevel;
4856  } elseif ($count > $section) {
4857  if ($headerLevel <= $sectionLevel) {
4858  // Passed the section's sub-parts.
4859  $remainder = true;
4860  }
4861  if ($remainder) {
4862  $rv .= $headerLine . $content;
4863  }
4864  }
4865  }
4866  }
4867  if (is_string($rv)) {
4868  # reinsert stripped tags
4869  $rv = trim($stripState->unstripBoth($rv));
4870  }
4871 
uniqPrefix()
Accessor for mUniqPrefix.
Definition: Parser.php:281
const OT_WIKI
Definition: Parser.php:19
$index
Definition: metadata.php:60
$mOutputType
Definition: Parser.php:128
$section
Definition: Utf8Test.php:83
$text
Definition: errorreport.php:18
setOutputType($ot)
Definition: Parser.php:264
$comment
Definition: buildRTE.php:83
$mOptions
Definition: Parser.php:124
strip($text, $state, $stripcomments=false, $dontstrip=array())
Strips and renders nowiki, pre, math, hiero If $render is set, performs necessary rendering operation...
Definition: Parser.php:570
+ Here is the caller graph for this function:

◆ extractTagsAndParams()

Parser::extractTagsAndParams (   $elements,
  $text,
$matches,
  $uniq_prefix = '' 
)
static

Replaces all occurrences of HTML-style comments and the given tags in the text with a random marker and returns teh next text.

The output parameter $matches will be an associative array filled with data in the form: 'UNIQ-xxxxx' => array( 'element', 'tag content', array( 'param' => 'x' ), '<element param="x">tag content</element>' ) )

Parameters
$elementslist of element names. Comments are always extracted.
$textSource text string.
$uniq_prefix

Definition at line 490 of file Parser.php.

493  {
494  static $n = 1;
495  $stripped = '';
496  $matches = array();
497 
498  $taglist = implode('|', $elements);
499  $start = "/<($taglist)(\\s+[^>]*?|\\s*?)(\/?>)|<(!--)/i";
500 
501  while ('' != $text) {
502  $p = preg_split($start, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
503  $stripped .= $p[0];
504  if (count($p) < 5) {
505  break;
506  }
507  if (count($p) > 5) {
508  // comment
509  $element = $p[4];
510  $attributes = '';
511  $close = '';
512  $inside = $p[5];
513  } else {
514  // tag
515  $element = $p[1];
516  $attributes = $p[2];
517  $close = $p[3];
518  $inside = $p[4];
519  }
520 
521  $marker = "$uniq_prefix-$element-" . sprintf('%08X', $n++) . '-QINU';
522  $stripped .= $marker;
523 
524  if ($close === '/>') {
525  // Empty element tag, <tag />
526  $content = null;
527  $text = $inside;
528  $tail = null;
529  } else {
530  if ($element == '!--') {
531  $end = '/(-->)/';
532  } else {
533  $end = "/(<\\/$element\\s*>)/i";
534  }
535  $q = preg_split($end, $inside, 2, PREG_SPLIT_DELIM_CAPTURE);
536  $content = $q[0];
537  if (count($q) < 3) {
538  # No end tag -- let it run out to the end of the text.
539  $tail = '';
540  $text = '';
541  } else {
542  $tail = $q[1];
543  $text = $q[2];
544  }
545  }
546 
547  $matches[$marker] = array( $element,
548  $content,
550  "<$element$attributes$close$content$tail" );
551  }
static decodeTagAttributes($text)
Return an associative array of attribute names and values from a partial tag string.
Definition: Sanitizer.php:812
$end
Definition: saml1-acs.php:18
$attributes
$text
Definition: errorreport.php:18
$n
Definition: RandomTest.php:85
Create styles array
The data for the language used.

◆ fetchScaryTemplateMaybeFromCache()

Parser::fetchScaryTemplateMaybeFromCache (   $url)

Definition at line 3459 of file Parser.php.

References $alignments, $current, $d, $html, $i, $id, $key, $m, $options, $params, $query, $res, $s, $size, $t, $tag, $text, $time, $title, $type, $url, $x, argSubstitution(), array, attributeStripCallback(), cleanSig(), cleanSigInSig(), clearState(), date, disableCache(), Sanitizer\escapeId(), formatHeadings(), getFunctionHooks(), getUserSig(), incrementIncludeSize(), makeImage(), Title\makeName(), Title\makeTitle(), Title\newFromDBkey(), Title\newFromText(), OT_HTML, OT_MSG, OT_PREPROCESS, OT_WIKI, parse(), preSaveTransform(), pstPass2(), renderImageGallery(), renderPreTag(), replaceInternalLinks(), replaceLinkHolders(), replaceLinkHoldersText(), replaceLinkHoldersTextCallback(), replaceVariables(), RLH_FOR_UPDATE, setFunctionHook(), setHook(), setOutputType(), SFH_NO_HASH, startExternalParse(), strip(), Sanitizer\stripAllTags(), stripNoGallery(), stripToc(), time, Title(), transformMsg(), validateSig(), Sanitizer\validateTagAttributes(), and wfMsg().

Referenced by createAssocArgs().

3462  {
3463  global $wgTranscludeCacheExpiry;
3464  $dbr = wfGetDB(DB_SLAVE);
3465  $obj = $dbr->selectRow(
3466  'transcache',
3467  array('tc_time', 'tc_contents'),
3468  array('tc_url' => $url)
3469  );
3470  if ($obj) {
3471  $time = $obj->tc_time;
3472  $text = $obj->tc_contents;
3473  if ($time && time() < $time + $wgTranscludeCacheExpiry) {
3474  return $text;
3475  }
3476  }
3477 
3478  $text = Http::get($url);
3479  if (!$text) {
3480  return wfMsg('scarytranscludefailed', $url);
3481  }
3482 
3483  $dbw = wfGetDB(DB_MASTER);
3484  $dbw->replace('transcache', array('tc_url'), array(
3485  'tc_url' => $url,
3486  'tc_time' => time(),
3487  'tc_contents' => $text));
$time
Definition: cron.php:21
wfMsg($x)
Definition: RandomTest.php:63
$text
Definition: errorreport.php:18
Create styles array
The data for the language used.
$url
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fetchTemplate()

Parser::fetchTemplate (   $title)

Fetch the unparsed text of a template and register a reference to it.

Definition at line 3411 of file Parser.php.

Referenced by createAssocArgs().

3414  {
3415  $text = false;
3416  // Loop to fetch the article, with up to 1 redirect
3417  for ($i = 0; $i < 2 && is_object($title); $i++) {
3418  $rev = Revision::newFromTitle($title);
3419  $this->mOutput->addTemplate($title, $title->getArticleID());
3420  if ($rev) {
3421  $text = $rev->getText();
3422  } elseif ($title->getNamespace() == NS_MEDIAWIKI) {
3423  global $wgLang;
3424  $message = $wgLang->lcfirst($title->getText());
3425  $text = wfMsgForContentNoTrans($message);
3426  if (wfEmptyMsg($message, $text)) {
3427  $text = false;
3428  break;
3429  }
3430  } else {
3431  break;
3432  }
3433  if ($text === false) {
3434  break;
3435  }
3436  // Redirect?
3438  }
catch(Exception $e) $message
$text
Definition: errorreport.php:18
static newFromRedirect($text)
Create a new Title for a redirect.
Definition: Title.php:301
$i
Definition: disco.tpl.php:19
+ Here is the caller graph for this function:

◆ findColonNoLinks()

Parser::findColonNoLinks (   $str,
$before,
$after 
)

Split up a string on ':', ignoring any occurences inside tags to prevent illegal overlapping.

Parameters
string$strthe string to split
string&$beforeset to everything before the ':'
string&$afterset to everything after the ':' return string the position of the ':', or false if none found

Definition at line 2344 of file Parser.php.

Referenced by closeList().

2344  :', or false if none found
2345  */
2346  public function findColonNoLinks($str, &$before, &$after)
2347  {
2348  $fname = 'Parser::findColonNoLinks';
2349  wfProfileIn($fname);
2350 
2351  $pos = strpos($str, ':');
2352  if ($pos === false) {
2353  // Nothing to find!
2354  wfProfileOut($fname);
2355  return false;
2356  }
2357 
2358  $lt = strpos($str, '<');
2359  if ($lt === false || $lt > $pos) {
2360  // Easy; no tag nesting to worry about
2361  $before = substr($str, 0, $pos);
2362  $after = substr($str, $pos+1);
2363  wfProfileOut($fname);
2364  return $pos;
2365  }
2366 
2367  // Ugly state machine to walk through avoiding tags.
2368  $state = MW_COLON_STATE_TEXT;
2369  $stack = 0;
2370  $len = strlen($str);
2371  for ($i = 0; $i < $len; $i++) {
2372  $c = $str{$i};
2373 
2374  switch ($state) {
2375  // (Using the number is a performance hack for common cases)
2376  case 0: // MW_COLON_STATE_TEXT:
2377  switch ($c) {
2378  case "<":
2379  // Could be either a <start> tag or an </end> tag
2380  $state = MW_COLON_STATE_TAGSTART;
2381  break;
2382  case ":":
2383  if ($stack == 0) {
2384  // We found it!
2385  $before = substr($str, 0, $i);
2386  $after = substr($str, $i + 1);
2387  wfProfileOut($fname);
2388  return $i;
2389  }
2390  // Embedded in a tag; don't break it.
2391  break;
2392  default:
2393  // Skip ahead looking for something interesting
2394  $colon = strpos($str, ':', $i);
2395  if ($colon === false) {
2396  // Nothing else interesting
2397  wfProfileOut($fname);
2398  return false;
2399  }
2400  $lt = strpos($str, '<', $i);
2401  if ($stack === 0) {
2402  if ($lt === false || $colon < $lt) {
2403  // We found it!
2404  $before = substr($str, 0, $colon);
2405  $after = substr($str, $colon + 1);
2406  wfProfileOut($fname);
2407  return $i;
2408  }
2409  }
2410  if ($lt === false) {
2411  // Nothing else interesting to find; abort!
2412  // We're nested, but there's no close tags left. Abort!
2413  break 2;
2414  }
2415  // Skip ahead to next tag start
2416  $i = $lt;
2418  }
2419  break;
2420  case 1: // MW_COLON_STATE_TAG:
2421  // In a <tag>
2422  switch ($c) {
2423  case ">":
2424  $stack++;
2426  break;
2427  case "/":
2428  // Slash may be followed by >?
2430  break;
2431  default:
2432  // ignore
2433  }
2434  break;
2435  case 2: // MW_COLON_STATE_TAGSTART:
2436  switch ($c) {
2437  case "/":
2439  break;
2440  case "!":
2442  break;
2443  case ">":
2444  // Illegal early close? This shouldn't happen D:
2446  break;
2447  default:
2449  }
2450  break;
2451  case 3: // MW_COLON_STATE_CLOSETAG:
2452  // In a </tag>
2453  if ($c == ">") {
2454  $stack--;
2455  if ($stack < 0) {
2456  wfDebug("Invalid input in $fname; too many close tags\n");
2457  wfProfileOut($fname);
2458  return false;
2459  }
2461  }
2462  break;
2464  if ($c == ">") {
2465  // Yes, a self-closed tag <blah/>
2467  } else {
2468  // Probably we're jumping the gun, and this is an attribute
2470  }
2471  break;
2472  case 5: // MW_COLON_STATE_COMMENT:
2473  if ($c == "-") {
2475  }
2476  break;
2478  if ($c == "-") {
2480  } else {
2482  }
2483  break;
2485  if ($c == ">") {
2487  } else {
2489  }
2490  break;
2491  default:
2492  throw new MWException("State machine error in $fname");
2493  }
2494  }
2495  if ($stack > 0) {
2496  wfDebug("Invalid input in $fname; not enough close tags (stack $stack, state $state)\n");
2497  return false;
2498  }
2499  wfProfileOut($fname);
findColonNoLinks($str, &$before, &$after)
Split up a string on &#39;:&#39;, ignoring any occurences inside tags to prevent illegal overlapping.
Definition: Parser.php:2344
const MW_COLON_STATE_CLOSETAG
Definition: Parser.php:51
const MW_COLON_STATE_TAGSLASH
Definition: Parser.php:52
const MW_COLON_STATE_TAGSTART
Definition: Parser.php:50
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Definition: linkback.php:10
const MW_COLON_STATE_COMMENT
Definition: Parser.php:53
const MW_COLON_STATE_TEXT
Definition: Parser.php:48
$i
Definition: disco.tpl.php:19
const MW_COLON_STATE_TAG
Definition: Parser.php:49
const MW_COLON_STATE_COMMENTDASHDASH
Definition: Parser.php:55
const MW_COLON_STATE_COMMENTDASH
Definition: Parser.php:54
+ Here is the caller graph for this function:

◆ firstCallInit()

Parser::firstCallInit ( )

Do various kinds of initialisation on the first call of the parser.

Definition at line 156 of file Parser.php.

159  {
160  if (!$this->mFirstCall) {
161  return;
162  }
163 
164  wfProfileIn(__METHOD__);
165  global $wgAllowDisplayTitle, $wgAllowSlowParserFunctions;
166 
167  $this->setHook('pre', array( $this, 'renderPreTag' ));
168 
169  $this->setFunctionHook('int', array( 'CoreParserFunctions', 'intFunction' ), SFH_NO_HASH);
170  $this->setFunctionHook('ns', array( 'CoreParserFunctions', 'ns' ), SFH_NO_HASH);
171  $this->setFunctionHook('urlencode', array( 'CoreParserFunctions', 'urlencode' ), SFH_NO_HASH);
172  $this->setFunctionHook('lcfirst', array( 'CoreParserFunctions', 'lcfirst' ), SFH_NO_HASH);
173  $this->setFunctionHook('ucfirst', array( 'CoreParserFunctions', 'ucfirst' ), SFH_NO_HASH);
174  $this->setFunctionHook('lc', array( 'CoreParserFunctions', 'lc' ), SFH_NO_HASH);
175  $this->setFunctionHook('uc', array( 'CoreParserFunctions', 'uc' ), SFH_NO_HASH);
176  $this->setFunctionHook('localurl', array( 'CoreParserFunctions', 'localurl' ), SFH_NO_HASH);
177  $this->setFunctionHook('localurle', array( 'CoreParserFunctions', 'localurle' ), SFH_NO_HASH);
178  $this->setFunctionHook('fullurl', array( 'CoreParserFunctions', 'fullurl' ), SFH_NO_HASH);
179  $this->setFunctionHook('fullurle', array( 'CoreParserFunctions', 'fullurle' ), SFH_NO_HASH);
180  $this->setFunctionHook('formatnum', array( 'CoreParserFunctions', 'formatnum' ), SFH_NO_HASH);
181  $this->setFunctionHook('grammar', array( 'CoreParserFunctions', 'grammar' ), SFH_NO_HASH);
182  $this->setFunctionHook('plural', array( 'CoreParserFunctions', 'plural' ), SFH_NO_HASH);
183  $this->setFunctionHook('numberofpages', array( 'CoreParserFunctions', 'numberofpages' ), SFH_NO_HASH);
184  $this->setFunctionHook('numberofusers', array( 'CoreParserFunctions', 'numberofusers' ), SFH_NO_HASH);
185  $this->setFunctionHook('numberofarticles', array( 'CoreParserFunctions', 'numberofarticles' ), SFH_NO_HASH);
186  $this->setFunctionHook('numberoffiles', array( 'CoreParserFunctions', 'numberoffiles' ), SFH_NO_HASH);
187  $this->setFunctionHook('numberofadmins', array( 'CoreParserFunctions', 'numberofadmins' ), SFH_NO_HASH);
188  $this->setFunctionHook('numberofedits', array( 'CoreParserFunctions', 'numberofedits' ), SFH_NO_HASH);
189  $this->setFunctionHook('language', array( 'CoreParserFunctions', 'language' ), SFH_NO_HASH);
190  $this->setFunctionHook('padleft', array( 'CoreParserFunctions', 'padleft' ), SFH_NO_HASH);
191  $this->setFunctionHook('padright', array( 'CoreParserFunctions', 'padright' ), SFH_NO_HASH);
192  $this->setFunctionHook('anchorencode', array( 'CoreParserFunctions', 'anchorencode' ), SFH_NO_HASH);
193  $this->setFunctionHook('special', array( 'CoreParserFunctions', 'special' ));
194  $this->setFunctionHook('defaultsort', array( 'CoreParserFunctions', 'defaultsort' ), SFH_NO_HASH);
195 
196  if ($wgAllowDisplayTitle) {
197  $this->setFunctionHook('displaytitle', array( 'CoreParserFunctions', 'displaytitle' ), SFH_NO_HASH);
198  }
199  if ($wgAllowSlowParserFunctions) {
200  $this->setFunctionHook('pagesinnamespace', array( 'CoreParserFunctions', 'pagesinnamespace' ), SFH_NO_HASH);
201  }
202 
203  $this->initialiseVariables();
204  $this->mFirstCall = false;
initialiseVariables()
initialise the magic variables (like CURRENTMONTHNAME)
Definition: Parser.php:2704
const SFH_NO_HASH
Definition: Parser.php:24
setHook($tag, $callback)
Create an HTML-style tag, e.g.
Definition: Parser.php:4080
Create styles array
The data for the language used.
setFunctionHook($id, $callback, $flags=0)
Create a function, e.g.
Definition: Parser.php:4113

◆ formatHeadings()

Parser::formatHeadings (   $text,
  $isMain = true 
)

This function accomplishes several tasks: 1) Auto-number headings if that option is enabled 2) Add an [edit] link to sections for logged in users who have enabled the option 3) Add a Table of contents on the top for users who have enabled the option 4) Auto-anchor headings.

It loops through all headlines, collects the necessary data, then splits up the string and re-inserts the newly formatted headlines.

Parameters
string$text
boolean$isMain

Definition at line 3582 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

3585  {
3586  global $wgMaxTocLevel, $wgContLang;
3587 
3588  $doNumberHeadings = $this->mOptions->getNumberHeadings();
3589  if (!$this->mTitle->quickUserCan('edit')) {
3590  $showEditLink = 0;
3591  } else {
3592  $showEditLink = $this->mOptions->getEditSection();
3593  }
3594 
3595  # Inhibit editsection links if requested in the page
3596  $esw =&MagicWord::get('noeditsection');
3597  if ($esw->matchAndRemove($text)) {
3598  $showEditLink = 0;
3599  }
3600 
3601  # Get all headlines for numbering them and adding funky stuff like [edit]
3602  # links - this is for later, but we need the number of headlines right now
3603  $matches = array();
3604  $numMatches = preg_match_all('/<H(?P<level>[1-6])(?P<attrib>.*?' . '>)(?P<header>.*?)<\/H[1-6] *>/i', $text, $matches);
3605 
3606  # if there are fewer than 4 headlines in the article, do not show TOC
3607  # unless it's been explicitly enabled.
3608  $enoughToc = $this->mShowToc &&
3609  (($numMatches >= 4) || $this->mForceTocPosition);
3610 
3611  # Allow user to stipulate that a page should have a "new section"
3612  # link added via __NEWSECTIONLINK__
3613  $mw =&MagicWord::get('newsectionlink');
3614  if ($mw->matchAndRemove($text)) {
3615  $this->mOutput->setNewSection(true);
3616  }
3617 
3618  # if the string __FORCETOC__ (not case-sensitive) occurs in the HTML,
3619  # override above conditions and always show TOC above first header
3620  $mw =&MagicWord::get('forcetoc');
3621  if ($mw->matchAndRemove($text)) {
3622  $this->mShowToc = true;
3623  $enoughToc = true;
3624  }
3625 
3626  # Never ever show TOC if no headers
3627  if ($numMatches < 1) {
3628  $enoughToc = false;
3629  }
3630 
3631  # We need this to perform operations on the HTML
3632  $sk = $this->mOptions->getSkin();
3633 
3634  # headline counter
3635  $headlineCount = 0;
3636  $sectionCount = 0; # headlineCount excluding template sections
3637 
3638  # Ugh .. the TOC should have neat indentation levels which can be
3639  # passed to the skin functions. These are determined here
3640  $toc = '';
3641  $full = '';
3642  $head = array();
3643  $sublevelCount = array();
3644  $levelCount = array();
3645  $toclevel = 0;
3646  $level = 0;
3647  $prevlevel = 0;
3648  $toclevel = 0;
3649  $prevtoclevel = 0;
3650 
3651  foreach ($matches[3] as $headline) {
3652  $istemplate = 0;
3653  $templatetitle = '';
3654  $templatesection = 0;
3655  $numbering = '';
3656  $mat = array();
3657  if (preg_match("/<!--MWTEMPLATESECTION=([^&]+)&([^_]+)-->/", $headline, $mat)) {
3658  $istemplate = 1;
3659  $templatetitle = base64_decode($mat[1]);
3660  $templatesection = 1 + (int) base64_decode($mat[2]);
3661  $headline = preg_replace("/<!--MWTEMPLATESECTION=([^&]+)&([^_]+)-->/", "", $headline);
3662  }
3663 
3664  if ($toclevel) {
3665  $prevlevel = $level;
3666  $prevtoclevel = $toclevel;
3667  }
3668  $level = $matches[1][$headlineCount];
3669 
3670  if ($doNumberHeadings || $enoughToc) {
3671  if ($level > $prevlevel) {
3672  # Increase TOC level
3673  $toclevel++;
3674  $sublevelCount[$toclevel] = 0;
3675  if ($toclevel<$wgMaxTocLevel) {
3676  $toc .= $sk->tocIndent();
3677  }
3678  } elseif ($level < $prevlevel && $toclevel > 1) {
3679  # Decrease TOC level, find level to jump to
3680 
3681  if ($toclevel == 2 && $level <= $levelCount[1]) {
3682  # Can only go down to level 1
3683  $toclevel = 1;
3684  } else {
3685  for ($i = $toclevel; $i > 0; $i--) {
3686  if ($levelCount[$i] == $level) {
3687  # Found last matching level
3688  $toclevel = $i;
3689  break;
3690  } elseif ($levelCount[$i] < $level) {
3691  # Found first matching level below current level
3692  $toclevel = $i + 1;
3693  break;
3694  }
3695  }
3696  }
3697  if ($toclevel<$wgMaxTocLevel) {
3698  $toc .= $sk->tocUnindent($prevtoclevel - $toclevel);
3699  }
3700  } else {
3701  # No change in level, end TOC line
3702  if ($toclevel<$wgMaxTocLevel) {
3703  $toc .= $sk->tocLineEnd();
3704  }
3705  }
3706 
3707  $levelCount[$toclevel] = $level;
3708 
3709  # count number of headlines for each level
3710  @$sublevelCount[$toclevel]++;
3711  $dot = 0;
3712  for ($i = 1; $i <= $toclevel; $i++) {
3713  if (!empty($sublevelCount[$i])) {
3714  if ($dot) {
3715  $numbering .= '.';
3716  }
3717  $numbering .= $wgContLang->formatNum($sublevelCount[$i]);
3718  $dot = 1;
3719  }
3720  }
3721  }
3722 
3723  # The canonized header is a version of the header text safe to use for links
3724  # Avoid insertion of weird stuff like <math> by expanding the relevant sections
3725  $canonized_headline = $this->mStripState->unstripBoth($headline);
3726 
3727  # Remove link placeholders by the link text.
3728  # <!--LINK number-->
3729  # turns into
3730  # link text with suffix
3731  $canonized_headline = preg_replace_callback(
3732  '/<!--LINK ([0-9]*)-->/',
3733  function ($hit) {
3734  return $this->mLinkHolders['texts'][$hit[1]];
3735  },
3736  $canonized_headline
3737  );
3738  $canonized_headline = preg_replace_callback(
3739  '/<!--IWLINK ([0-9]*)-->/',
3740  function ($hit) {
3741  return $this->mInterwikiLinkHolders['texts'][$hit[1]];
3742  },
3743  $canonized_headline
3744  );
3745 
3746  # strip out HTML
3747  $canonized_headline = preg_replace('/<.*?' . '>/', '', $canonized_headline);
3748  $tocline = trim($canonized_headline);
3749  # Save headline for section edit hint before it's escaped
3750  $headline_hint = trim($canonized_headline);
3751  $canonized_headline = Sanitizer::escapeId($tocline);
3752  $refers[$headlineCount] = $canonized_headline;
3753 
3754  # count how many in assoc. array so we can track dupes in anchors
3755  isset($refers[$canonized_headline]) ? $refers[$canonized_headline]++ : $refers[$canonized_headline] = 1;
3756  $refcount[$headlineCount]=$refers[$canonized_headline];
3757 
3758  # Don't number the heading if it is the only one (looks silly)
3759  if ($doNumberHeadings && count($matches[3]) > 1) {
3760  # the two are different if the line contains a link
3761  $headline=$numbering . ' ' . $headline;
3762  }
3763 
3764  # Create the anchor for linking from the TOC to the section
3765  $anchor = $canonized_headline;
3766  if ($refcount[$headlineCount] > 1) {
3767  $anchor .= '_' . $refcount[$headlineCount];
3768  }
3769  if ($enoughToc && (!isset($wgMaxTocLevel) || $toclevel<$wgMaxTocLevel)) {
3770  $toc .= $sk->tocLine($anchor, $tocline, $numbering, $toclevel);
3771  }
3772  # give headline the correct <h#> tag
3773  if ($showEditLink && (!$istemplate || $templatetitle !== "")) {
3774  if ($istemplate) {
3775  $editlink = $sk->editSectionLinkForOther($templatetitle, $templatesection);
3776  } else {
3777  $editlink = $sk->editSectionLink($this->mTitle, $sectionCount+1, $headline_hint);
3778  }
3779  } else {
3780  $editlink = '';
3781  }
3782  $head[$headlineCount] = $sk->makeHeadline($level, $matches['attrib'][$headlineCount], $anchor, $headline, $editlink);
3783 
3784  $headlineCount++;
3785  if (!$istemplate) {
3786  $sectionCount++;
3787  }
3788  }
3789 
3790  if ($enoughToc) {
3791  if ($toclevel<$wgMaxTocLevel) {
3792  $toc .= $sk->tocUnindent($toclevel - 1);
3793  }
3794  $toc = $sk->tocList($toc);
3795  }
3796 
3797  # split up and insert constructed headlines
3798 
3799  $blocks = preg_split('/<H[1-6].*?' . '>.*?<\/H[1-6]>/i', $text);
3800  $i = 0;
3801 
3802  foreach ($blocks as $block) {
3803  if ($showEditLink && $headlineCount > 0 && $i == 0 && $block != "\n") {
3804  # This is the [edit] link that appears for the top block of text when
3805  # section editing is enabled
3806 
3807  # Disabled because it broke block formatting
3808  # For example, a bullet point in the top line
3809  # $full .= $sk->editSectionLink(0);
3810  }
3811  $full .= $block;
3812  if ($enoughToc && !$i && $isMain && !$this->mForceTocPosition) {
3813  # Top anchor now in skin
3814  $full = $full . $toc;
3815  }
3816 
3817  if (!empty($head[$i])) {
3818  $full .= $head[$i];
3819  }
3820  $i++;
3821  }
3822  if ($this->mForceTocPosition) {
3823  return str_replace('<!--MWTOC-->', $toc, $full);
3824  } else {
3825  return $full;
$text
Definition: errorreport.php:18
Create styles array
The data for the language used.
static escapeId($id)
Given a value escape it so that it can be used in an id attribute and return it, this does not valida...
Definition: Sanitizer.php:760
$i
Definition: disco.tpl.php:19
+ Here is the caller graph for this function:

◆ getCommon()

Parser::getCommon (   $st1,
  $st2 
)

Definition at line 2087 of file Parser.php.

References $i.

Referenced by closeList().

2090  {
2091  $fl = strlen($st1);
2092  $shorter = strlen($st2);
2093  if ($fl < $shorter) {
2094  $shorter = $fl;
2095  }
2096 
2097  for ($i = 0; $i < $shorter; ++$i) {
2098  if ($st1{$i} != $st2{$i}) {
2099  break;
2100  }
2101  }
$i
Definition: disco.tpl.php:19
+ Here is the caller graph for this function:

◆ getDefaultSort()

Parser::getDefaultSort ( )

Accessor for $mDefaultSort Will use the title/prefixed title if none is set.

Returns
string

Definition at line 4947 of file Parser.php.

Referenced by magicLinkCallback(), and replaceSection().

4950  {
4951  if ($this->mDefaultSort !== false) {
4952  return $this->mDefaultSort;
4953  } else {
4954  return $this->mTitle->getNamespace() == NS_CATEGORY
4955  ? $this->mTitle->getText()
4956  : $this->mTitle->getPrefixedText();
$mDefaultSort
Definition: Parser.php:115
+ Here is the caller graph for this function:

◆ getFunctionHooks()

Parser::getFunctionHooks ( )

Get all registered function hook identifiers.

Returns
array

Definition at line 4150 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

4153  {
+ Here is the caller graph for this function:

◆ getFunctionLang()

Parser::getFunctionLang ( )

Definition at line 466 of file Parser.php.

469  {
470  global $wgLang, $wgContLang;

◆ getOptions()

Parser::getOptions ( )

Definition at line 461 of file Parser.php.

464  {

◆ getRandomString()

Parser::getRandomString ( )
static

Get a random string.

Definition at line 452 of file Parser.php.

455  {

◆ getRevisionTimestamp()

Parser::getRevisionTimestamp ( )

Get the timestamp associated with the current revision, adjusted for the default server-local timestamp.

Definition at line 4899 of file Parser.php.

Referenced by closeList(), and replaceSection().

4902  {
4903  if (is_null($this->mRevisionTimestamp)) {
4904  wfProfileIn(__METHOD__);
4905  global $wgContLang;
4906  $dbr = wfGetDB(DB_SLAVE);
4907  $timestamp = $dbr->selectField(
4908  'revision',
4909  'rev_timestamp',
4910  array( 'rev_id' => $this->mRevisionId ),
4911  __METHOD__
4912  );
4913 
4914  // Normalize timestamp to internal MW format for timezone processing.
4915  // This has the added side-effect of replacing a null value with
4916  // the current time, which gives us more sensible behavior for
4917  // previews.
4918  $timestamp = wfTimestamp(TS_MW, $timestamp);
4919 
4920  // The cryptic '' timezone parameter tells to use the site-default
4921  // timezone offset instead of the user settings.
4922  //
4923  // Since this value will be saved into the parser cache, served
4924  // to other users, and potentially even used inside links and such,
4925  // it needs to be consistent for all visitors.
4926  $this->mRevisionTimestamp = $wgContLang->userAdjust($timestamp, '');
4927 
4928  wfProfileOut(__METHOD__);
4929  }
Create styles array
The data for the language used.
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:81
+ Here is the caller graph for this function:

◆ getSection()

Parser::getSection (   $text,
  $section,
  $deftext = '' 
)

This function returns the text of a section, specified by a number ($section).

A section is text under a heading like == Heading == or <h1>Heading</h1>, or the first section before any such heading (section 0).

If a section contains subsections, these are also returned.

Parameters
$textString: text to look in
$sectionInteger: section number
$deftextdefault to return if section is not found
Returns
string text of the requested section

Definition at line 4885 of file Parser.php.

4888  {

◆ getTags()

Parser::getTags ( )

#-

#+ Accessor

Definition at line 4741 of file Parser.php.

4744  {

◆ getTitle()

& Parser::getTitle ( )

Definition at line 457 of file Parser.php.

460  {

◆ getUserSig()

Parser::getUserSig ( $user)

Fetch the user's signature text, if any, and normalize to validated, ready-to-insert wikitext.

Parameters
User$user
Returns
string

Definition at line 3937 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

3940  {
3941  $username = $user->getName();
3942  $nickname = $user->getOption('nickname');
3943  $nickname = $nickname === '' ? $username : $nickname;
3944 
3945  if ($user->getBoolOption('fancysig') !== false) {
3946  # Sig. might contain markup; validate this
3947  if ($this->validateSig($nickname) !== false) {
3948  # Validated; clean up (if needed) and return it
3949  return $this->cleanSig($nickname, true);
3950  } else {
3951  # Failed to validate; fall back to the default
3952  $nickname = $username;
3953  wfDebug("Parser::getUserSig: $username has bad XML tags in signature.\n");
3954  }
3955  }
3956 
3957  // Make sure nickname doesnt get a sig in a sig
3958  $nickname = $this->cleanSigInSig($nickname);
3959 
3960  # If we're still here, make it a link to the user page
3961  $userpage = $user->getUserPage();
validateSig($text)
Check that the user&#39;s signature contains no bad XML.
Definition: Parser.php:3969
cleanSig($text, $parsing=false)
Clean up signature text.
Definition: Parser.php:3984
cleanSigInSig($text)
Strip ~~~, ~~~~ and ~~~~~ out of signatures.
Definition: Parser.php:4006
+ Here is the caller graph for this function:

◆ getVariableValue()

Parser::getVariableValue (   $index)

Return value of a magic variable (like PAGENAME)

Some of these require message or data lookups and can be expensive to check many times.

Definition at line 2506 of file Parser.php.

Referenced by closeList().

2509  {
2510  global $wgContLang, $wgSitename, $wgServer, $wgServerName, $wgScriptPath;
2511 
2516  static $varCache = array();
2517  if (wfRunHooks('ParserGetVariableValueVarCache', array( &$this, &$varCache ))) {
2518  if (isset($varCache[$index])) {
2519  return $varCache[$index];
2520  }
2521  }
2522 
2523  $ts = time();
2524  wfRunHooks('ParserGetVariableValueTs', array( &$this, &$ts ));
2525 
2526  # Use the time zone
2527  global $wgLocaltimezone;
2528  if (isset($wgLocaltimezone)) {
2529  $oldtz = getenv('TZ');
2530  putenv('TZ=' . $wgLocaltimezone);
2531  }
2532  $localTimestamp = date('YmdHis', $ts);
2533  $localMonth = date('m', $ts);
2534  $localMonthName = date('n', $ts);
2535  $localDay = date('j', $ts);
2536  $localDay2 = date('d', $ts);
2537  $localDayOfWeek = date('w', $ts);
2538  $localWeek = date('W', $ts);
2539  $localYear = date('Y', $ts);
2540  $localHour = date('H', $ts);
2541  if (isset($wgLocaltimezone)) {
2542  putenv('TZ=' . $oldtz);
2543  }
2544 
2545  switch ($index) {
2546  case 'currentmonth':
2547  return $varCache[$index] = $wgContLang->formatNum(date('m', $ts));
2548  case 'currentmonthname':
2549  return $varCache[$index] = $wgContLang->getMonthName(date('n', $ts));
2550  case 'currentmonthnamegen':
2551  return $varCache[$index] = $wgContLang->getMonthNameGen(date('n', $ts));
2552  case 'currentmonthabbrev':
2553  return $varCache[$index] = $wgContLang->getMonthAbbreviation(date('n', $ts));
2554  case 'currentday':
2555  return $varCache[$index] = $wgContLang->formatNum(date('j', $ts));
2556  case 'currentday2':
2557  return $varCache[$index] = $wgContLang->formatNum(date('d', $ts));
2558  case 'localmonth':
2559  return $varCache[$index] = $wgContLang->formatNum($localMonth);
2560  case 'localmonthname':
2561  return $varCache[$index] = $wgContLang->getMonthName($localMonthName);
2562  case 'localmonthnamegen':
2563  return $varCache[$index] = $wgContLang->getMonthNameGen($localMonthName);
2564  case 'localmonthabbrev':
2565  return $varCache[$index] = $wgContLang->getMonthAbbreviation($localMonthName);
2566  case 'localday':
2567  return $varCache[$index] = $wgContLang->formatNum($localDay);
2568  case 'localday2':
2569  return $varCache[$index] = $wgContLang->formatNum($localDay2);
2570  case 'pagename':
2571  return $this->mTitle->getText();
2572  case 'pagenamee':
2573  return $this->mTitle->getPartialURL();
2574  case 'fullpagename':
2575  return $this->mTitle->getPrefixedText();
2576  case 'fullpagenamee':
2577  return $this->mTitle->getPrefixedURL();
2578  case 'subpagename':
2579  return $this->mTitle->getSubpageText();
2580  case 'subpagenamee':
2581  return $this->mTitle->getSubpageUrlForm();
2582  case 'basepagename':
2583  return $this->mTitle->getBaseText();
2584  case 'basepagenamee':
2585  return wfUrlEncode(str_replace(' ', '_', $this->mTitle->getBaseText()));
2586  case 'talkpagename':
2587  if ($this->mTitle->canTalk()) {
2588  $talkPage = $this->mTitle->getTalkPage();
2589  return $talkPage->getPrefixedText();
2590  } else {
2591  return '';
2592  }
2593  // no break
2594  case 'talkpagenamee':
2595  if ($this->mTitle->canTalk()) {
2596  $talkPage = $this->mTitle->getTalkPage();
2597  return $talkPage->getPrefixedUrl();
2598  } else {
2599  return '';
2600  }
2601  // no break
2602  case 'subjectpagename':
2603  $subjPage = $this->mTitle->getSubjectPage();
2604  return $subjPage->getPrefixedText();
2605  case 'subjectpagenamee':
2606  $subjPage = $this->mTitle->getSubjectPage();
2607  return $subjPage->getPrefixedUrl();
2608  case 'revisionid':
2609  return $this->mRevisionId;
2610  case 'revisionday':
2611  return intval(substr($this->getRevisionTimestamp(), 6, 2));
2612  case 'revisionday2':
2613  return substr($this->getRevisionTimestamp(), 6, 2);
2614  case 'revisionmonth':
2615  return intval(substr($this->getRevisionTimestamp(), 4, 2));
2616  case 'revisionyear':
2617  return substr($this->getRevisionTimestamp(), 0, 4);
2618  case 'revisiontimestamp':
2619  return $this->getRevisionTimestamp();
2620  case 'namespace':
2621  return str_replace('_', ' ', $wgContLang->getNsText($this->mTitle->getNamespace()));
2622  case 'namespacee':
2623  return wfUrlencode($wgContLang->getNsText($this->mTitle->getNamespace()));
2624  case 'talkspace':
2625  return $this->mTitle->canTalk() ? str_replace('_', ' ', $this->mTitle->getTalkNsText()) : '';
2626  case 'talkspacee':
2627  return $this->mTitle->canTalk() ? wfUrlencode($this->mTitle->getTalkNsText()) : '';
2628  case 'subjectspace':
2629  return $this->mTitle->getSubjectNsText();
2630  case 'subjectspacee':
2631  return(wfUrlencode($this->mTitle->getSubjectNsText()));
2632  case 'currentdayname':
2633  return $varCache[$index] = $wgContLang->getWeekdayName(date('w', $ts) + 1);
2634  case 'currentyear':
2635  return $varCache[$index] = $wgContLang->formatNum(date('Y', $ts), true);
2636  case 'currenttime':
2637  return $varCache[$index] = $wgContLang->time(wfTimestamp(TS_MW, $ts), false, false);
2638  case 'currenthour':
2639  return $varCache[$index] = $wgContLang->formatNum(date('H', $ts), true);
2640  case 'currentweek':
2641  // @bug 4594 PHP5 has it zero padded, PHP4 does not, cast to
2642  // int to remove the padding
2643  return $varCache[$index] = $wgContLang->formatNum((int) date('W', $ts));
2644  case 'currentdow':
2645  return $varCache[$index] = $wgContLang->formatNum(date('w', $ts));
2646  case 'localdayname':
2647  return $varCache[$index] = $wgContLang->getWeekdayName($localDayOfWeek + 1);
2648  case 'localyear':
2649  return $varCache[$index] = $wgContLang->formatNum($localYear, true);
2650  case 'localtime':
2651  return $varCache[$index] = $wgContLang->time($localTimestamp, false, false);
2652  case 'localhour':
2653  return $varCache[$index] = $wgContLang->formatNum($localHour, true);
2654  case 'localweek':
2655  // @bug 4594 PHP5 has it zero padded, PHP4 does not, cast to
2656  // int to remove the padding
2657  return $varCache[$index] = $wgContLang->formatNum((int) $localWeek);
2658  case 'localdow':
2659  return $varCache[$index] = $wgContLang->formatNum($localDayOfWeek);
2660  case 'numberofarticles':
2661  return $varCache[$index] = $wgContLang->formatNum(SiteStats::articles());
2662  case 'numberoffiles':
2663  return $varCache[$index] = $wgContLang->formatNum(SiteStats::images());
2664  case 'numberofusers':
2665  return $varCache[$index] = $wgContLang->formatNum(SiteStats::users());
2666  case 'numberofpages':
2667  return $varCache[$index] = $wgContLang->formatNum(SiteStats::pages());
2668  case 'numberofadmins':
2669  return $varCache[$index] = $wgContLang->formatNum(SiteStats::admins());
2670  case 'numberofedits':
2671  return $varCache[$index] = $wgContLang->formatNum(SiteStats::edits());
2672  case 'currenttimestamp':
2673  return $varCache[$index] = wfTimestampNow();
2674  case 'localtimestamp':
2675  return $varCache[$index] = $localTimestamp;
2676  case 'currentversion':
2677  return $varCache[$index] = SpecialVersion::getVersion();
2678  case 'sitename':
2679  return $wgSitename;
2680  case 'server':
2681  return $wgServer;
2682  case 'servername':
2683  return $wgServerName;
2684  case 'scriptpath':
2685  return $wgScriptPath;
2686  case 'directionmark':
2687  return $wgContLang->getDirMark();
2688  case 'contentlanguage':
2689  global $wgContLanguageCode;
2690  return $wgContLanguageCode;
2691  default:
2692  $ret = null;
2693  if (wfRunHooks('ParserGetVariableValueSwitch', array( &$this, &$varCache, &$index, &$ret ))) {
2694  return $ret;
2695  } else {
2696  return null;
2697  }
$mRevisionId
Definition: Parser.php:132
$index
Definition: metadata.php:60
getRevisionTimestamp()
Get the timestamp associated with the current revision, adjusted for the default server-local timesta...
Definition: Parser.php:4899
Done rendering charts as images
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
Create styles array
The data for the language used.
$ret
Definition: parser.php:6
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
+ Here is the caller graph for this function:

◆ incrementIncludeSize()

Parser::incrementIncludeSize (   $type,
  $size 
)

Increment an include size counter.

Parameters
string$typeThe type of expansion
integer$sizeThe size of the text
Returns
boolean False if this inclusion would take it over the maximum, true otherwise

Definition at line 3521 of file Parser.php.

Referenced by createAssocArgs(), and fetchScaryTemplateMaybeFromCache().

3524  {
3525  if ($this->mIncludeSizes[$type] + $size > $this->mOptions->getMaxIncludeSize()) {
3526  return false;
3527  } else {
3528  $this->mIncludeSizes[$type] += $size;
3529  return true;
$size
Definition: RandomTest.php:84
$type
+ Here is the caller graph for this function:

◆ initialiseVariables()

Parser::initialiseVariables ( )

initialise the magic variables (like CURRENTMONTHNAME)

Definition at line 2704 of file Parser.php.

Referenced by closeList().

2707  {
2708  $fname = 'Parser::initialiseVariables';
2709  wfProfileIn($fname);
2710  $variableIDs = MagicWord::getVariableIDs();
2711 
2712  $this->mVariables = array();
2713  foreach ($variableIDs as $id) {
2714  $mw =&MagicWord::get($id);
2715  $mw->addToArray($this->mVariables, $id);
2716  }
if(!array_key_exists('StateId', $_REQUEST)) $id
Create styles array
The data for the language used.
+ Here is the caller graph for this function:

◆ insertStripItem()

Parser::insertStripItem (   $text,
$state 
)

Add an item to the strip state Returns the unique tag which must be inserted into the stripped text The tag will be replaced with the original text in unstrip()

Definition at line 720 of file Parser.php.

Referenced by createAssocArgs().

723  {
724  $rnd = $this->mUniqPrefix . '-item' . Parser::getRandomString();
725  $state->general->setPair($rnd, $text);
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Definition: linkback.php:10
$text
Definition: errorreport.php:18
getRandomString()
Get a random string.
Definition: Parser.php:452
+ Here is the caller graph for this function:

◆ internalParse()

Parser::internalParse (   $text)

Helper function for parse() that transforms wiki markup into HTML.

Only called for $mOutputType == OT_HTML.

Definition at line 1032 of file Parser.php.

Referenced by setOutputType().

1035  {
1036  $args = array();
1037  $isMain = true;
1038  $fname = 'Parser::internalParse';
1039  wfProfileIn($fname);
1040 
1041  # Hook to suspend the parser in this state
1042  if (!wfRunHooks('ParserBeforeInternalParse', array( &$this, &$text, &$this->mStripState ))) {
1043  wfProfileOut($fname);
1044  return $text ;
1045  }
1046 
1047  # Remove <noinclude> tags and <includeonly> sections
1048  $text = strtr($text, array( '<onlyinclude>' => '' , '</onlyinclude>' => '' ));
1049  $text = strtr($text, array( '<noinclude>' => '', '</noinclude>' => ''));
1050  $text = StringUtils::delimiterReplace('<includeonly>', '</includeonly>', '', $text);
1051 
1052  $text = Sanitizer::removeHTMLtags($text, array( &$this, 'attributeStripCallback' ));
1053 
1054  $text = $this->replaceVariables($text, $args);
1055  wfRunHooks('InternalParseBeforeLinks', array( &$this, &$text, &$this->mStripState ));
1056 
1057  // Tables need to come after variable replacement for things to work
1058  // properly; putting them before other transformations should keep
1059  // exciting things like link expansions from showing up in surprising
1060  // places.
1061  $text = $this->doTableStuff($text);
1062 
1063  $text = preg_replace('/(^|\n)-----*/', '\\1<hr />', $text);
1064 
1065  $text = $this->stripToc($text);
1066  $this->stripNoGallery($text);
1067  $text = $this->doHeadings($text);
1068  if ($this->mOptions->getUseDynamicDates()) {
1069  $df =&DateFormatter::getInstance();
1070  $text = $df->reformat($this->mOptions->getDateFormat(), $text);
1071  }
1072  $text = $this->doAllQuotes($text);
1073  $text = $this->replaceInternalLinks($text);
1074  $text = $this->replaceExternalLinks($text);
1075 
1076  # replaceInternalLinks may sometimes leave behind
1077  # absolute URLs, which have to be masked to hide them from replaceExternalLinks
1078  $text = str_replace($this->mUniqPrefix . "NOPARSE", "", $text);
1079 
1080  $text = $this->doMagicLinks($text);
1081  $text = $this->formatHeadings($text, $isMain);
1082 
1083  wfProfileOut($fname);
& doMagicLinks(&$text)
Replace special strings like "ISBN xxx" and "RFC xxx" with magic external links.
Definition: Parser.php:1091
replaceExternalLinks($text)
Replace external links.
Definition: Parser.php:1380
doHeadings($text)
Parse headers and return html.
Definition: Parser.php:1155
stripNoGallery(&$text)
Detect NOGALLERY magic word and set a placeholder.
Definition: Parser.php:3534
formatHeadings($text, $isMain=true)
This function accomplishes several tasks: 1) Auto-number headings if that option is enabled 2) Add an...
Definition: Parser.php:3582
replaceInternalLinks($s)
Process [[ ]] wikilinks.
Definition: Parser.php:1610
doAllQuotes($text)
Replace single quotes with HTML markup.
Definition: Parser.php:1176
static removeHTMLtags($text, $processCallback=null, $args=array())
Cleans up HTML, removes dangerous tags and attributes, and removes HTML comments. ...
Definition: Sanitizer.php:343
doTableStuff($text)
parse the wiki syntax used to render tables
Definition: Parser.php:843
$text
Definition: errorreport.php:18
Create styles array
The data for the language used.
replaceVariables($text, $args=array(), $argsOnly=false)
Replace magic variables, templates, and template arguments with the appropriate text.
Definition: Parser.php:2921
stripToc($text)
Detect TOC magic word and set a placeholder.
Definition: Parser.php:3545
+ Here is the caller graph for this function:

◆ internalTidy()

Parser::internalTidy (   $text)
static

Use the HTML tidy PECL extension to use the tidy library in-process, saving the overhead of spawning a new process.

Currently written to the PHP 4.3.x version of the extension, may not work on PHP 5.

'pear install tidy' should be able to compile the extension module.

Definition at line 817 of file Parser.php.

820  {
821  global $wgTidyConf;
822  $fname = 'Parser::internalTidy';
823  wfProfileIn($fname);
824 
825  tidy_load_config($wgTidyConf);
826  tidy_set_encoding('utf8');
827  tidy_parse_string($text);
828  tidy_clean_repair();
829  if (tidy_get_status() == 2) {
830  // 2 is magic number for fatal error
831  // http://www.php.net/manual/en/function.tidy-get-status.php
832  $cleansource = null;
833  } else {
834  $cleansource = tidy_get_output();
835  }
836  wfProfileOut($fname);
$text
Definition: errorreport.php:18

◆ interwikiTransclude()

Parser::interwikiTransclude (   $title,
  $action 
)

Transclude an interwiki link.

Definition at line 3443 of file Parser.php.

Referenced by createAssocArgs().

3446  {
3447  global $wgEnableScaryTranscluding;
3448 
3449  if (!$wgEnableScaryTranscluding) {
3450  return wfMsg('scarytranscludedisabled');
3451  }
3452 
3453  $url = $title->getFullUrl("action=$action");
3454 
3455  if (strlen($url) > 255) {
3456  return wfMsg('scarytranscludetoolong');
3457  }
wfMsg($x)
Definition: RandomTest.php:63
$url
+ Here is the caller graph for this function:

◆ magicLinkCallback()

Parser::magicLinkCallback (   $m)

Definition at line 1112 of file Parser.php.

References $h, $i, $id, $img, $m, $output, GuzzleHttp\Psr7\$protocol, $query, $r, $result, $ret, $s, $state, $target, $text, $url, areSubpagesAllowed(), armorLinks(), array, Sanitizer\cleanUrl(), closeParagraph(), Sanitizer\decodeCharReferences(), doAllQuotes(), doHeadings(), doQuotes(), EXT_IMAGE_REGEX, EXT_LINK_BRACKETED, EXT_LINK_URL_CLASS, getDefaultSort(), image, is, Title\legalChars(), makeImage(), makeKnownLinkHolder(), makeLinkHolder(), maybeDoSubpageLink(), maybeMakeExternalImage(), Title\newFromText(), NS_SPECIAL, replaceExternalLinks(), replaceFreeExternalLinks(), replaceInternalLinks(), replaceUnusualEscapes(), replaceUnusualEscapesCallback(), to, top, wfMsg(), and wfUrlProtocols().

1115  {
1116  if (substr($m[0], 0, 1) == '<') {
1117  # Skip HTML element
1118  return $m[0];
1119  } elseif (substr($m[0], 0, 4) == 'ISBN') {
1120  $isbn = $m[2];
1121  $num = strtr($isbn, array(
1122  '-' => '',
1123  ' ' => '',
1124  'x' => 'X',
1125  ));
1126  $titleObj = SpecialPage::getTitleFor('Booksources');
1127  $text = '<a href="' .
1128  $titleObj->escapeLocalUrl("isbn=$num") .
1129  "\" class=\"internal\">ISBN $isbn</a>";
1130  } else {
1131  if (substr($m[0], 0, 3) == 'RFC') {
1132  $keyword = 'RFC';
1133  $urlmsg = 'rfcurl';
1134  $id = $m[1];
1135  } elseif (substr($m[0], 0, 4) == 'PMID') {
1136  $keyword = 'PMID';
1137  $urlmsg = 'pubmedurl';
1138  $id = $m[1];
1139  } else {
1140  throw new MWException(__METHOD__ . ': unrecognised match type "' .
1141  substr($m[0], 0, 20) . '"');
1142  }
1143 
1144  $url = wfMsg($urlmsg, $id);
1145  $sk = $this->mOptions->getSkin();
1146  $la = $sk->getExternalLinkAttributes($url, $keyword . $id);
1147  $text = "<a href=\"{$url}\"{$la}>{$keyword} {$id}</a>";
1148  }
if(!array_key_exists('StateId', $_REQUEST)) $id
wfMsg($x)
Definition: RandomTest.php:63
$text
Definition: errorreport.php:18
Create styles array
The data for the language used.
$url
+ Here is the call graph for this function:

◆ makeImage()

Parser::makeImage (   $nt,
  $options 
)

Parse image options text and use it to make an image.

Definition at line 4598 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache(), and magicLinkCallback().

4601  {
4602  # @TODO: let the MediaHandler specify its transform parameters
4603  #
4604  # Check if the options text is of the form "options|alt text"
4605  # Options are:
4606  # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
4607  # * left no resizing, just left align. label is used for alt= only
4608  # * right same, but right aligned
4609  # * none same, but not aligned
4610  # * ___px scale to ___ pixels width, no aligning. e.g. use in taxobox
4611  # * center center the image
4612  # * framed Keep original image size, no magnify-button.
4613  # vertical-align values (no % or length right now):
4614  # * baseline
4615  # * sub
4616  # * super
4617  # * top
4618  # * text-top
4619  # * middle
4620  # * bottom
4621  # * text-bottom
4622 
4623 
4624  $part = array_map('trim', explode('|', $options));
4625 
4626  $mwAlign = array();
4627  $alignments = array( 'left', 'right', 'center', 'none', 'baseline', 'sub', 'super', 'top', 'text-top', 'middle', 'bottom', 'text-bottom' );
4628  foreach ($alignments as $alignment) {
4629  $mwAlign[$alignment] =&MagicWord::get('img_' . $alignment);
4630  }
4631  $mwThumb =&MagicWord::get('img_thumbnail');
4632  $mwManualThumb =&MagicWord::get('img_manualthumb');
4633  $mwWidth =&MagicWord::get('img_width');
4634  $mwFramed =&MagicWord::get('img_framed');
4635  $mwPage =&MagicWord::get('img_page');
4636  $caption = '';
4637 
4638  $params = array();
4639  $framed = $thumb = false;
4640  $manual_thumb = '' ;
4641  $align = $valign = '';
4642  $sk = $this->mOptions->getSkin();
4643 
4644  foreach ($part as $val) {
4645  if (!is_null($mwThumb->matchVariableStartToEnd($val))) {
4646  $thumb=true;
4647  } elseif (!is_null($match = $mwManualThumb->matchVariableStartToEnd($val))) {
4648  # use manually specified thumbnail
4649  $thumb=true;
4650  $manual_thumb = $match;
4651  } else {
4652  foreach ($alignments as $alignment) {
4653  if (!is_null($mwAlign[$alignment]->matchVariableStartToEnd($val))) {
4654  switch ($alignment) {
4655  case 'left': case 'right': case 'center': case 'none':
4656  $align = $alignment; break;
4657  default:
4658  $valign = $alignment;
4659  }
4660  continue 2;
4661  }
4662  }
4663  if (!is_null($match = $mwPage->matchVariableStartToEnd($val))) {
4664  # Select a page in a multipage document
4665  $params['page'] = $match;
4666  } elseif (!isset($params['width']) && !is_null($match = $mwWidth->matchVariableStartToEnd($val))) {
4667  wfDebug("img_width match: $match\n");
4668  # $match is the image width in pixels
4669  $m = array();
4670  if (preg_match('/^([0-9]*)x([0-9]*)$/', $match, $m)) {
4671  $params['width'] = intval($m[1]);
4672  $params['height'] = intval($m[2]);
4673  } else {
4674  $params['width'] = intval($match);
4675  }
4676  } elseif (!is_null($mwFramed->matchVariableStartToEnd($val))) {
4677  $framed=true;
4678  } else {
4679  $caption = $val;
4680  }
4681  }
4682  }
4683  # Strip bad stuff out of the alt text
4684  $alt = $this->replaceLinkHoldersText($caption);
4685 
4686  # make sure there are no placeholders in thumbnail attributes
4687  # that are later expanded to html- so expand them now and
4688  # remove the tags
4689  $alt = $this->mStripState->unstripBoth($alt);
4690  $alt = Sanitizer::stripAllTags($alt);
4691 
4692  # Linker does the rest
$params
Definition: disable.php:11
static stripAllTags($text)
Take a fragment of (potentially invalid) HTML and return a version with any tags removed, encoded as plain text.
Definition: Sanitizer.php:1255
replaceLinkHoldersText($text)
Replace link placeholders with plain text of links (not HTML-formatted).
Definition: Parser.php:4470
Create styles array
The data for the language used.
$alignments
Definition: example_063.php:81
if(!isset($_REQUEST['ReturnTo'])) if(!isset($_REQUEST['AuthId'])) $options
Definition: as_login.php:20
+ Here is the caller graph for this function:

◆ makeKnownLinkHolder()

Parser::makeKnownLinkHolder (   $nt,
  $text = '',
  $query = '',
  $trail = '',
  $prefix = '' 
)

Render a forced-blue link inline; protect against double expansion of URLs if we're in a mode that prepends full URL prefixes to internal links.

Since this little disaster has to split off the trail text to avoid breaking URLs in the following text without breaking trails on the wiki links, it's been made into a horrible function.

Parameters
Title$nt
string$text
string$query
string$trail
string$prefix
Returns
string HTML-wikitext mix oh yuck

Definition at line 1957 of file Parser.php.

Referenced by magicLinkCallback().

1960  {
1961  list($inside, $trail) = Linker::splitTrail($trail);
1962  $sk = $this->mOptions->getSkin();
1963  $link = $sk->makeKnownLinkObj($nt, $text, $query, $inside, $prefix);
$text
Definition: errorreport.php:18
$query
+ Here is the caller graph for this function:

◆ makeLinkHolder()

Parser::makeLinkHolder ( $nt,
  $text = '',
  $query = '',
  $trail = '',
  $prefix = '' 
)

Make a link placeholder.

The text returned can be later resolved to a real link with replaceLinkHolders(). This is done for two reasons: firstly to avoid further parsing of interwiki links, and secondly to allow all existence checks and article length checks (for stub links) to be bundled into a single query.

Definition at line 1915 of file Parser.php.

Referenced by magicLinkCallback().

1918  {
1919  wfProfileIn(__METHOD__);
1920  if (!is_object($nt)) {
1921  # Fail gracefully
1922  $retVal = "<!-- ERROR -->{$prefix}{$text}{$trail}";
1923  } else {
1924  # Separate the link trail from the rest of the link
1925  list($inside, $trail) = Linker::splitTrail($trail);
1926 
1927  if ($nt->isExternal()) {
1928  $nr = array_push($this->mInterwikiLinkHolders['texts'], $prefix . $text . $inside);
1929  $this->mInterwikiLinkHolders['titles'][] = $nt;
1930  $retVal = '<!--IWLINK ' . ($nr-1) . "-->{$trail}";
1931  } else {
1932  $nr = array_push($this->mLinkHolders['namespaces'], $nt->getNamespace());
1933  $this->mLinkHolders['dbkeys'][] = $nt->getDBkey();
1934  $this->mLinkHolders['queries'][] = $query;
1935  $this->mLinkHolders['texts'][] = $prefix . $text . $inside;
1936  $this->mLinkHolders['titles'][] = $nt;
1937 
1938  $retVal = '<!--LINK ' . ($nr-1) . "-->{$trail}";
1939  }
1940  }
1941  wfProfileOut(__METHOD__);
$text
Definition: errorreport.php:18
$query
+ Here is the caller graph for this function:

◆ maybeDoSubpageLink()

Parser::maybeDoSubpageLink (   $target,
$text 
)

Handle link to subpage if necessary.

Parameters
string$targetthe source of the link
string&$textthe link text, modified as necessary
Returns
string the full name of the link

Definition at line 2004 of file Parser.php.

Referenced by createAssocArgs(), and magicLinkCallback().

2007  {
2008  # Valid link forms:
2009  # Foobar -- normal
2010  # :Foobar -- override special treatment of prefix (images, language links)
2011  # /Foobar -- convert to CurrentPage/Foobar
2012  # /Foobar/ -- convert to CurrentPage/Foobar, strip the initial / from text
2013  # ../ -- convert to CurrentPage, from CurrentPage/CurrentSubPage
2014  # ../Foobar -- convert to CurrentPage/Foobar, from CurrentPage/CurrentSubPage
2015 
2016  $fname = 'Parser::maybeDoSubpageLink';
2017  wfProfileIn($fname);
2018  $ret = $target; # default return value is no change
2019 
2020  # bug 7425
2021  $target = trim($target);
2022 
2023  # Some namespaces don't allow subpages,
2024  # so only perform processing if subpages are allowed
2025  if ($this->areSubpagesAllowed()) {
2026  # Look at the first character
2027  if ($target != '' && $target{0} == '/') {
2028  # / at end means we don't want the slash to be shown
2029  $trailingSlashes = preg_match_all('%(/+)$%', $target, $m);
2030  if ($trailingSlashes) {
2031  $noslash = $target = substr($target, 1, -strlen($m[0][0]));
2032  } else {
2033  $noslash = substr($target, 1);
2034  }
2035 
2036  $ret = $this->mTitle->getPrefixedText() . '/' . trim($noslash);
2037  if ('' === $text) {
2038  $text = $target;
2039  } # this might be changed for ugliness reasons
2040  } else {
2041  # check for .. subpage backlinks
2042  $dotdotcount = 0;
2043  $nodotdot = $target;
2044  while (strncmp($nodotdot, "../", 3) == 0) {
2045  ++$dotdotcount;
2046  $nodotdot = substr($nodotdot, 3);
2047  }
2048  if ($dotdotcount > 0) {
2049  $exploded = explode('/', $this->mTitle->GetPrefixedText());
2050  if (count($exploded) > $dotdotcount) { # not allowed to go below top level page
2051  $ret = implode('/', array_slice($exploded, 0, -$dotdotcount));
2052  # / at the end means don't show full path
2053  if (substr($nodotdot, -1, 1) == '/') {
2054  $nodotdot = substr($nodotdot, 0, -1);
2055  if ('' === $text) {
2056  $text = $nodotdot;
2057  }
2058  }
2059  $nodotdot = trim($nodotdot);
2060  if ($nodotdot != '') {
2061  $ret .= '/' . $nodotdot;
2062  }
2063  }
2064  }
2065  }
2066  }
2067 
2068  wfProfileOut($fname);
File written to
Sum of both Ranges is
Definition: 03formulas.php:77
Rows to repeat at top
$text
Definition: errorreport.php:18
areSubpagesAllowed()
Return true if subpage links should be expanded on this page.
Definition: Parser.php:1990
$ret
Definition: parser.php:6
+ Here is the caller graph for this function:

◆ maybeMakeExternalImage()

Parser::maybeMakeExternalImage (   $url)

make an image if it's allowed, either through the global option or through the exception

Definition at line 1589 of file Parser.php.

Referenced by magicLinkCallback().

1592  {
1593  $sk = $this->mOptions->getSkin();
1594  $imagesfrom = $this->mOptions->getAllowExternalImagesFrom();
1595  $imagesexception = !empty($imagesfrom);
1596  $text = false;
1597  if ($this->mOptions->getAllowExternalImages()
1598  || ($imagesexception && strpos($url, $imagesfrom) === 0)) {
1599  if (preg_match(EXT_IMAGE_REGEX, $url)) {
1600  # Image found
1601  $text = $sk->makeExternalImage(htmlspecialchars($url));
1602  }
1603  }
const EXT_IMAGE_REGEX
Definition: Parser.php:42
$text
Definition: errorreport.php:18
$url
+ Here is the caller graph for this function:

◆ nextItem()

Parser::nextItem (   $char)

Definition at line 2125 of file Parser.php.

Referenced by closeList().

2128  {
2129  if ('*' == $char || '#' == $char) {
2130  return '</li><li>';
2131  } elseif (':' == $char || ';' == $char) {
2132  $close = '</dd>';
2133  if ($this->mDTopen) {
2134  $close = '</dt>';
2135  }
2136  if (';' == $char) {
2137  $this->mDTopen = true;
2138  return $close . '<dt>';
2139  } else {
2140  $this->mDTopen = false;
2141  return $close . '<dd>';
2142  }
2143  }
+ Here is the caller graph for this function:

◆ openList()

Parser::openList (   $char)

Definition at line 2105 of file Parser.php.

References $result, and closeParagraph().

Referenced by closeList().

2108  {
2109  $result = $this->closeParagraph();
2110 
2111  if ('*' == $char) {
2112  $result .= '<ul><li>';
2113  } elseif ('#' == $char) {
2114  $result .= '<ol><li>';
2115  } elseif (':' == $char) {
2116  $result .= '<dl><dd>';
2117  } elseif (';' == $char) {
2118  $result .= '<dl><dt>';
2119  $this->mDTopen = true;
2120  } else {
2121  $result = '<!-- ERR 1 -->';
2122  }
2123 
$result
closeParagraph()
#+ Used by doBlockLevels()
Definition: Parser.php:2074
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Options()

Parser::Options (   $x = null)

Definition at line 4728 of file Parser.php.

4731  {

◆ OutputType()

Parser::OutputType (   $x = null)

Definition at line 4732 of file Parser.php.

4735  {

◆ parse()

Parser::parse (   $text,
$title,
  $options,
  $linestart = true,
  $clearState = true,
  $revid = null 
)

Convert wikitext to HTML Do not call this function recursively.

Parameters
string$textText we want to parse
Title&$titleA title object
array$options
boolean$linestart
boolean$clearState
int$revidnumber to pass in {{REVISIONID}}
Returns
ParserOutput a ParserOutput

First pass–just handle <nowiki> sections, pass the rest off to internalParse() which does all the real work.

Definition at line 298 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache(), and setOutputType().

301  {
307  global $wgUseTidy, $wgAlwaysUseTidy, $wgContLang;
308  $fname = 'Parser::parse-' . wfGetCaller();
309  wfProfileIn(__METHOD__);
310  wfProfileIn($fname);
311 
312  if ($clearState) {
313  $this->clearState();
314  }
315 
316  $this->mOptions = $options;
317  $this->mTitle =&$title;
318  $oldRevisionId = $this->mRevisionId;
319  $oldRevisionTimestamp = $this->mRevisionTimestamp;
320  if ($revid !== null) {
321  $this->mRevisionId = $revid;
322  $this->mRevisionTimestamp = null;
323  }
324  $this->setOutputType(OT_HTML);
325  wfRunHooks('ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ));
326  $text = $this->strip($text, $this->mStripState);
327  wfRunHooks('ParserAfterStrip', array( &$this, &$text, &$this->mStripState ));
328  $text = $this->internalParse($text);
329  $text = $this->mStripState->unstripGeneral($text);
330 
331  # Clean up special characters, only run once, next-to-last before doBlockLevels
332  $fixtags = array(
333  # french spaces, last one Guillemet-left
334  # only if there is something before the space
335  '/(.) (?=\\?|:|;|!|\\302\\273)/' => '\\1&nbsp;\\2',
336  # french spaces, Guillemet-right
337  '/(\\302\\253) /' => '\\1&nbsp;',
338  );
339  $text = preg_replace(array_keys($fixtags), array_values($fixtags), $text);
340 
341  # only once and last
342  $text = $this->doBlockLevels($text, $linestart);
343 
344  $this->replaceLinkHolders($text);
345 
346  # the position of the parserConvert() call should not be changed. it
347  # assumes that the links are all replaced and the only thing left
348  # is the <nowiki> mark.
349  # Side-effects: this calls $this->mOutput->setTitleText()
350  $text = $wgContLang->parserConvert($text, $this);
351 
352  $text = $this->mStripState->unstripNoWiki($text);
353 
354  wfRunHooks('ParserBeforeTidy', array( &$this, &$text ));
355 
357 
358  if (($wgUseTidy and $this->mOptions->mTidy) or $wgAlwaysUseTidy) {
360  } else {
361  # attempt to sanitize at least some nesting problems
362  # (bug #2702 and quite a few others)
363  $tidyregs = array(
364  # ''Something [http://www.cool.com cool''] -->
365  # <i>Something</i><a href="http://www.cool.com"..><i>cool></i></a>
366  '/(<([bi])>)(<([bi])>)?([^<]*)(<\/?a[^<]*>)([^<]*)(<\/\\4>)?(<\/\\2>)/' =>
367  '\\1\\3\\5\\8\\9\\6\\1\\3\\7\\8\\9',
368  # fix up an anchor inside another anchor, only
369  # at least for a single single nested link (bug 3695)
370  '/(<a[^>]+>)([^<]*)(<a[^>]+>[^<]*)<\/a>(.*)<\/a>/' =>
371  '\\1\\2</a>\\3</a>\\1\\4</a>',
372  # fix div inside inline elements- doBlockLevels won't wrap a line which
373  # contains a div, so fix it up here; replace
374  # div with escaped text
375  '/(<([aib]) [^>]+>)([^<]*)(<div([^>]*)>)(.*)(<\/div>)([^<]*)(<\/\\2>)/' =>
376  '\\1\\3&lt;div\\5&gt;\\6&lt;/div&gt;\\8\\9',
377  # remove empty italic or bold tag pairs, some
378  # introduced by rules above
379  '/<([bi])><\/\\1>/' => '',
380  );
381 
382  $text = preg_replace(
383  array_keys($tidyregs),
384  array_values($tidyregs),
385  $text
386  );
387  }
388 
389  wfRunHooks('ParserAfterTidy', array( &$this, &$text ));
390 
391  # Information on include size limits, for the benefit of users who try to skirt them
392  if (max($this->mIncludeSizes) > 1000) {
393  $max = $this->mOptions->getMaxIncludeSize();
394  $text .= "<!-- \n" .
395  "Pre-expand include size: {$this->mIncludeSizes['pre-expand']} bytes\n" .
396  "Post-expand include size: {$this->mIncludeSizes['post-expand']} bytes\n" .
397  "Template argument size: {$this->mIncludeSizes['arg']} bytes\n" .
398  "Maximum: $max bytes\n" .
399  "-->\n";
400  }
401  $this->mOutput->setText($text);
402  $this->mRevisionId = $oldRevisionId;
403  $this->mRevisionTimestamp = $oldRevisionTimestamp;
404  wfProfileOut($fname);
405  wfProfileOut(__METHOD__);
406 
Sum of both Ranges is
Definition: 03formulas.php:77
clearState()
Clear Parser state.
Definition: Parser.php:211
up()
Definition: up.php:2
$mRevisionId
Definition: Parser.php:132
doBlockLevels($text, $linestart)
#-
Definition: Parser.php:2171
const OT_HTML
Definition: Parser.php:18
$mRevisionTimestamp
Definition: Parser.php:134
static http()
Fetches the global http state from ILIAS.
$text
Definition: errorreport.php:18
setOutputType($ot)
Definition: Parser.php:264
tidy($text)
Interface with html tidy, used if $wgUseTidy = true.
Definition: Parser.php:741
Create styles array
The data for the language used.
replaceLinkHolders(&$text, $options=0)
Replace link placeholders with actual links, in the buffer Placeholders created in Skin::makeLinkObj(...
Definition: Parser.php:4164
static normalizeCharReferences($text)
Ensure that any entities and character references are legal for XML and XHTML specifically.
Definition: Sanitizer.php:921
strip($text, $state, $stripcomments=false, $dontstrip=array())
Strips and renders nowiki, pre, math, hiero If $render is set, performs necessary rendering operation...
Definition: Parser.php:570
expand()
Definition: expand.php:2
internalParse($text)
Helper function for parse() that transforms wiki markup into HTML.
Definition: Parser.php:1032
if(!isset($_REQUEST['ReturnTo'])) if(!isset($_REQUEST['AuthId'])) $options
Definition: as_login.php:20
+ Here is the caller graph for this function:

◆ preprocess()

Parser::preprocess (   $text,
  $title,
  $options 
)

Expand templates and variables in the text, producing valid, static wikitext.

Also removes comments.

Definition at line 427 of file Parser.php.

430  {
431  wfProfileIn(__METHOD__);
432  $this->clearState();
434  $this->mOptions = $options;
435  $this->mTitle = $title;
436  wfRunHooks('ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ));
437  $text = $this->strip($text, $this->mStripState);
438  wfRunHooks('ParserAfterStrip', array( &$this, &$text, &$this->mStripState ));
439  if ($this->mOptions->getRemoveComments()) {
441  }
442  $text = $this->replaceVariables($text);
443  $text = $this->mStripState->unstripBoth($text);
444  wfProfileOut(__METHOD__);
clearState()
Clear Parser state.
Definition: Parser.php:211
$text
Definition: errorreport.php:18
setOutputType($ot)
Definition: Parser.php:264
Create styles array
The data for the language used.
replaceVariables($text, $args=array(), $argsOnly=false)
Replace magic variables, templates, and template arguments with the appropriate text.
Definition: Parser.php:2921
strip($text, $state, $stripcomments=false, $dontstrip=array())
Strips and renders nowiki, pre, math, hiero If $render is set, performs necessary rendering operation...
Definition: Parser.php:570
const OT_PREPROCESS
Definition: Parser.php:21
static removeHTMLcomments($text)
Remove &#39;&#39;, and everything between.
Definition: Sanitizer.php:533
if(!isset($_REQUEST['ReturnTo'])) if(!isset($_REQUEST['AuthId'])) $options
Definition: as_login.php:20

◆ preSaveTransform()

Parser::preSaveTransform (   $text,
$title,
  $user,
  $options,
  $clearState = true 
)

Transform wiki markup when saving a page by doing
->
conversion, substitting signatures, {{subst:}} templates, etc.

Parameters
string$textthe text to transform
Title&$titlethe Title object for the current article
User&$userthe User object describing the current user
ParserOptions$optionsparsing options
bool$clearStatewhether to clear the parser state first
Returns
string the altered wiki markup

Definition at line 3839 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

3842  {
3843  $this->mOptions = $options;
3844  $this->mTitle =&$title;
3845  $this->setOutputType(OT_WIKI);
3846 
3847  if ($clearState) {
3848  $this->clearState();
3849  }
3850 
3851  $stripState = new StripState;
3852  $pairs = array(
3853  "\r\n" => "\n",
3854  );
3855  $text = str_replace(array_keys($pairs), array_values($pairs), $text);
3856  $text = $this->strip($text, $stripState, true, array( 'gallery' ));
3857  $text = $this->pstPass2($text, $stripState, $user);
3858  $text = $stripState->unstripBoth($text);
clearState()
Clear Parser state.
Definition: Parser.php:211
const OT_WIKI
Definition: Parser.php:19
pstPass2($text, &$stripState, $user)
Pre-save transform helper function.
Definition: Parser.php:3864
$text
Definition: errorreport.php:18
setOutputType($ot)
Definition: Parser.php:264
Create styles array
The data for the language used.
strip($text, $state, $stripcomments=false, $dontstrip=array())
Strips and renders nowiki, pre, math, hiero If $render is set, performs necessary rendering operation...
Definition: Parser.php:570
if(!isset($_REQUEST['ReturnTo'])) if(!isset($_REQUEST['AuthId'])) $options
Definition: as_login.php:20
+ Here is the caller graph for this function:

◆ pstPass2()

Parser::pstPass2 (   $text,
$stripState,
  $user 
)

Pre-save transform helper function.

Definition at line 3864 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

3867  {
3868  global $wgContLang, $wgLocaltimezone;
3869 
3870  /* Note: This is the timestamp saved as hardcoded wikitext to
3871  * the database, we use $wgContLang here in order to give
3872  * everyone the same signature and use the default one rather
3873  * than the one selected in each user's preferences.
3874  */
3875  if (isset($wgLocaltimezone)) {
3876  $oldtz = getenv('TZ');
3877  putenv('TZ=' . $wgLocaltimezone);
3878  }
3879  $d = $wgContLang->timeanddate(date('YmdHis'), false, false) .
3880  ' (' . date('T') . ')';
3881  if (isset($wgLocaltimezone)) {
3882  putenv('TZ=' . $oldtz);
3883  }
3884 
3885  # Variable replacement
3886  # Because mOutputType is OT_WIKI, this will only process {{subst:xxx}} type tags
3887  $text = $this->replaceVariables($text);
3888 
3889  # Strip out <nowiki> etc. added via replaceVariables
3890  $text = $this->strip($text, $stripState, false, array( 'gallery' ));
3891 
3892  # Signatures
3893  $sigText = $this->getUserSig($user);
3894  $text = strtr($text, array(
3895  '~~~~~' => $d,
3896  '~~~~' => "$sigText $d",
3897  '~~~' => $sigText
3898  ));
3899 
3900  # Context links: [[|name]] and [[name (context)|]]
3901  #
3902  global $wgLegalTitleChars;
3903  $tc = "[$wgLegalTitleChars]";
3904  $nc = '[ _0-9A-Za-z\x80-\xff]'; # Namespaces can use non-ascii!
3905 
3906  $p1 = "/\[\[(:?$nc+:|:|)($tc+?)( \\($tc+\\))\\|]]/"; # [[ns:page (context)|]]
3907  $p3 = "/\[\[(:?$nc+:|:|)($tc+?)( \\($tc+\\)|)(, $tc+|)\\|]]/"; # [[ns:page (context), context|]]
3908  $p2 = "/\[\[\\|($tc+)]]/"; # [[|page]]
3909 
3910  # try $p1 first, to turn "[[A, B (C)|]]" into "[[A, B (C)|A, B]]"
3911  $text = preg_replace($p1, '[[\\1\\2\\3|\\2]]', $text);
3912  $text = preg_replace($p3, '[[\\1\\2\\3\\4|\\2]]', $text);
3913 
3914  $t = $this->mTitle->getText();
3915  $m = array();
3916  if (preg_match("/^($nc+:|)$tc+?( \\($tc+\\))$/", $t, $m)) {
3917  $text = preg_replace($p2, "[[$m[1]\\1$m[2]|\\1]]", $text);
3918  } elseif (preg_match("/^($nc+:|)$tc+?(, $tc+|)$/", $t, $m) && '' != "$m[1]$m[2]") {
3919  $text = preg_replace($p2, "[[$m[1]\\1$m[2]|\\1]]", $text);
3920  } else {
3921  # if there's no context, don't bother duplicating the title
3922  $text = preg_replace($p2, '[[\\1]]', $text);
3923  }
3924 
3925  # Trim trailing whitespace
3926  $text = rtrim($text);
3927 
getUserSig(&$user)
Fetch the user&#39;s signature text, if any, and normalize to validated, ready-to-insert wikitext...
Definition: Parser.php:3937
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
$text
Definition: errorreport.php:18
Create styles array
The data for the language used.
replaceVariables($text, $args=array(), $argsOnly=false)
Replace magic variables, templates, and template arguments with the appropriate text.
Definition: Parser.php:2921
strip($text, $state, $stripcomments=false, $dontstrip=array())
Strips and renders nowiki, pre, math, hiero If $render is set, performs necessary rendering operation...
Definition: Parser.php:570
for($i=6; $i< 13; $i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296
+ Here is the caller graph for this function:

◆ recursiveTagParse()

Parser::recursiveTagParse (   $text)

Recursive parser entry point that can be called from an extension tag hook.

Definition at line 412 of file Parser.php.

415  {
416  wfProfileIn(__METHOD__);
417  wfRunHooks('ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ));
418  $text = $this->strip($text, $this->mStripState);
419  wfRunHooks('ParserAfterStrip', array( &$this, &$text, &$this->mStripState ));
420  $text = $this->internalParse($text);
421  wfProfileOut(__METHOD__);
$text
Definition: errorreport.php:18
Create styles array
The data for the language used.
strip($text, $state, $stripcomments=false, $dontstrip=array())
Strips and renders nowiki, pre, math, hiero If $render is set, performs necessary rendering operation...
Definition: Parser.php:570
internalParse($text)
Helper function for parse() that transforms wiki markup into HTML.
Definition: Parser.php:1032

◆ renderImageGallery()

Parser::renderImageGallery (   $text,
  $params 
)

Renders an image gallery from a text with one line per image.

text labels may be given by using |-style alternative text. E.g. Image:one.jpg|The number "1" Image:tree.jpg|A tree given as text will return the HTML of a gallery with two images, labeled 'The number "1"' and 'A tree'.

Definition at line 4529 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

4532  {
4533  $ig = new ImageGallery();
4534  $ig->setContextTitle($this->mTitle);
4535  $ig->setShowBytes(false);
4536  $ig->setShowFilename(false);
4537  $ig->setParsing();
4538  $ig->useSkin($this->mOptions->getSkin());
4539 
4540  if (isset($params['caption'])) {
4541  $caption = $params['caption'];
4542  $caption = htmlspecialchars($caption);
4543  $caption = $this->replaceInternalLinks($caption);
4544  $ig->setCaptionHtml($caption);
4545  }
4546  if (isset($params['perrow'])) {
4547  $ig->setPerRow($params['perrow']);
4548  }
4549  if (isset($params['widths'])) {
4550  $ig->setWidths($params['widths']);
4551  }
4552  if (isset($params['heights'])) {
4553  $ig->setHeights($params['heights']);
4554  }
4555 
4556  $lines = explode("\n", $text);
4557  foreach ($lines as $line) {
4558  # match lines like these:
4559  # Image:someimage.jpg|This is some image
4560  $matches = array();
4561  preg_match("/^([^|]+)(\\|(.*))?$/", $line, $matches);
4562  # Skip empty lines
4563  if (count($matches) == 0) {
4564  continue;
4565  }
4566  $tp = Title::newFromText($matches[1]);
4567  $nt =&$tp;
4568  if (is_null($nt)) {
4569  # Bogus title. Ignore these so we don't bomb out later.
4570  continue;
4571  }
4572  if (isset($matches[3])) {
4573  $label = $matches[3];
4574  } else {
4575  $label = '';
4576  }
4577 
4578  $pout = $this->parse(
4579  $label,
4580  $this->mTitle,
4581  $this->mOptions,
4582  false, // Strip whitespace...?
4583  false // Don't clear state!
4584  );
4585  $html = $pout->getText();
4586 
4587  $ig->add(new Image($nt), $html);
4588 
4589  # Only add real images (bug #5586)
4590  if ($nt->getNamespace() == NS_IMAGE) {
4591  $this->mOutput->addImage($nt->getDBkey());
4592  }
4593  }
$params
Definition: disable.php:11
static newFromText($text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:124
replaceInternalLinks($s)
Process [[ ]] wikilinks.
Definition: Parser.php:1610
$text
Definition: errorreport.php:18
Create styles array
The data for the language used.
parse($text, &$title, $options, $linestart=true, $clearState=true, $revid=null)
Convert wikitext to HTML Do not call this function recursively.
Definition: Parser.php:298
$html
Definition: example_001.php:87
+ Here is the caller graph for this function:

◆ renderPreTag()

Parser::renderPreTag (   $text,
  $attribs 
)

Tag hook handler for 'pre'.

Definition at line 4509 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

4512  {
4513  // Backwards-compatibility hack
4514  $content = StringUtils::delimiterReplace('<nowiki>', '</nowiki>', '$1', $text, 'i');
4515 
4516  $attribs = Sanitizer::validateTagAttributes($attribs, 'pre');
4517  return wfOpenElement('pre', $attribs) .
4518  Xml::escapeTagsOnly($content) .
static validateTagAttributes($attribs, $element)
Take an array of attribute names and values and normalize or discard illegal values for the given ele...
Definition: Sanitizer.php:583
$text
Definition: errorreport.php:18
+ Here is the caller graph for this function:

◆ replace_callback()

Parser::replace_callback (   $text,
  $callbacks 
)

parse any parentheses in format ((title|part|part)) and call callbacks to get a replacement text for any found piece

Parameters
string$textThe text to parse
array$callbacksrules in form: '{' => array( # opening parentheses 'end' => '}', # closing parentheses 'cb' => array(2 => callback, # replacement callback to call if {{..}} is found 3 => callback # replacement callback to call if {{{..}}} is found ) ) 'min' => 2, # Minimum parenthesis count in cb 'max' => 3, # Maximum parenthesis count in cb

Definition at line 2734 of file Parser.php.

Referenced by closeList().

2737  {
2738  wfProfileIn(__METHOD__);
2739  $openingBraceStack = array(); # this array will hold a stack of parentheses which are not closed yet
2740  $lastOpeningBrace = -1; # last not closed parentheses
2741 
2742  $validOpeningBraces = implode('', array_keys($callbacks));
2743 
2744  $i = 0;
2745  while ($i < strlen($text)) {
2746  # Find next opening brace, closing brace or pipe
2747  if ($lastOpeningBrace == -1) {
2748  $currentClosing = '';
2749  $search = $validOpeningBraces;
2750  } else {
2751  $currentClosing = $openingBraceStack[$lastOpeningBrace]['braceEnd'];
2752  $search = $validOpeningBraces . '|' . $currentClosing;
2753  }
2754  $rule = null;
2755  $i += strcspn($text, $search, $i);
2756  if ($i < strlen($text)) {
2757  if ($text[$i] == '|') {
2758  $found = 'pipe';
2759  } elseif ($text[$i] == $currentClosing) {
2760  $found = 'close';
2761  } elseif (isset($callbacks[$text[$i]])) {
2762  $found = 'open';
2763  $rule = $callbacks[$text[$i]];
2764  } else {
2765  # Some versions of PHP have a strcspn which stops on null characters
2766  # Ignore and continue
2767  ++$i;
2768  continue;
2769  }
2770  } else {
2771  # All done
2772  break;
2773  }
2774 
2775  if ($found == 'open') {
2776  # found opening brace, let's add it to parentheses stack
2777  $piece = array('brace' => $text[$i],
2778  'braceEnd' => $rule['end'],
2779  'title' => '',
2780  'parts' => null);
2781 
2782  # count opening brace characters
2783  $piece['count'] = strspn($text, $piece['brace'], $i);
2784  $piece['startAt'] = $piece['partStart'] = $i + $piece['count'];
2785  $i += $piece['count'];
2786 
2787  # we need to add to stack only if opening brace count is enough for one of the rules
2788  if ($piece['count'] >= $rule['min']) {
2789  $lastOpeningBrace++;
2790  $openingBraceStack[$lastOpeningBrace] = $piece;
2791  }
2792  } elseif ($found == 'close') {
2793  # lets check if it is enough characters for closing brace
2794  $maxCount = $openingBraceStack[$lastOpeningBrace]['count'];
2795  $count = strspn($text, $text[$i], $i, $maxCount);
2796 
2797  # check for maximum matching characters (if there are 5 closing
2798  # characters, we will probably need only 3 - depending on the rules)
2799  $matchingCount = 0;
2800  $matchingCallback = null;
2801  $cbType = $callbacks[$openingBraceStack[$lastOpeningBrace]['brace']];
2802  if ($count > $cbType['max']) {
2803  # The specified maximum exists in the callback array, unless the caller
2804  # has made an error
2805  $matchingCount = $cbType['max'];
2806  } else {
2807  # Count is less than the maximum
2808  # Skip any gaps in the callback array to find the true largest match
2809  # Need to use array_key_exists not isset because the callback can be null
2810  $matchingCount = $count;
2811  while ($matchingCount > 0 && !array_key_exists($matchingCount, $cbType['cb'])) {
2812  --$matchingCount;
2813  }
2814  }
2815 
2816  if ($matchingCount <= 0) {
2817  $i += $count;
2818  continue;
2819  }
2820  $matchingCallback = $cbType['cb'][$matchingCount];
2821 
2822  # let's set a title or last part (if '|' was found)
2823  if (null === $openingBraceStack[$lastOpeningBrace]['parts']) {
2824  $openingBraceStack[$lastOpeningBrace]['title'] =
2825  substr(
2826  $text,
2827  $openingBraceStack[$lastOpeningBrace]['partStart'],
2828  $i - $openingBraceStack[$lastOpeningBrace]['partStart']
2829  );
2830  } else {
2831  $openingBraceStack[$lastOpeningBrace]['parts'][] =
2832  substr(
2833  $text,
2834  $openingBraceStack[$lastOpeningBrace]['partStart'],
2835  $i - $openingBraceStack[$lastOpeningBrace]['partStart']
2836  );
2837  }
2838 
2839  $pieceStart = $openingBraceStack[$lastOpeningBrace]['startAt'] - $matchingCount;
2840  $pieceEnd = $i + $matchingCount;
2841 
2842  if (is_callable($matchingCallback)) {
2843  $cbArgs = array(
2844  'text' => substr($text, $pieceStart, $pieceEnd - $pieceStart),
2845  'title' => trim($openingBraceStack[$lastOpeningBrace]['title']),
2846  'parts' => $openingBraceStack[$lastOpeningBrace]['parts'],
2847  'lineStart' => (($pieceStart > 0) && ($text[$pieceStart-1] == "\n")),
2848  );
2849  # finally we can call a user callback and replace piece of text
2850  $replaceWith = call_user_func($matchingCallback, $cbArgs);
2851  $text = substr($text, 0, $pieceStart) . $replaceWith . substr($text, $pieceEnd);
2852  $i = $pieceStart + strlen($replaceWith);
2853  } else {
2854  # null value for callback means that parentheses should be parsed, but not replaced
2855  $i += $matchingCount;
2856  }
2857 
2858  # reset last opening parentheses, but keep it in case there are unused characters
2859  $piece = array('brace' => $openingBraceStack[$lastOpeningBrace]['brace'],
2860  'braceEnd' => $openingBraceStack[$lastOpeningBrace]['braceEnd'],
2861  'count' => $openingBraceStack[$lastOpeningBrace]['count'],
2862  'title' => '',
2863  'parts' => null,
2864  'startAt' => $openingBraceStack[$lastOpeningBrace]['startAt']);
2865  $openingBraceStack[$lastOpeningBrace--] = null;
2866 
2867  if ($matchingCount < $piece['count']) {
2868  $piece['count'] -= $matchingCount;
2869  $piece['startAt'] -= $matchingCount;
2870  $piece['partStart'] = $piece['startAt'];
2871  # do we still qualify for any callback with remaining count?
2872  $currentCbList = $callbacks[$piece['brace']]['cb'];
2873  while ($piece['count']) {
2874  if (array_key_exists($piece['count'], $currentCbList)) {
2875  $lastOpeningBrace++;
2876  $openingBraceStack[$lastOpeningBrace] = $piece;
2877  break;
2878  }
2879  --$piece['count'];
2880  }
2881  }
2882  } elseif ($found == 'pipe') {
2883  # lets set a title if it is a first separator, or next part otherwise
2884  if (null === $openingBraceStack[$lastOpeningBrace]['parts']) {
2885  $openingBraceStack[$lastOpeningBrace]['title'] =
2886  substr(
2887  $text,
2888  $openingBraceStack[$lastOpeningBrace]['partStart'],
2889  $i - $openingBraceStack[$lastOpeningBrace]['partStart']
2890  );
2891  $openingBraceStack[$lastOpeningBrace]['parts'] = array();
2892  } else {
2893  $openingBraceStack[$lastOpeningBrace]['parts'][] =
2894  substr(
2895  $text,
2896  $openingBraceStack[$lastOpeningBrace]['partStart'],
2897  $i - $openingBraceStack[$lastOpeningBrace]['partStart']
2898  );
2899  }
2900  $openingBraceStack[$lastOpeningBrace]['partStart'] = ++$i;
2901  }
2902  }
2903 
2904  wfProfileOut(__METHOD__);
$rule
Definition: showstats.php:43
$text
Definition: errorreport.php:18
Create styles array
The data for the language used.
$i
Definition: disco.tpl.php:19
+ Here is the caller graph for this function:

◆ replaceExternalLinks()

Parser::replaceExternalLinks (   $text)

Replace external links.

Note: this is all very hackish and the order of execution matters a lot. Make sure to run maintenance/parserTests.php if you change this code.

Definition at line 1380 of file Parser.php.

Referenced by magicLinkCallback().

1383  {
1384  global $wgContLang;
1385  $fname = 'Parser::replaceExternalLinks';
1386  wfProfileIn($fname);
1387 
1388  $sk = $this->mOptions->getSkin();
1389 
1390  $bits = preg_split(EXT_LINK_BRACKETED, $text, -1, PREG_SPLIT_DELIM_CAPTURE);
1391 
1392  $s = $this->replaceFreeExternalLinks(array_shift($bits));
1393 
1394  $i = 0;
1395  while ($i<count($bits)) {
1396  $url = $bits[$i++];
1397  $protocol = $bits[$i++];
1398  $text = $bits[$i++];
1399  $trail = $bits[$i++];
1400 
1401  # The characters '<' and '>' (which were escaped by
1402  # removeHTMLtags()) should not be included in
1403  # URLs, per RFC 2396.
1404  $m2 = array();
1405  if (preg_match('/&(lt|gt);/', $url, $m2, PREG_OFFSET_CAPTURE)) {
1406  $text = substr($url, $m2[0][1]) . ' ' . $text;
1407  $url = substr($url, 0, $m2[0][1]);
1408  }
1409 
1410  # If the link text is an image URL, replace it with an <img> tag
1411  # This happened by accident in the original parser, but some people used it extensively
1412  $img = $this->maybeMakeExternalImage($text);
1413  if ($img !== false) {
1414  $text = $img;
1415  }
1416 
1417  $dtrail = '';
1418 
1419  # Set linktype for CSS - if URL==text, link is essentially free
1420  $linktype = ($text == $url) ? 'free' : 'text';
1421 
1422  # No link text, e.g. [http://domain.tld/some.link]
1423  if ($text == '') {
1424  # Autonumber if allowed. See bug #5918
1425  if (strpos(wfUrlProtocols(), substr($protocol, 0, strpos($protocol, ':'))) !== false) {
1426  $text = '[' . ++$this->mAutonumber . ']';
1427  $linktype = 'autonumber';
1428  } else {
1429  # Otherwise just use the URL
1430  $text = htmlspecialchars($url);
1431  $linktype = 'free';
1432  }
1433  } else {
1434  # Have link text, e.g. [http://domain.tld/some.link text]s
1435  # Check for trail
1436  list($dtrail, $trail) = Linker::splitTrail($trail);
1437  }
1438 
1439  $text = $wgContLang->markNoConversion($text);
1440 
1442 
1443  # Process the trail (i.e. everything after this link up until start of the next link),
1444  # replacing any non-bracketed links
1445  $trail = $this->replaceFreeExternalLinks($trail);
1446 
1447  # Use the encoded URL
1448  # This means that users can paste URLs directly into the text
1449  # Funny characters like &ouml; aren't valid in URLs anyway
1450  # This was changed in August 2004
1451  $s .= $sk->makeExternalLink($url, $text, false, $linktype, $this->mTitle->getNamespace()) . $dtrail . $trail;
1452 
1453  # Register link in the output object.
1454  # Replace unnecessary URL escape codes with the referenced character
1455  # This prevents spammers from hiding links from the filters
1456  $pasteurized = Parser::replaceUnusualEscapes($url);
1457  $this->mOutput->addExternalLink($pasteurized);
1458  }
1459 
1460  wfProfileOut($fname);
static replaceUnusualEscapes($url)
Replace unusual URL escape codes with their equivalent characters.
Definition: Parser.php:1554
$s
Definition: pwgen.php:45
const EXT_LINK_BRACKETED
Definition: Parser.php:40
static cleanUrl($url, $hostname=true)
Definition: Sanitizer.php:1288
$text
Definition: errorreport.php:18
maybeMakeExternalImage($url)
make an image if it&#39;s allowed, either through the global option or through the exception ...
Definition: Parser.php:1589
Create styles array
The data for the language used.
$i
Definition: disco.tpl.php:19
$url
replaceFreeExternalLinks($text)
Replace anything that looks like a URL with a link.
Definition: Parser.php:1466
wfUrlProtocols()
Returns a regular expression of url protocols.
+ Here is the caller graph for this function:

◆ replaceFreeExternalLinks()

Parser::replaceFreeExternalLinks (   $text)

Replace anything that looks like a URL with a link.

Definition at line 1466 of file Parser.php.

Referenced by magicLinkCallback().

1469  {
1470  global $wgContLang;
1471 
1472  $fname = 'Parser::replaceFreeExternalLinks';
1473  wfProfileIn($fname);
1474 
1475  $bits = preg_split('/(\b(?:' . wfUrlProtocols() . '))/S', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
1476  $s = array_shift($bits);
1477  $i = 0;
1478 
1479  $sk = $this->mOptions->getSkin();
1480 
1481  while ($i < count($bits)) {
1482  $protocol = $bits[$i++];
1483  $remainder = $bits[$i++];
1484 
1485  $m = array();
1486  if (preg_match('/^(' . EXT_LINK_URL_CLASS . '+)(.*)$/s', $remainder, $m)) {
1487  # Found some characters after the protocol that look promising
1488  $url = $protocol . $m[1];
1489  $trail = $m[2];
1490 
1491  # special case: handle urls as url args:
1492  # http://www.example.com/foo?=http://www.example.com/bar
1493  if (strlen($trail) == 0 &&
1494  isset($bits[$i]) &&
1495  preg_match('/^' . wfUrlProtocols() . '$/S', $bits[$i]) &&
1496  preg_match('/^(' . EXT_LINK_URL_CLASS . '+)(.*)$/s', $bits[$i + 1], $m)) {
1497  # add protocol, arg
1498  $url .= $bits[$i] . $m[1]; # protocol, url as arg to previous link
1499  $i += 2;
1500  $trail = $m[2];
1501  }
1502 
1503  # The characters '<' and '>' (which were escaped by
1504  # removeHTMLtags()) should not be included in
1505  # URLs, per RFC 2396.
1506  $m2 = array();
1507  if (preg_match('/&(lt|gt);/', $url, $m2, PREG_OFFSET_CAPTURE)) {
1508  $trail = substr($url, $m2[0][1]) . $trail;
1509  $url = substr($url, 0, $m2[0][1]);
1510  }
1511 
1512  # Move trailing punctuation to $trail
1513  $sep = ',;\.:!?';
1514  # If there is no left bracket, then consider right brackets fair game too
1515  if (strpos($url, '(') === false) {
1516  $sep .= ')';
1517  }
1518 
1519  $numSepChars = strspn(strrev($url), $sep);
1520  if ($numSepChars) {
1521  $trail = substr($url, -$numSepChars) . $trail;
1522  $url = substr($url, 0, -$numSepChars);
1523  }
1524 
1526  # Is this an external image?
1527  $text = $this->maybeMakeExternalImage($url);
1528  if ($text === false) {
1529  # Not an image, make a link
1530  $text = $sk->makeExternalLink($url, $wgContLang->markNoConversion($url), true, 'free', $this->mTitle->getNamespace());
1531  # Register it in the output object...
1532  # Replace unnecessary URL escape codes with their equivalent characters
1533  $pasteurized = Parser::replaceUnusualEscapes($url);
1534 
1535  $this->mOutput->addExternalLink($pasteurized);
1536  }
1537  $s .= $text . $trail;
1538  } else {
1539  $s .= $protocol . $remainder;
1540  }
1541  }
1542  wfProfileOut($fname);
File written to
static replaceUnusualEscapes($url)
Replace unusual URL escape codes with their equivalent characters.
Definition: Parser.php:1554
$s
Definition: pwgen.php:45
static cleanUrl($url, $hostname=true)
Definition: Sanitizer.php:1288
$text
Definition: errorreport.php:18
maybeMakeExternalImage($url)
make an image if it&#39;s allowed, either through the global option or through the exception ...
Definition: Parser.php:1589
Create styles array
The data for the language used.
$i
Definition: disco.tpl.php:19
$url
const EXT_LINK_URL_CLASS
Definition: Parser.php:35
wfUrlProtocols()
Returns a regular expression of url protocols.
+ Here is the caller graph for this function:

◆ replaceInternalLinks()

Parser::replaceInternalLinks (   $s)

Process [[ ]] wikilinks.

Strip the whitespace Category links produce, see bug 87

Todo:
We might want to use trim($tmp, "\n") here.

Definition at line 1610 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache(), and magicLinkCallback().

1613  {
1614  global $wgContLang;
1615  static $fname = 'Parser::replaceInternalLinks' ;
1616 
1617  wfProfileIn($fname);
1618 
1619  wfProfileIn($fname . '-setup');
1620  static $tc = false;
1621  # the % is needed to support urlencoded titles as well
1622  if (!$tc) {
1623  $tc = Title::legalChars() . '#%';
1624  }
1625 
1626  $sk = $this->mOptions->getSkin();
1627 
1628  #split the entire text string on occurences of [[
1629  $a = explode('[[', ' ' . $s);
1630  #get the first element (all text up to first [[), and remove the space we added
1631  $s = array_shift($a);
1632  $s = substr($s, 1);
1633 
1634  # Match a link having the form [[namespace:link|alternate]]trail
1635  static $e1 = false;
1636  if (!$e1) {
1637  $e1 = "/^([{$tc}]+)(?:\\|(.+?))?]](.*)\$/sD";
1638  }
1639  # Match cases where there is no "]]", which might still be images
1640  static $e1_img = false;
1641  if (!$e1_img) {
1642  $e1_img = "/^([{$tc}]+)\\|(.*)\$/sD";
1643  }
1644  # Match the end of a line for a word that's not followed by whitespace,
1645  # e.g. in the case of 'The Arab al[[Razi]]', 'al' will be matched
1646  $e2 = wfMsgForContent('linkprefix');
1647 
1648  $useLinkPrefixExtension = $wgContLang->linkPrefixExtension();
1649  if (is_null($this->mTitle)) {
1650  throw new MWException(__METHOD__ . ": \$this->mTitle is null\n");
1651  }
1652  $nottalk = !$this->mTitle->isTalkPage();
1653 
1654  if ($useLinkPrefixExtension) {
1655  $m = array();
1656  if (preg_match($e2, $s, $m)) {
1657  $first_prefix = $m[2];
1658  } else {
1659  $first_prefix = false;
1660  }
1661  } else {
1662  $prefix = '';
1663  }
1664 
1665  if ($wgContLang->hasVariants()) {
1666  $selflink = $wgContLang->convertLinkToAllVariants($this->mTitle->getPrefixedText());
1667  } else {
1668  $selflink = array($this->mTitle->getPrefixedText());
1669  }
1670  $useSubpages = $this->areSubpagesAllowed();
1671  wfProfileOut($fname . '-setup');
1672 
1673  # Loop for each link
1674  for ($k = 0; isset($a[$k]); $k++) {
1675  $line = $a[$k];
1676  if ($useLinkPrefixExtension) {
1677  wfProfileIn($fname . '-prefixhandling');
1678  if (preg_match($e2, $s, $m)) {
1679  $prefix = $m[2];
1680  $s = $m[1];
1681  } else {
1682  $prefix='';
1683  }
1684  # first link
1685  if ($first_prefix) {
1686  $prefix = $first_prefix;
1687  $first_prefix = false;
1688  }
1689  wfProfileOut($fname . '-prefixhandling');
1690  }
1691 
1692  $might_be_img = false;
1693 
1694  wfProfileIn("$fname-e1");
1695  if (preg_match($e1, $line, $m)) { # page with normal text or alt
1696  $text = $m[2];
1697  # If we get a ] at the beginning of $m[3] that means we have a link that's something like:
1698  # [[Image:Foo.jpg|[http://example.com desc]]] <- having three ] in a row fucks up,
1699  # the real problem is with the $e1 regex
1700  # See bug 1300.
1701  #
1702  # Still some problems for cases where the ] is meant to be outside punctuation,
1703  # and no image is in sight. See bug 2095.
1704  #
1705  if ($text !== '' &&
1706  substr($m[3], 0, 1) === ']' &&
1707  strpos($text, '[') !== false
1708  ) {
1709  $text .= ']'; # so that replaceExternalLinks($text) works later
1710  $m[3] = substr($m[3], 1);
1711  }
1712  # fix up urlencoded title texts
1713  if (strpos($m[1], '%') !== false) {
1714  # Should anchors '#' also be rejected?
1715  $m[1] = str_replace(array('<', '>'), array('&lt;', '&gt;'), urldecode($m[1]));
1716  }
1717  $trail = $m[3];
1718  } elseif (preg_match($e1_img, $line, $m)) { # Invalid, but might be an image with a link in its caption
1719  $might_be_img = true;
1720  $text = $m[2];
1721  if (strpos($m[1], '%') !== false) {
1722  $m[1] = urldecode($m[1]);
1723  }
1724  $trail = "";
1725  } else { # Invalid form; output directly
1726  $s .= $prefix . '[[' . $line ;
1727  wfProfileOut("$fname-e1");
1728  continue;
1729  }
1730  wfProfileOut("$fname-e1");
1731  wfProfileIn("$fname-misc");
1732 
1733  # Don't allow internal links to pages containing
1734  # PROTO: where PROTO is a valid URL protocol; these
1735  # should be external links.
1736  if (preg_match('/^\b(?:' . wfUrlProtocols() . ')/', $m[1])) {
1737  $s .= $prefix . '[[' . $line ;
1738  continue;
1739  }
1740 
1741  # Make subpage if necessary
1742  if ($useSubpages) {
1743  $link = $this->maybeDoSubpageLink($m[1], $text);
1744  } else {
1745  $link = $m[1];
1746  }
1747 
1748  $noforce = (substr($m[1], 0, 1) != ':');
1749  if (!$noforce) {
1750  # Strip off leading ':'
1751  $link = substr($link, 1);
1752  }
1753 
1754  wfProfileOut("$fname-misc");
1755  wfProfileIn("$fname-title");
1756  $nt = Title::newFromText($this->mStripState->unstripNoWiki($link));
1757  if (!$nt) {
1758  $s .= $prefix . '[[' . $line;
1759  wfProfileOut("$fname-title");
1760  continue;
1761  }
1762 
1763  $ns = $nt->getNamespace();
1764  $iw = $nt->getInterWiki();
1765  wfProfileOut("$fname-title");
1766 
1767  if ($might_be_img) { # if this is actually an invalid link
1768  wfProfileIn("$fname-might_be_img");
1769  if ($ns == NS_IMAGE && $noforce) { #but might be an image
1770  $found = false;
1771  while (isset($a[$k+1])) {
1772  #look at the next 'line' to see if we can close it there
1773  $spliced = array_splice($a, $k + 1, 1);
1774  $next_line = array_shift($spliced);
1775  $m = explode(']]', $next_line, 3);
1776  if (count($m) == 3) {
1777  # the first ]] closes the inner link, the second the image
1778  $found = true;
1779  $text .= "[[{$m[0]}]]{$m[1]}";
1780  $trail = $m[2];
1781  break;
1782  } elseif (count($m) == 2) {
1783  #if there's exactly one ]] that's fine, we'll keep looking
1784  $text .= "[[{$m[0]}]]{$m[1]}";
1785  } else {
1786  #if $next_line is invalid too, we need look no further
1787  $text .= '[[' . $next_line;
1788  break;
1789  }
1790  }
1791  if (!$found) {
1792  # we couldn't find the end of this imageLink, so output it raw
1793  #but don't ignore what might be perfectly normal links in the text we've examined
1794  $text = $this->replaceInternalLinks($text);
1795  $s .= "{$prefix}[[$link|$text";
1796  # note: no $trail, because without an end, there *is* no trail
1797  wfProfileOut("$fname-might_be_img");
1798  continue;
1799  }
1800  } else { #it's not an image, so output it raw
1801  $s .= "{$prefix}[[$link|$text";
1802  # note: no $trail, because without an end, there *is* no trail
1803  wfProfileOut("$fname-might_be_img");
1804  continue;
1805  }
1806  wfProfileOut("$fname-might_be_img");
1807  }
1808 
1809  $wasblank = ('' == $text);
1810  if ($wasblank) {
1811  $text = $link;
1812  }
1813 
1814  # Link not escaped by : , create the various objects
1815  if ($noforce) {
1816 
1817  # Interwikis
1818  wfProfileIn("$fname-interwiki");
1819  if ($iw && $this->mOptions->getInterwikiMagic() && $nottalk && $wgContLang->getLanguageName($iw)) {
1820  $this->mOutput->addLanguageLink($nt->getFullText());
1821  $s = rtrim($s . $prefix);
1822  $s .= trim($trail, "\n") == '' ? '': $prefix . $trail;
1823  wfProfileOut("$fname-interwiki");
1824  continue;
1825  }
1826  wfProfileOut("$fname-interwiki");
1827 
1828  if ($ns == NS_IMAGE) {
1829  wfProfileIn("$fname-image");
1830  if (!wfIsBadImage($nt->getDBkey(), $this->mTitle)) {
1831  # recursively parse links inside the image caption
1832  # actually, this will parse them in any other parameters, too,
1833  # but it might be hard to fix that, and it doesn't matter ATM
1834  $text = $this->replaceExternalLinks($text);
1835  $text = $this->replaceInternalLinks($text);
1836 
1837  # cloak any absolute URLs inside the image markup, so replaceExternalLinks() won't touch them
1838  $s .= $prefix . $this->armorLinks($this->makeImage($nt, $text)) . $trail;
1839  $this->mOutput->addImage($nt->getDBkey());
1840 
1841  wfProfileOut("$fname-image");
1842  continue;
1843  } else {
1844  # We still need to record the image's presence on the page
1845  $this->mOutput->addImage($nt->getDBkey());
1846  }
1847  wfProfileOut("$fname-image");
1848  }
1849 
1850  if ($ns == NS_CATEGORY) {
1851  wfProfileIn("$fname-category");
1852  $s = rtrim($s . "\n"); # bug 87
1853 
1854  if ($wasblank) {
1855  $sortkey = $this->getDefaultSort();
1856  } else {
1857  $sortkey = $text;
1858  }
1859  $sortkey = Sanitizer::decodeCharReferences($sortkey);
1860  $sortkey = str_replace("\n", '', $sortkey);
1861  $sortkey = $wgContLang->convertCategoryKey($sortkey);
1862  $this->mOutput->addCategory($nt->getDBkey(), $sortkey);
1863 
1868  $s .= trim($prefix . $trail, "\n") == '' ? '': $prefix . $trail;
1869 
1870  wfProfileOut("$fname-category");
1871  continue;
1872  }
1873  }
1874 
1875  # Self-link checking
1876  if ($nt->getFragment() === '') {
1877  if (in_array($nt->getPrefixedText(), $selflink, true)) {
1878  $s .= $prefix . $sk->makeSelfLinkObj($nt, $text, '', $trail);
1879  continue;
1880  }
1881  }
1882 
1883  # Special and Media are pseudo-namespaces; no pages actually exist in them
1884  if ($ns == NS_MEDIA) {
1885  $link = $sk->makeMediaLinkObj($nt, $text);
1886  # Cloak with NOPARSE to avoid replacement in replaceExternalLinks
1887  $s .= $prefix . $this->armorLinks($link) . $trail;
1888  $this->mOutput->addImage($nt->getDBkey());
1889  continue;
1890  } elseif ($ns == NS_SPECIAL) {
1891  $s .= $this->makeKnownLinkHolder($nt, $text, '', $trail, $prefix);
1892  continue;
1893  } elseif ($ns == NS_IMAGE) {
1894  $img = new Image($nt);
1895  if ($img->exists()) {
1896  // Force a blue link if the file exists; may be a remote
1897  // upload on the shared repository, and we want to see its
1898  // auto-generated page.
1899  $s .= $this->makeKnownLinkHolder($nt, $text, '', $trail, $prefix);
1900  $this->mOutput->addLink($nt);
1901  continue;
1902  }
1903  }
1904  $s .= $this->makeLinkHolder($nt, $text, '', $trail, $prefix);
1905  }
1906  wfProfileOut($fname);
replaceExternalLinks($text)
Replace external links.
Definition: Parser.php:1380
Sum of both Ranges is
Definition: 03formulas.php:77
static newFromText($text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:124
$s
Definition: pwgen.php:45
maybeDoSubpageLink($target, &$text)
Handle link to subpage if necessary.
Definition: Parser.php:2004
static decodeCharReferences($text)
Decode any character references, numeric or named entities, in the text and return a UTF-8 string...
Definition: Sanitizer.php:1018
makeLinkHolder(&$nt, $text='', $query='', $trail='', $prefix='')
Make a link placeholder.
Definition: Parser.php:1915
replaceInternalLinks($s)
Process [[ ]] wikilinks.
Definition: Parser.php:1610
makeImage($nt, $options)
Parse image options text and use it to make an image.
Definition: Parser.php:4598
Generate an image
makeKnownLinkHolder($nt, $text='', $query='', $trail='', $prefix='')
Render a forced-blue link inline; protect against double expansion of URLs if we&#39;re in a mode that pr...
Definition: Parser.php:1957
const NS_SPECIAL
Definition: Title.php:16
$text
Definition: errorreport.php:18
armorLinks($text)
Insert a NOPARSE hacky thing into any inline links in a chunk that&#39;s going to go through further pars...
Definition: Parser.php:1977
areSubpagesAllowed()
Return true if subpage links should be expanded on this page.
Definition: Parser.php:1990
Create styles array
The data for the language used.
static legalChars()
Get a regex character class describing the legal characters in a link.
Definition: Title.php:355
getDefaultSort()
Accessor for $mDefaultSort Will use the title/prefixed title if none is set.
Definition: Parser.php:4947
wfUrlProtocols()
Returns a regular expression of url protocols.
+ Here is the caller graph for this function:

◆ replaceLinkHolders()

Parser::replaceLinkHolders ( $text,
  $options = 0 
)

Replace link placeholders with actual links, in the buffer Placeholders created in Skin::makeLinkObj() Returns an array of links found, indexed by PDBK: 0 - broken 1 - normal link 2 - stub $options is a bit field, RLH_FOR_UPDATE to select for update.

Definition at line 4164 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache(), and setOutputType().

4167  {
4168  global $wgUser;
4169  global $wgContLang;
4170 
4171  $fname = 'Parser::replaceLinkHolders';
4172  wfProfileIn($fname);
4173 
4174  $pdbks = array();
4175  $colours = array();
4176  $sk = $this->mOptions->getSkin();
4177  $linkCache =&LinkCache::singleton();
4178 
4179  if (!empty($this->mLinkHolders['namespaces'])) {
4180  wfProfileIn($fname . '-check');
4181  $dbr = wfGetDB(DB_SLAVE);
4182  $page = $dbr->tableName('page');
4183  $threshold = $wgUser->getOption('stubthreshold');
4184 
4185  # Sort by namespace
4186  asort($this->mLinkHolders['namespaces']);
4187 
4188  # Generate query
4189  $query = false;
4190  $current = null;
4191  foreach ($this->mLinkHolders['namespaces'] as $key => $ns) {
4192  # Make title object
4193  $title = $this->mLinkHolders['titles'][$key];
4194 
4195  # Skip invalid entries.
4196  # Result will be ugly, but prevents crash.
4197  if (is_null($title)) {
4198  continue;
4199  }
4200  $pdbk = $pdbks[$key] = $title->getPrefixedDBkey();
4201 
4202  # Check if it's a static known link, e.g. interwiki
4203  if ($title->isAlwaysKnown()) {
4204  $colours[$pdbk] = 1;
4205  } elseif (($id = $linkCache->getGoodLinkID($pdbk)) != 0) {
4206  $colours[$pdbk] = 1;
4207  $this->mOutput->addLink($title, $id);
4208  } elseif ($linkCache->isBadLink($pdbk)) {
4209  $colours[$pdbk] = 0;
4210  } else {
4211  # Not in the link cache, add it to the query
4212  if (!isset($current)) {
4213  $current = $ns;
4214  $query = "SELECT page_id, page_namespace, page_title";
4215  if ($threshold > 0) {
4216  $query .= ', page_len, page_is_redirect';
4217  }
4218  $query .= " FROM $page WHERE (page_namespace=$ns AND page_title IN(";
4219  } elseif ($current != $ns) {
4220  $current = $ns;
4221  $query .= ")) OR (page_namespace=$ns AND page_title IN(";
4222  } else {
4223  $query .= ', ';
4224  }
4225 
4226  $query .= $dbr->addQuotes($this->mLinkHolders['dbkeys'][$key]);
4227  }
4228  }
4229  if ($query) {
4230  $query .= '))';
4231  if ($options & RLH_FOR_UPDATE) {
4232  $query .= ' FOR UPDATE';
4233  }
4234 
4235  $res = $dbr->query($query, $fname);
4236 
4237  # Fetch data and form into an associative array
4238  # non-existent = broken
4239  # 1 = known
4240  # 2 = stub
4241  while ($s = $dbr->fetchObject($res)) {
4242  $title = Title::makeTitle($s->page_namespace, $s->page_title);
4243  $pdbk = $title->getPrefixedDBkey();
4244  $linkCache->addGoodLinkObj($s->page_id, $title);
4245  $this->mOutput->addLink($title, $s->page_id);
4246 
4247  if ($threshold > 0) {
4248  $size = $s->page_len;
4249  if ($s->page_is_redirect || $s->page_namespace != 0 || $size >= $threshold) {
4250  $colours[$pdbk] = 1;
4251  } else {
4252  $colours[$pdbk] = 2;
4253  }
4254  } else {
4255  $colours[$pdbk] = 1;
4256  }
4257  }
4258  }
4259  wfProfileOut($fname . '-check');
4260 
4261  # Do a second query for different language variants of links and categories
4262  if ($wgContLang->hasVariants()) {
4263  $linkBatch = new LinkBatch();
4264  $variantMap = array(); // maps $pdbkey_Variant => $keys (of link holders)
4265  $categoryMap = array(); // maps $category_variant => $category (dbkeys)
4266  $varCategories = array(); // category replacements oldDBkey => newDBkey
4267 
4268  $categories = $this->mOutput->getCategoryLinks();
4269 
4270  // Add variants of links to link batch
4271  foreach ($this->mLinkHolders['namespaces'] as $key => $ns) {
4272  $title = $this->mLinkHolders['titles'][$key];
4273  if (is_null($title)) {
4274  continue;
4275  }
4276 
4277  $pdbk = $title->getPrefixedDBkey();
4278  $titleText = $title->getText();
4279 
4280  // generate all variants of the link title text
4281  $allTextVariants = $wgContLang->convertLinkToAllVariants($titleText);
4282 
4283  // if link was not found (in first query), add all variants to query
4284  if (!isset($colours[$pdbk])) {
4285  foreach ($allTextVariants as $textVariant) {
4286  if ($textVariant != $titleText) {
4287  $variantTitle = Title::makeTitle($ns, $textVariant);
4288  if (is_null($variantTitle)) {
4289  continue;
4290  }
4291  $linkBatch->addObj($variantTitle);
4292  $variantMap[$variantTitle->getPrefixedDBkey()][] = $key;
4293  }
4294  }
4295  }
4296  }
4297 
4298  // process categories, check if a category exists in some variant
4299  foreach ($categories as $category) {
4300  $variants = $wgContLang->convertLinkToAllVariants($category);
4301  foreach ($variants as $variant) {
4302  if ($variant != $category) {
4303  $variantTitle = Title::newFromDBkey(Title::makeName(NS_CATEGORY, $variant));
4304  if (is_null($variantTitle)) {
4305  continue;
4306  }
4307  $linkBatch->addObj($variantTitle);
4308  $categoryMap[$variant] = $category;
4309  }
4310  }
4311  }
4312 
4313 
4314  if (!$linkBatch->isEmpty()) {
4315  // construct query
4316  $titleClause = $linkBatch->constructSet('page', $dbr);
4317 
4318  $variantQuery = "SELECT page_id, page_namespace, page_title";
4319  if ($threshold > 0) {
4320  $variantQuery .= ', page_len, page_is_redirect';
4321  }
4322 
4323  $variantQuery .= " FROM $page WHERE $titleClause";
4324  if ($options & RLH_FOR_UPDATE) {
4325  $variantQuery .= ' FOR UPDATE';
4326  }
4327 
4328  $varRes = $dbr->query($variantQuery, $fname);
4329 
4330  // for each found variants, figure out link holders and replace
4331  while ($s = $dbr->fetchObject($varRes)) {
4332  $variantTitle = Title::makeTitle($s->page_namespace, $s->page_title);
4333  $varPdbk = $variantTitle->getPrefixedDBkey();
4334  $vardbk = $variantTitle->getDBkey();
4335 
4336  $holderKeys = array();
4337  if (isset($variantMap[$varPdbk])) {
4338  $holderKeys = $variantMap[$varPdbk];
4339  $linkCache->addGoodLinkObj($s->page_id, $variantTitle);
4340  $this->mOutput->addLink($variantTitle, $s->page_id);
4341  }
4342 
4343  // loop over link holders
4344  foreach ($holderKeys as $key) {
4345  $title = $this->mLinkHolders['titles'][$key];
4346  if (is_null($title)) {
4347  continue;
4348  }
4349 
4350  $pdbk = $title->getPrefixedDBkey();
4351 
4352  if (!isset($colours[$pdbk])) {
4353  // found link in some of the variants, replace the link holder data
4354  $this->mLinkHolders['titles'][$key] = $variantTitle;
4355  $this->mLinkHolders['dbkeys'][$key] = $variantTitle->getDBkey();
4356 
4357  // set pdbk and colour
4358  $pdbks[$key] = $varPdbk;
4359  if ($threshold > 0) {
4360  $size = $s->page_len;
4361  if ($s->page_is_redirect || $s->page_namespace != 0 || $size >= $threshold) {
4362  $colours[$varPdbk] = 1;
4363  } else {
4364  $colours[$varPdbk] = 2;
4365  }
4366  } else {
4367  $colours[$varPdbk] = 1;
4368  }
4369  }
4370  }
4371 
4372  // check if the object is a variant of a category
4373  if (isset($categoryMap[$vardbk])) {
4374  $oldkey = $categoryMap[$vardbk];
4375  if ($oldkey != $vardbk) {
4376  $varCategories[$oldkey]=$vardbk;
4377  }
4378  }
4379  }
4380 
4381  // rebuild the categories in original order (if there are replacements)
4382  if (count($varCategories)>0) {
4383  $newCats = array();
4384  $originalCats = $this->mOutput->getCategories();
4385  foreach ($originalCats as $cat => $sortkey) {
4386  // make the replacement
4387  if (array_key_exists($cat, $varCategories)) {
4388  $newCats[$varCategories[$cat]] = $sortkey;
4389  } else {
4390  $newCats[$cat] = $sortkey;
4391  }
4392  }
4393  $this->mOutput->setCategoryLinks($newCats);
4394  }
4395  }
4396  }
4397 
4398  # Construct search and replace arrays
4399  wfProfileIn($fname . '-construct');
4400  $replacePairs = array();
4401  foreach ($this->mLinkHolders['namespaces'] as $key => $ns) {
4402  $pdbk = $pdbks[$key];
4403  $searchkey = "<!--LINK $key-->";
4404  $title = $this->mLinkHolders['titles'][$key];
4405  if (empty($colours[$pdbk])) {
4406  $linkCache->addBadLinkObj($title);
4407  $colours[$pdbk] = 0;
4408  $this->mOutput->addLink($title, 0);
4409  $replacePairs[$searchkey] = $sk->makeBrokenLinkObj(
4410  $title,
4411  $this->mLinkHolders['texts'][$key],
4412  $this->mLinkHolders['queries'][$key]
4413  );
4414  } elseif ($colours[$pdbk] == 1) {
4415  $replacePairs[$searchkey] = $sk->makeKnownLinkObj(
4416  $title,
4417  $this->mLinkHolders['texts'][$key],
4418  $this->mLinkHolders['queries'][$key]
4419  );
4420  } elseif ($colours[$pdbk] == 2) {
4421  $replacePairs[$searchkey] = $sk->makeStubLinkObj(
4422  $title,
4423  $this->mLinkHolders['texts'][$key],
4424  $this->mLinkHolders['queries'][$key]
4425  );
4426  }
4427  }
4428  $replacer = new HashtableReplacer($replacePairs, 1);
4429  wfProfileOut($fname . '-construct');
4430 
4431  # Do the thing
4432  wfProfileIn($fname . '-replace');
4433  $text = preg_replace_callback(
4434  '/(<!--LINK .*?-->)/',
4435  $replacer->cb(),
4436  $text
4437  );
4438 
4439  wfProfileOut($fname . '-replace');
4440  }
4441 
4442  # Now process interwiki link holders
4443  # This is quite a bit simpler than internal links
4444  if (!empty($this->mInterwikiLinkHolders['texts'])) {
4445  wfProfileIn($fname . '-interwiki');
4446  # Make interwiki link HTML
4447  $replacePairs = array();
4448  foreach ($this->mInterwikiLinkHolders['texts'] as $key => $link) {
4449  $title = $this->mInterwikiLinkHolders['titles'][$key];
4450  $replacePairs[$key] = $sk->makeLinkObj($title, $link);
4451  }
4452  $replacer = new HashtableReplacer($replacePairs, 1);
4453 
4454  $text = preg_replace_callback(
4455  '/<!--IWLINK (.*?)-->/',
4456  $replacer->cb(),
4457  $text
4458  );
4459  wfProfileOut($fname . '-interwiki');
4460  }
4461 
4462  wfProfileOut($fname);
$size
Definition: RandomTest.php:84
if(!array_key_exists('StateId', $_REQUEST)) $id
$s
Definition: pwgen.php:45
static makeName($ns, $title)
Definition: Title.php:400
static newFromDBkey($key)
Create a new Title from a prefixed DB key.
Definition: Title.php:102
foreach($_POST as $key=> $value) $res
const RLH_FOR_UPDATE
Definition: Parser.php:15
$text
Definition: errorreport.php:18
$query
Create styles array
The data for the language used.
static & makeTitle($ns, $title)
Create a new Title from a namespace index and a DB key.
Definition: Title.php:253
$key
Definition: croninfo.php:18
if(!isset($_REQUEST['ReturnTo'])) if(!isset($_REQUEST['AuthId'])) $options
Definition: as_login.php:20
+ Here is the caller graph for this function:

◆ replaceLinkHoldersText()

Parser::replaceLinkHoldersText (   $text)

Replace link placeholders with plain text of links (not HTML-formatted).

Parameters
string$text
Returns
string

Definition at line 4470 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

4473  {
4474  $fname = 'Parser::replaceLinkHoldersText';
4475  wfProfileIn($fname);
4476 
4477  $text = preg_replace_callback(
4478  '/<!--(LINK|IWLINK) (.*?)-->/',
4479  array( &$this, 'replaceLinkHoldersTextCallback' ),
4480  $text
4481  );
4482 
4483  wfProfileOut($fname);
$text
Definition: errorreport.php:18
Create styles array
The data for the language used.
+ Here is the caller graph for this function:

◆ replaceLinkHoldersTextCallback()

Parser::replaceLinkHoldersTextCallback (   $matches)
Parameters
array$matches
Returns
string

Definition at line 4490 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

4493  {
4494  $type = $matches[1];
4495  $key = $matches[2];
4496  if ($type == 'LINK') {
4497  if (isset($this->mLinkHolders['texts'][$key])) {
4498  return $this->mLinkHolders['texts'][$key];
4499  }
4500  } elseif ($type == 'IWLINK') {
4501  if (isset($this->mInterwikiLinkHolders['texts'][$key])) {
4502  return $this->mInterwikiLinkHolders['texts'][$key];
4503  }
4504  }
$type
$key
Definition: croninfo.php:18
+ Here is the caller graph for this function:

◆ replaceSection()

Parser::replaceSection (   $oldtext,
  $section,
  $text 
)

Definition at line 4890 of file Parser.php.

References $mDefaultSort, $mRevisionTimestamp, $section, $text, $timestamp, array, extractSections(), getDefaultSort(), getRevisionTimestamp(), and setDefaultSort().

4893  {
+ Here is the call graph for this function:

◆ replaceUnusualEscapes()

static Parser::replaceUnusualEscapes (   $url)
static

Replace unusual URL escape codes with their equivalent characters.

Parameters
string
Returns
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.

Definition at line 1554 of file Parser.php.

Referenced by magicLinkCallback().

1557  {
1558  return preg_replace_callback(
1559  '/%[0-9A-Fa-f]{2}/',
1560  array( 'Parser', 'replaceUnusualEscapesCallback' ),
1561  $url
Create styles array
The data for the language used.
$url
+ Here is the caller graph for this function:

◆ replaceUnusualEscapesCallback()

static Parser::replaceUnusualEscapesCallback (   $matches)
staticprivate

Callback function used in replaceUnusualEscapes().

Replaces unusual URL escape codes with their equivalent character

Definition at line 1569 of file Parser.php.

Referenced by magicLinkCallback().

1572  {
1573  $char = urldecode($matches[0]);
1574  $ord = ord($char);
1575 
1576  // Is it an unsafe or HTTP reserved character according to RFC 1738?
1577  if ($ord > 32 && $ord < 127 && strpos('<>"#{}|\^~[]`;/?', $char) === false) {
1578  // No, shouldn't be escaped
1579  return $char;
1580  } else {
1581  // Yes, leave it escaped
1582  return $matches[0];
+ Here is the caller graph for this function:

◆ replaceVariables()

Parser::replaceVariables (   $text,
  $args = array(),
  $argsOnly = false 
)

Replace magic variables, templates, and template arguments with the appropriate text.

Templates are substituted recursively, taking care to avoid infinite loops.

Note that the substitution depends on value of $mOutputType: OT_WIKI: only {{subst:}} templates OT_MSG: only magic variables OT_HTML: all templates and magic variables

Parameters
string$texThe text to transform
array$argsKey-value pairs representing template parameters to substitute
bool$argsOnlyOnly do argument (triple-brace) expansion, not double-brace expansion

Definition at line 2921 of file Parser.php.

Referenced by closeList(), createAssocArgs(), and fetchScaryTemplateMaybeFromCache().

2924  {
2925  # Prevent too big inclusions
2926  if (strlen($text) > $this->mOptions->getMaxIncludeSize()) {
2927  return $text;
2928  }
2929 
2930  $fname = __METHOD__ /*. '-L' . count( $this->mArgStack )*/;
2931  wfProfileIn($fname);
2932 
2933  # This function is called recursively. To keep track of arguments we need a stack:
2934  array_push($this->mArgStack, $args);
2935 
2936  $braceCallbacks = array();
2937  if (!$argsOnly) {
2938  $braceCallbacks[2] = array( &$this, 'braceSubstitution' );
2939  }
2940  if ($this->mOutputType != OT_MSG) {
2941  $braceCallbacks[3] = array( &$this, 'argSubstitution' );
2942  }
2943  if ($braceCallbacks) {
2944  $callbacks = array(
2945  '{' => array(
2946  'end' => '}',
2947  'cb' => $braceCallbacks,
2948  'min' => $argsOnly ? 3 : 2,
2949  'max' => isset($braceCallbacks[3]) ? 3 : 2,
2950  ),
2951  '[' => array(
2952  'end' => ']',
2953  'cb' => array(2=>null),
2954  'min' => 2,
2955  'max' => 2,
2956  )
2957  );
2958  $text = $this->replace_callback($text, $callbacks);
2959 
2960  array_pop($this->mArgStack);
2961  }
2962  wfProfileOut($fname);
replace_callback($text, $callbacks)
parse any parentheses in format ((title|part|part)) and call callbacks to get a replacement text for ...
Definition: Parser.php:2734
$text
Definition: errorreport.php:18
const OT_MSG
Definition: Parser.php:20
Create styles array
The data for the language used.
+ Here is the caller graph for this function:

◆ setDefaultSort()

Parser::setDefaultSort (   $sort)

Mutator for $mDefaultSort.

Parameters
$sortNew value

Definition at line 4936 of file Parser.php.

Referenced by replaceSection().

4939  {
+ Here is the caller graph for this function:

◆ setFunctionHook()

Parser::setFunctionHook (   $id,
  $callback,
  $flags = 0 
)

Create a function, e.g.

{{sum:1|2|3}} The callback function should have the form: function myParserFunction( &$parser, $arg1, $arg2, $arg3 ) { ... }

The callback may either return the text result of the function, or an array with the text in element 0, and a number of flags in the other elements. The names of the flags are specified in the keys. Valid flags are: found The text returned is valid, stop processing the template. This is on by default. nowiki Wiki markup in the return value should be escaped noparse Unsafe HTML tags should not be stripped, etc. noargs Don't replace triple-brace arguments in the return value isHTML The returned text is HTML, armour it against wikitext transformation

Parameters
string$idThe magic word ID
mixed$callbackThe callback function (and object) to use
integer$flagsa combination of the following flags: SFH_NO_HASH No leading hash, i.e. {{plural:...}} instead of {{if:...}}
Returns
The old callback function for this name, if any

Definition at line 4113 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

4116  {
4117  $oldVal = isset($this->mFunctionHooks[$id]) ? $this->mFunctionHooks[$id] : null;
4118  $this->mFunctionHooks[$id] = $callback;
4119 
4120  # Add to function cache
4121  $mw = MagicWord::get($id);
4122  if (!$mw) {
4123  throw new MWException('Parser::setFunctionHook() expecting a magic word identifier.');
4124  }
4125 
4126  $synonyms = $mw->getSynonyms();
4127  $sensitive = intval($mw->isCaseSensitive());
4128 
4129  foreach ($synonyms as $syn) {
4130  # Case
4131  if (!$sensitive) {
4132  $syn = strtolower($syn);
4133  }
4134  # Add leading hash
4135  if (!($flags & SFH_NO_HASH)) {
4136  $syn = '#' . $syn;
4137  }
4138  # Remove trailing colon
4139  if (substr($syn, -1, 1) == ':') {
4140  $syn = substr($syn, 0, -1);
4141  }
4142  $this->mFunctionSynonyms[$sensitive][$syn] = $id;
4143  }
if(!array_key_exists('StateId', $_REQUEST)) $id
const SFH_NO_HASH
Definition: Parser.php:24
+ Here is the caller graph for this function:

◆ setHook()

Parser::setHook (   $tag,
  $callback 
)

Create an HTML-style tag, e.g.

<yourtag>special text</yourtag> The callback should have the following form: function myParserHook( $text, $params, &$parser ) { ... }

Transform and return $text. Use $parser for any required context, e.g. use $parser->getTitle() and $parser->getOptions() not $wgTitle or $wgOut->mParserOptions

Parameters
mixed$tagThe tag to use, e.g. 'hook' for <hook>
mixed$callbackThe callback function (and object) to use for the tag
Returns
The old value of the mTagHooks array associated with the hook

Definition at line 4080 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

4083  {
4084  $tag = strtolower($tag);
4085  $oldVal = isset($this->mTagHooks[$tag]) ? $this->mTagHooks[$tag] : null;
4086  $this->mTagHooks[$tag] = $callback;
4087 
if(function_exists('posix_getuid') &&posix_getuid()===0) if(!array_key_exists('t', $options)) $tag
Definition: cron.php:35
+ Here is the caller graph for this function:

◆ setOutputType()

Parser::setOutputType (   $ot)

Definition at line 264 of file Parser.php.

References $mRevisionId, $mRevisionTimestamp, $mUniqPrefix, $options, $ot, $text, $title, array, clearState(), doBlockLevels(), expand(), ILIAS\FileDelivery\http(), internalParse(), is, Sanitizer\normalizeCharReferences(), OT_HTML, OT_MSG, OT_PREPROCESS, OT_WIKI, parse(), replaceLinkHolders(), strip(), tidy(), uniqPrefix(), and up().

Referenced by fetchScaryTemplateMaybeFromCache().

267  {
268  $this->mOutputType = $ot;
269  // Shortcut alias
270  $this->ot = array(
271  'html' => $ot == OT_HTML,
272  'wiki' => $ot == OT_WIKI,
273  'msg' => $ot == OT_MSG,
274  'pre' => $ot == OT_PREPROCESS,
const OT_WIKI
Definition: Parser.php:19
const OT_HTML
Definition: Parser.php:18
const OT_MSG
Definition: Parser.php:20
Create styles array
The data for the language used.
const OT_PREPROCESS
Definition: Parser.php:21
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ startExternalParse()

Parser::startExternalParse ( $title,
  $options,
  $outputType,
  $clearState = true 
)

Set up some variables which are usually set up in parse() so that an external function can call some class members with confidence.

Definition at line 4017 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

4020  {
4021  $this->mTitle =&$title;
4022  $this->mOptions = $options;
4023  $this->setOutputType($outputType);
4024  if ($clearState) {
4025  $this->clearState();
clearState()
Clear Parser state.
Definition: Parser.php:211
setOutputType($ot)
Definition: Parser.php:264
if(!isset($_REQUEST['ReturnTo'])) if(!isset($_REQUEST['AuthId'])) $options
Definition: as_login.php:20
+ Here is the caller graph for this function:

◆ strip()

Parser::strip (   $text,
  $state,
  $stripcomments = false,
  $dontstrip = array() 
)

Strips and renders nowiki, pre, math, hiero If $render is set, performs necessary rendering operations on plugins Returns the text, and fills an array with data needed in unstrip()

Parameters
StripState$state
bool$stripcommentswhen set, HTML comments will be stripped in addition to other tags. This is important for section editing, where these comments cause confusion when counting the sections in the wikisource
arraydontstrip contains tags which should not be stripped; used to prevent stipping of <gallery> when saving (fixes bug 2700)

Definition at line 570 of file Parser.php.

Referenced by createAssocArgs(), fetchScaryTemplateMaybeFromCache(), and setOutputType().

573  {
574  global $wgContLang;
575  wfProfileIn(__METHOD__);
576  $render = ($this->mOutputType == OT_HTML);
577 
578  $uniq_prefix = $this->mUniqPrefix;
579  $commentState = new ReplacementArray;
580  $nowikiItems = array();
581  $generalItems = array();
582 
583  $elements = array_merge(
584  array( 'nowiki', 'gallery' ),
585  array_keys($this->mTagHooks)
586  );
587  global $wgRawHtml;
588  if ($wgRawHtml) {
589  $elements[] = 'html';
590  }
591  if ($this->mOptions->getUseTeX()) {
592  $elements[] = 'math';
593  }
594 
595  # Removing $dontstrip tags from $elements list (currently only 'gallery', fixing bug 2700)
596  foreach ($elements as $k => $v) {
597  if (!in_array($v, $dontstrip)) {
598  continue;
599  }
600  unset($elements[$k]);
601  }
602 
603  $matches = array();
604  $text = Parser::extractTagsAndParams($elements, $text, $matches, $uniq_prefix);
605 
606  foreach ($matches as $marker => $data) {
607  list($element, $content, $params, $tag) = $data;
608  if ($render) {
609  $tagName = strtolower($element);
610  wfProfileIn(__METHOD__ . "-render-$tagName");
611  switch ($tagName) {
612  case '!--':
613  // Comment
614  if (substr($tag, -3) == '-->') {
615  $output = $tag;
616  } else {
617  // Unclosed comment in input.
618  // Close it so later stripping can remove it
619  $output = "$tag-->";
620  }
621  break;
622  case 'html':
623  if ($wgRawHtml) {
624  $output = $content;
625  break;
626  }
627  // Shouldn't happen otherwise. :)
628  // no break
629  case 'nowiki':
630  $output = Xml::escapeTagsOnly($content);
631  break;
632  case 'math':
633  $output = $wgContLang->armourMath(MathRenderer::renderMath($content));
634  break;
635  case 'gallery':
636  $output = $this->renderImageGallery($content, $params);
637  break;
638  default:
639  if (isset($this->mTagHooks[$tagName])) {
640  $output = call_user_func_array(
641  $this->mTagHooks[$tagName],
642  array( $content, $params, $this )
643  );
644  } else {
645  throw new MWException("Invalid call hook $element");
646  }
647  }
648  wfProfileOut(__METHOD__ . "-render-$tagName");
649  } else {
650  // Just stripping tags; keep the source
651  $output = $tag;
652  }
653 
654  // Unstrip the output, to support recursive strip() calls
655  $output = $state->unstripBoth($output);
656 
657  if (!$stripcomments && $element == '!--') {
658  $commentState->setPair($marker, $output);
659  } elseif ($element == 'html' || $element == 'nowiki') {
660  $nowikiItems[$marker] = $output;
661  } else {
662  $generalItems[$marker] = $output;
663  }
664  }
665  # Add the new items to the state
666  # We do this after the loop instead of during it to avoid slowing
667  # down the recursive unstrip
668  $state->nowiki->mergeArray($nowikiItems);
669  $state->general->mergeArray($generalItems);
670 
671  # Unstrip comments unless explicitly told otherwise.
672  # (The comments are always stripped prior to this point, so as to
673  # not invoke any extension tags / parser hooks contained within
674  # a comment.)
675  if (!$stripcomments) {
676  // Put them all back and forget them
677  $text = $commentState->replace($text);
678  }
679 
680  wfProfileOut(__METHOD__);
$params
Definition: disable.php:11
renderImageGallery($text, $params)
Renders an image gallery from a text with one line per image.
Definition: Parser.php:4529
const OT_HTML
Definition: Parser.php:18
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\+" &#(? foreach( $entity_files as $file) $output
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Definition: linkback.php:10
$mUniqPrefix
Definition: Parser.php:113
$text
Definition: errorreport.php:18
Create styles array
The data for the language used.
extractTagsAndParams($elements, $text, &$matches, $uniq_prefix='')
Replaces all occurrences of HTML-style comments and the given tags in the text with a random marker a...
Definition: Parser.php:490
if(function_exists('posix_getuid') &&posix_getuid()===0) if(!array_key_exists('t', $options)) $tag
Definition: cron.php:35
+ Here is the caller graph for this function:

◆ stripNoGallery()

Parser::stripNoGallery ( $text)

Detect NOGALLERY magic word and set a placeholder.

Definition at line 3534 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

3537  {
3538  # if the string __NOGALLERY__ (not case-sensitive) occurs in the HTML,
3539  # do not add TOC
3540  $mw = MagicWord::get('nogallery');
+ Here is the caller graph for this function:

◆ stripToc()

Parser::stripToc (   $text)

Detect TOC magic word and set a placeholder.

Definition at line 3545 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

3548  {
3549  # if the string __NOTOC__ (not case-sensitive) occurs in the HTML,
3550  # do not add TOC
3551  $mw = MagicWord::get('notoc');
3552  if ($mw->matchAndRemove($text)) {
3553  $this->mShowToc = false;
3554  }
3555 
3556  $mw = MagicWord::get('toc');
3557  if ($mw->match($text)) {
3558  $this->mShowToc = true;
3559  $this->mForceTocPosition = true;
3560 
3561  // Set a placeholder. At the end we'll fill it in with the TOC.
3562  $text = $mw->replace('<!--MWTOC-->', $text, 1);
3563 
3564  // Only keep the first one.
3565  $text = $mw->replace('', $text);
3566  }
$text
Definition: errorreport.php:18
+ Here is the caller graph for this function:

◆ tidy()

Parser::tidy (   $text)
static

Interface with html tidy, used if $wgUseTidy = true.

If tidy isn't able to correct the markup, the original will be returned in all its glory with a warning comment appended.

Either the external tidy program or the in-process tidy extension will be used depending on availability. Override the default $wgTidyInternal setting to disable the internal if it's not working.

Parameters
string$textHideous HTML input
Returns
string Corrected HTML output

Definition at line 741 of file Parser.php.

Referenced by setOutputType().

744  {
745  global $wgTidyInternal;
746  $wrappedtext = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' .
747 ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>' .
748 '<head><title>test</title></head><body>' . $text . '</body></html>';
749  if ($wgTidyInternal) {
750  $correctedtext = Parser::internalTidy($wrappedtext);
751  } else {
752  $correctedtext = Parser::externalTidy($wrappedtext);
753  }
754  if (is_null($correctedtext)) {
755  wfDebug("Tidy error detected!\n");
756  return $text . "\n<!-- Tidy found serious XHTML errors -->\n";
757  }
internalTidy($text)
Use the HTML tidy PECL extension to use the tidy library in-process, saving the overhead of spawning ...
Definition: Parser.php:817
externalTidy($text)
Spawn an external HTML tidy process and get corrected markup back from it.
Definition: Parser.php:765
$text
Definition: errorreport.php:18
+ Here is the caller graph for this function:

◆ Title()

Parser::Title (   $x = null)

#-

#+ Accessor/mutator

Definition at line 4724 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

4727  {
+ Here is the caller graph for this function:

◆ transformMsg()

Parser::transformMsg (   $text,
  $options 
)

Transform a MediaWiki message by replacing magic variables.

Parameters
string$textthe text to transform
ParserOptions$optionsoptions
Returns
string the text with variables substituted

Definition at line 4035 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

4038  {
4039  global $wgTitle;
4040  static $executing = false;
4041 
4042  $fname = "Parser::transformMsg";
4043 
4044  # Guard against infinite recursion
4045  if ($executing) {
4046  return $text;
4047  }
4048  $executing = true;
4049 
4050  wfProfileIn($fname);
4051 
4052  if ($wgTitle && !($wgTitle instanceof FakeTitle)) {
4053  $this->mTitle = $wgTitle;
4054  } else {
4055  $this->mTitle = Title::newFromText('msg');
4056  }
4057  $this->mOptions = $options;
4058  $this->setOutputType(OT_MSG);
4059  $this->clearState();
4060  $text = $this->replaceVariables($text);
4061 
4062  $executing = false;
4063  wfProfileOut($fname);
clearState()
Clear Parser state.
Definition: Parser.php:211
static newFromText($text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:124
$text
Definition: errorreport.php:18
setOutputType($ot)
Definition: Parser.php:264
const OT_MSG
Definition: Parser.php:20
replaceVariables($text, $args=array(), $argsOnly=false)
Replace magic variables, templates, and template arguments with the appropriate text.
Definition: Parser.php:2921
if(!isset($_REQUEST['ReturnTo'])) if(!isset($_REQUEST['AuthId'])) $options
Definition: as_login.php:20
+ Here is the caller graph for this function:

◆ uniqPrefix()

Parser::uniqPrefix ( )

Accessor for mUniqPrefix.

Definition at line 281 of file Parser.php.

Referenced by setOutputType().

284  {
+ Here is the caller graph for this function:

◆ unstrip()

Parser::unstrip (   $text,
  $state 
)

Restores pre, math, and other extensions removed by strip()

always call unstripNoWiki() after this one

Deprecated:
use $this->mStripState->unstrip()

Definition at line 689 of file Parser.php.

692  {

◆ unstripForHTML()

Parser::unstripForHTML (   $text)
Deprecated:
use $this->mStripState->unstripBoth()

Definition at line 708 of file Parser.php.

711  {

◆ unstripNoWiki()

Parser::unstripNoWiki (   $text,
  $state 
)

Always call this after unstrip() to preserve the order.

Deprecated:
use $this->mStripState->unstrip()

Definition at line 700 of file Parser.php.

703  {

◆ validateSig()

Parser::validateSig (   $text)

Check that the user's signature contains no bad XML.

Parameters
string$text
Returns
mixed An expanded string, or false if invalid.

Definition at line 3969 of file Parser.php.

Referenced by fetchScaryTemplateMaybeFromCache().

3972  {
+ Here is the caller graph for this function:

◆ variableSubstitution()

Parser::variableSubstitution (   $matches)

Replace magic variables.

Definition at line 2968 of file Parser.php.

Referenced by closeList(), and createAssocArgs().

2971  {
2972  global $wgContLang;
2973  $fname = 'Parser::variableSubstitution';
2974  $varname = $wgContLang->lc($matches[1]);
2975  wfProfileIn($fname);
2976  $skip = false;
2977  if ($this->mOutputType == OT_WIKI) {
2978  # Do only magic variables prefixed by SUBST
2979  $mwSubst =&MagicWord::get('subst');
2980  if (!$mwSubst->matchStartAndRemove($varname)) {
2981  $skip = true;
2982  }
2983  # Note that if we don't substitute the variable below,
2984  # we don't remove the {{subst:}} magic word, in case
2985  # it is a template rather than a magic variable.
2986  }
2987  if (!$skip && array_key_exists($varname, $this->mVariables)) {
2988  $id = $this->mVariables[$varname];
2989  # Now check if we did really match, case sensitive or not
2990  $mw =&MagicWord::get($id);
2991  if ($mw->match($matches[1])) {
2992  $text = $this->getVariableValue($id);
2993  $this->mOutput->mContainsOldMagic = true;
2994  } else {
2995  $text = $matches[0];
2996  }
2997  } else {
2998  $text = $matches[0];
2999  }
3000  wfProfileOut($fname);
if(!array_key_exists('StateId', $_REQUEST)) $id
const OT_WIKI
Definition: Parser.php:19
$text
Definition: errorreport.php:18
getVariableValue($index)
Return value of a magic variable (like PAGENAME)
Definition: Parser.php:2506
+ Here is the caller graph for this function:

Field Documentation

◆ $mArgStack

Parser::$mArgStack

Definition at line 108 of file Parser.php.

◆ $mAutonumber

Parser::$mAutonumber

Definition at line 104 of file Parser.php.

◆ $mDefaultSort

Parser::$mDefaultSort

Definition at line 115 of file Parser.php.

Referenced by replaceSection().

◆ $mDTopen

Parser::$mDTopen

Definition at line 105 of file Parser.php.

◆ $mFunctionHooks

Parser::$mFunctionHooks

Definition at line 98 of file Parser.php.

◆ $mFunctionSynonyms

Parser::$mFunctionSynonyms

Definition at line 99 of file Parser.php.

◆ $mIncludeCount

Parser::$mIncludeCount

Definition at line 107 of file Parser.php.

◆ $mIncludeSizes

Parser::$mIncludeSizes

Definition at line 114 of file Parser.php.

◆ $mInPre

Parser::$mInPre

Definition at line 110 of file Parser.php.

◆ $mInterwikiLinkHolders

Parser::$mInterwikiLinkHolders

Definition at line 111 of file Parser.php.

◆ $mLastSection

Parser::$mLastSection

Definition at line 109 of file Parser.php.

◆ $mLinkHolders

Parser::$mLinkHolders

Definition at line 112 of file Parser.php.

◆ $mOptions

Parser::$mOptions

Definition at line 124 of file Parser.php.

◆ $mOutput

Parser::$mOutput

Definition at line 103 of file Parser.php.

◆ $mOutputType

Parser::$mOutputType

Definition at line 128 of file Parser.php.

◆ $mRevIdForTs

Parser::$mRevIdForTs

Definition at line 136 of file Parser.php.

◆ $mRevisionId

Parser::$mRevisionId

Definition at line 132 of file Parser.php.

Referenced by closeList(), and setOutputType().

◆ $mRevisionTimestamp

Parser::$mRevisionTimestamp

Definition at line 134 of file Parser.php.

Referenced by replaceSection(), and setOutputType().

◆ $mStripState

Parser::$mStripState

Definition at line 106 of file Parser.php.

◆ $mTagHooks

Parser::$mTagHooks

#+

Definition at line 97 of file Parser.php.

◆ $mTemplatePath

Parser::$mTemplatePath

Definition at line 119 of file Parser.php.

Referenced by createAssocArgs().

◆ $mTemplates

Parser::$mTemplates

Definition at line 116 of file Parser.php.

◆ $mTitle

Parser::$mTitle

Definition at line 126 of file Parser.php.

◆ $mUniqPrefix

Parser::$mUniqPrefix

Definition at line 113 of file Parser.php.

Referenced by setOutputType().

◆ $mVariables

Parser::$mVariables

Definition at line 100 of file Parser.php.

◆ $ot

Parser::$ot

Definition at line 130 of file Parser.php.

Referenced by setOutputType().

◆ VERSION

const Parser::VERSION = MW_PARSER_VERSION

Definition at line 92 of file Parser.php.


The documentation for this class was generated from the following file: