Go Back   vb.org Archive > Community Discussions > Modification Requests/Questions (Unpaid)
FAQ Community Calendar Today's Posts Search

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #9  
Old 12-21-2007, 03:45 PM
faqcorner faqcorner is offline
 
Join Date: Apr 2007
Posts: 28
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

*sigh* bumpy

found the parse code in the mediawiki distros...

Quote:
/**
* 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
*
* @param string $tex The text to transform
* @param array $args Key-value pairs representing template parameters to substitute
* @param bool $argsOnly Only do argument (triple-brace) expansion, not double-brace expansion
* @private
*/
function replaceVariables( $text, $args = array(), $argsOnly = false ) {
# Prevent too big inclusions
if( strlen( $text ) > $this->mOptions->getMaxIncludeSize() ) {
return $text;
}

$fname = __METHOD__ /*. '-L' . count( $this->mArgStack )*/;
wfProfileIn( $fname );

# This function is called recursively. To keep track of arguments we need a stack:
array_push( $this->mArgStack, $args );

$braceCallbacks = array();
if ( !$argsOnly ) {
$braceCallbacks[2] = array( &$this, 'braceSubstitution' );
}
if ( $this->mOutputType != OT_MSG ) {
$braceCallbacks[3] = array( &$this, 'argSubstitution' );
}
if ( $braceCallbacks ) {
$callbacks = array(
'{' => array(
'end' => '}',
'cb' => $braceCallbacks,
'min' => $argsOnly ? 3 : 2,
'max' => isset( $braceCallbacks[3] ) ? 3 : 2,
),
'[' => array(
'end' => ']',
'cb' => array(2=>null),
'min' => 2,
'max' => 2,
)
);
$text = $this->replace_callback ($text, $callbacks);

array_pop( $this->mArgStack );
}
wfProfileOut( $fname );
return $text;
}

/**
* Replace magic variables
* @private
*/
function variableSubstitution( $matches ) {
global $wgContLang;
$fname = 'Parser::variableSubstitution';
$varname = $wgContLang->lc($matches[1]);
wfProfileIn( $fname );
$skip = false;
if ( $this->mOutputType == OT_WIKI ) {
# Do only magic variables prefixed by SUBST
$mwSubst =& MagicWord::get( 'subst' );
if (!$mwSubst->matchStartAndRemove( $varname ))
$skip = true;
# Note that if we don't substitute the variable below,
# we don't remove the {{subst:}} magic word, in case
# it is a template rather than a magic variable.
}
if ( !$skip && array_key_exists( $varname, $this->mVariables ) ) {
$id = $this->mVariables[$varname];
# Now check if we did really match, case sensitive or not
$mw =& MagicWord::get( $id );
if ($mw->match($matches[1])) {
$text = $this->getVariableValue( $id );
$this->mOutput->mContainsOldMagic = true;
} else {
$text = $matches[0];
}
} else {
$text = $matches[0];
}
wfProfileOut( $fname );
return $text;
}


/// Clean up argument array - refactored in 1.9 so parserfunctions can use it, too.
static function createAssocArgs( $args ) {
$assocArgs = array();
$index = 1;
foreach( $args as $arg ) {
$eqpos = strpos( $arg, '=' );
if ( $eqpos === false ) {
$assocArgs[$index++] = $arg;
} else {
$name = trim( substr( $arg, 0, $eqpos ) );
$value = trim( substr( $arg, $eqpos+1 ) );
if ( $value === false ) {
$value = '';
}
if ( $name !== false ) {
$assocArgs[$name] = $value;
}
}
}

return $assocArgs;
}

/**
* Return the text of a template, after recursively
* replacing any variables or templates within the template.
*
* @param array $piece The parts of the template
* $piece['text']: matched text
* $piece['title']: the title, i.e. the part before the |
* $piece['parts']: the parameter array
* @return string the text of the template
* @private
*/
function braceSubstitution( $piece ) {
global $wgContLang, $wgLang, $wgAllowDisplayTitle, $wgNonincludableNamespaces;
$fname = __METHOD__ /*. '-L' . count( $this->mArgStack )*/;
wfProfileIn( $fname );
wfProfileIn( __METHOD__.'-setup' );

# Flags
$found = false; # $text has been filled
$nowiki = false; # wiki markup in $text should be escaped
$noparse = false; # Unsafe HTML tags should not be stripped, etc.
$noargs = false; # Don't replace triple-brace arguments in $text
$replaceHeadings = false; # Make the edit section links go to the template not the article
$headingOffset = 0; # Skip headings when number, to account for those that weren't transcluded.
$isHTML = false; # $text is HTML, armour it against wikitext transformation
$forceRawInterwiki = false; # Force interwiki transclusion to be done in raw mode not rendered

# Title object, where $text came from
$title = NULL;

$linestart = '';


# $part1 is the bit before the first |, and must contain only title characters
# $args is a list of arguments, starting from index 0, not including $part1

$titleText = $part1 = $piece['title'];
# If the third subpattern matched anything, it will start with |

if (null == $piece['parts']) {
$replaceWith = $this->variableSubstitution (array ($piece['text'], $piece['title']));
if ($replaceWith != $piece['text']) {
$text = $replaceWith;
$found = true;
$noparse = true;
$noargs = true;
}
}

$args = (null == $piece['parts']) ? array() : $piece['parts'];
wfProfileOut( __METHOD__.'-setup' );

# SUBST
wfProfileIn( __METHOD__.'-modifiers' );
if ( !$found ) {
$mwSubst =& MagicWord::get( 'subst' );
if ( $mwSubst->matchStartAndRemove( $part1 ) xor $this->ot['wiki'] ) {
# One of two possibilities is true:
# 1) Found SUBST but not in the PST phase
# 2) Didn't find SUBST and in the PST phase
# In either case, return without further processing
$text = $piece['text'];
$found = true;
$noparse = true;
$noargs = true;
}
}

# MSG, MSGNW and RAW
if ( !$found ) {
# Check for MSGNW:
$mwMsgnw =& MagicWord::get( 'msgnw' );
if ( $mwMsgnw->matchStartAndRemove( $part1 ) ) {
$nowiki = true;
} else {
# Remove obsolete MSG:
$mwMsg =& MagicWord::get( 'msg' );
$mwMsg->matchStartAndRemove( $part1 );
}

# Check for RAW:
$mwRaw =& MagicWord::get( 'raw' );
if ( $mwRaw->matchStartAndRemove( $part1 ) ) {
$forceRawInterwiki = true;
}
}
wfProfileOut( __METHOD__.'-modifiers' );

//save path level before recursing into functions & templates.
$lastPathLevel = $this->mTemplatePath;

# Parser functions
if ( !$found ) {
wfProfileIn( __METHOD__ . '-pfunc' );

$colonPos = strpos( $part1, ':' );
if ( $colonPos !== false ) {
# Case sensitive functions
$function = substr( $part1, 0, $colonPos );
if ( isset( $this->mFunctionSynonyms[1][$function] ) ) {
$function = $this->mFunctionSynonyms[1][$function];
} else {
# Case insensitive functions
$function = strtolower( $function );
if ( isset( $this->mFunctionSynonyms[0][$function] ) ) {
$function = $this->mFunctionSynonyms[0][$function];
} else {
$function = false;
}
}
if ( $function ) {
$funcArgs = array_map( 'trim', $args );
$funcArgs = array_merge( array( &$this, trim( substr( $part1, $colonPos + 1 ) ) ), $funcArgs );
$result = call_user_func_array( $this->mFunctionHooks[$function], $funcArgs );
$found = true;

// The text is usually already parsed, doesn't need triple-brace tags expanded, etc.
//$noargs = true;
//$noparse = true;

if ( is_array( $result ) ) {
if ( isset( $result[0] ) ) {
$text = $linestart . $result[0];
unset( $result[0] );
}

// Extract flags into the local scope
// This allows callers to set flags such as nowiki, noparse, found, etc.
extract( $result );
} else {
$text = $linestart . $result;
}
}
}
wfProfileOut( __METHOD__ . '-pfunc' );
}

# Template table test

# Did we encounter this template already? If yes, it is in the cache
# and we need to check for loops.
if ( !$found && isset( $this->mTemplates[$piece['title']] ) ) {
$found = true;

# Infinite loop test
if ( isset( $this->mTemplatePath[$part1] ) ) {
$noparse = true;
$noargs = true;
$found = true;
$text = $linestart .
"[[$part1]]<!-- WARNING: template loop detected -->";
wfDebug( __METHOD__.": template loop broken at '$part1'\n" );
} else {
# set $text to cached message.
$text = $linestart . $this->mTemplates[$piece['title']];
#treat title for cached page the same as others
$ns = NS_TEMPLATE;
$subpage = '';
$part1 = $this->maybeDoSubpageLink( $part1, $subpage );
if ($subpage !== '') {
$ns = $this->mTitle->getNamespace();
}
$title = Title::newFromText( $part1, $ns );
//used by include size checking
$titleText = $title->getPrefixedText();
//used by edit section links
$replaceHeadings = true;

}
}

# Load from database
if ( !$found ) {
wfProfileIn( __METHOD__ . '-loadtpl' );
$ns = NS_TEMPLATE;
# declaring $subpage directly in the function call
# does not work correctly with references and breaks
# {{/subpage}}-style inclusions
$subpage = '';
$part1 = $this->maybeDoSubpageLink( $part1, $subpage );
if ($subpage !== '') {
$ns = $this->mTitle->getNamespace();
}
$title = Title::newFromText( $part1, $ns );


if ( !is_null( $title ) ) {
$titleText = $title->getPrefixedText();
# Check for language variants if the template is not found
if($wgContLang->hasVariants() && $title->getArticleID() == 0){
$wgContLang->findVariantLink($part1, $title);
}

if ( !$title->isExternal() ) {
if ( $title->getNamespace() == NS_SPECIAL && $this->mOptions->getAllowSpecialInclusion() && $this->ot['html'] ) {
$text = SpecialPage::capturePath( $title );
if ( is_string( $text ) ) {
$found = true;
$noparse = true;
$noargs = true;
$isHTML = true;
$this->disableCache();
}
} else if ( $wgNonincludableNamespaces && in_array( $title->getNamespace(), $wgNonincludableNamespaces ) ) {
$found = false; //access denied
wfDebug( "$fname: template inclusion denied for " . $title->getPrefixedDBkey() );
} else {
list($articleContent,$title) = $this->fetchTemplateAndtitle( $title );
if ( $articleContent !== false ) {
$found = true;
$text = $articleContent;
$replaceHeadings = true;
}
}

# If the title is valid but undisplayable, make a link to it
if ( !$found && ( $this->ot['html'] || $this->ot['pre'] ) ) {
$text = "[[:$titleText]]";
$found = true;
}
} elseif ( $title->isTrans() ) {
// Interwiki transclusion
if ( $this->ot['html'] && !$forceRawInterwiki ) {
$text = $this->interwikiTransclude( $title, 'render' );
$isHTML = true;
$noparse = true;
} else {
$text = $this->interwikiTransclude( $title, 'raw' );
$replaceHeadings = true;
}
$found = true;
}

# Template cache array insertion
# Use the original $piece['title'] not the mangled $part1, so that
# modifiers such as RAW: produce separate cache entries
if( $found ) {
if( $isHTML ) {
// A special page; don't store it in the template cache.
} else {
$this->mTemplates[$piece['title']] = $text;
}
$text = $linestart . $text;
}
}
wfProfileOut( __METHOD__ . '-loadtpl' );
}

if ( $found && !$this->incrementIncludeSize( 'pre-expand', strlen( $text ) ) ) {
# Error, oversize inclusion
$text = $linestart .
"[[$titleText]]<!-- WARNING: template omitted, pre-expand include size too large -->";
$noparse = true;
$noargs = true;
}

# Recursive parsing, escaping and link table handling
# Only for HTML output
if ( $nowiki && $found && ( $this->ot['html'] || $this->ot['pre'] ) ) {
$text = wfEscapeWikiText( $text );
} elseif ( !$this->ot['msg'] && $found ) {
if ( $noargs ) {
$assocArgs = array();
} else {
# Clean up argument array
$assocArgs = self::createAssocArgs($args);
# Add a new element to the templace recursion path
$this->mTemplatePath[$part1] = 1;
}

if ( !$noparse ) {
# If there are any <onlyinclude> tags, only include them
if ( in_string( '<onlyinclude>', $text ) && in_string( '</onlyinclude>', $text ) ) {
$replacer = new OnlyIncludeReplacer;
StringUtils::delimiterReplaceCallback( '<onlyinclude>', '</onlyinclude>',
array( &$replacer, 'replace' ), $text );
$text = $replacer->output;
}
# Remove <noinclude> sections and <includeonly> tags
$text = StringUtils::delimiterReplace( '<noinclude>', '</noinclude>', '', $text );
$text = strtr( $text, array( '<includeonly>' => '' , '</includeonly>' => '' ) );

if( $this->ot['html'] || $this->ot['pre'] ) {
# Strip <nowiki>, <pre>, etc.
$text = $this->strip( $text, $this->mStripState );
if ( $this->ot['html'] ) {
$text = Sanitizer::removeHTMLtags( $text, array( &$this, 'replaceVariables' ), $assocArgs );
} elseif ( $this->ot['pre'] && $this->mOptions->getRemoveComments() ) {
$text = Sanitizer::removeHTMLcomments( $text );
}
}
$text = $this->replaceVariables( $text, $assocArgs );

# If the template begins with a table or block-level
# element, it should be treated as beginning a new line.
if (!$piece['lineStart'] && preg_match('/^(?:{\\||:|;|#|\*)/', $text)) /*}*/{
$text = "\n" . $text;
}
} elseif ( !$noargs ) {
# $noparse and !$noargs
# Just replace the arguments, not any double-brace items
# This is used for rendered interwiki transclusion
$text = $this->replaceVariables( $text, $assocArgs, true );
}
}
# Prune lower levels off the recursion check path
$this->mTemplatePath = $lastPathLevel;

if ( $found && !$this->incrementIncludeSize( 'post-expand', strlen( $text ) ) ) {
# Error, oversize inclusion
$text = $linestart .
"[[$titleText]]<!-- WARNING: template omitted, post-expand include size too large -->";
$noparse = true;
$noargs = true;
}

if ( !$found ) {
wfProfileOut( $fname );
return $piece['text'];
} else {
wfProfileIn( __METHOD__ . '-placeholders' );
if ( $isHTML ) {
# Replace raw HTML by a placeholder
# Add a blank line preceding, to prevent it from mucking up
# immediately preceding headings
$text = "\n\n" . $this->insertStripItem( $text, $this->mStripState );
} else {
# replace ==section headers==
# XXX this needs to go away once we have a better parser.
if ( !$this->ot['wiki'] && !$this->ot['pre'] && $replaceHeadings ) {
if( !is_null( $title ) )
$encodedname = base64_encode($title->getPrefixedDBkey());
else
$encodedname = base64_encode("");
$m = preg_split('/(^={1,6}.*?={1,6}\s*?$)/m', $text, -1,
PREG_SPLIT_DELIM_CAPTURE);
$text = '';
$nsec = $headingOffset;

for( $i = 0; $i < count($m); $i += 2 ) {
$text .= $m[$i];
if (!isset($m[$i + 1]) || $m[$i + 1] == "") continue;
$hl = $m[$i + 1];
if( strstr($hl, "<!--MWTEMPLATESECTION") ) {
$text .= $hl;
continue;
}
$m2 = array();
preg_match('/^(={1,6})(.*?)(={1,6})\s*?$/m', $hl, $m2);
$text .= $m2[1] . $m2[2] . "<!--MWTEMPLATESECTION="
. $encodedname . "&" . base64_encode("$nsec") . "-->" . $m2[3];

$nsec++;
}
}
}
wfProfileOut( __METHOD__ . '-placeholders' );
}

# Prune lower levels off the recursion check path
$this->mTemplatePath = $lastPathLevel;

if ( !$found ) {
wfProfileOut( $fname );
return $piece['text'];
} else {
wfProfileOut( $fname );
return $text;
}
}

/**
* Fetch the unparsed text of a template and register a reference to it.
*/
function fetchTemplateAndtitle( $title ) {
$text = $skip = false;
$finalTitle = $title;
// Loop to fetch the article, with up to 1 redirect
for ( $i = 0; $i < 2 && is_object( $title ); $i++ ) {
# Give extensions a chance to select the revision instead
$id = false; // Assume current
wfRunHooks( 'BeforeParserFetchTemplateAndtitle', array( &$this, &$title, &$skip, &$id ) );

if( $skip ) {
$text = false;
$this->mOutput->addTemplate( $title, $title->getArticleID(), null );
break;
}
$rev = $id ? Revision::newFromId( $id ) : Revision::newFromTitle( $title );
$rev_id = $rev ? $rev->getId() : 0;

$this->mOutput->addTemplate( $title, $title->getArticleID(), $rev_id );

if( $rev ) {
$text = $rev->getText();
} elseif( $title->getNamespace() == NS_MEDIAWIKI ) {
global $wgLang;
$message = $wgLang->lcfirst( $title->getText() );
$text = wfMsgForContentNoTrans( $message );
if( wfEmptyMsg( $message, $text ) ) {
$text = false;
break;
}
} else {
break;
}
if ( $text === false ) {
break;
}
// Redirect?
$finalTitle = $title;
$title = Title::newFromRedirect( $text );
}
return array($text,$finalTitle);
}

function fetchTemplate( $title ) {
$rv = $this->fetchTemplateAndtitle($title);
return $rv[0];
}

/**
* Transclude an interwiki link.
*/
function interwikiTransclude( $title, $action ) {
global $wgEnableScaryTranscluding;

if (!$wgEnableScaryTranscluding)
return wfMsg('scarytranscludedisabled');

$url = $title->getFullUrl( "action=$action" );

if (strlen($url) > 255)
return wfMsg('scarytranscludetoolong');
return $this->fetchScaryTemplateMaybeFromCache($url);
}

function fetchScaryTemplateMaybeFromCache($url) {
global $wgTranscludeCacheExpiry;
$dbr = wfGetDB(DB_SLAVE);
$obj = $dbr->selectRow('transcache', array('tc_time', 'tc_contents'),
array('tc_url' => $url));
if ($obj) {
$time = $obj->tc_time;
$text = $obj->tc_contents;
if ($time && time() < $time + $wgTranscludeCacheExpiry ) {
return $text;
}
}

$text = Http::get($url);
if (!$text)
return wfMsg('scarytranscludefailed', $url);

$dbw = wfGetDB(DB_MASTER);
$dbw->replace('transcache', array('tc_url'), array(
'tc_url' => $url,
'tc_time' => time(),
'tc_contents' => $text));
return $text;
}


/**
* Triple brace replacement -- used for template arguments
* @private
*/
function argSubstitution( $matches ) {
$arg = trim( $matches['title'] );
$text = $matches['text'];
$inputArgs = end( $this->mArgStack );

if ( array_key_exists( $arg, $inputArgs ) ) {
$text = $inputArgs[$arg];
} else if (($this->mOutputType == OT_HTML || $this->mOutputType == OT_PREPROCESS ) &&
null != $matches['parts'] && count($matches['parts']) > 0) {
$text = $matches['parts'][0];
}
if ( !$this->incrementIncludeSize( 'arg', strlen( $text ) ) ) {
$text = $matches['text'] .
'<!-- WARNING: argument omitted, expansion size too large -->';
}

return $text;
}

/**
* Increment an include size counter
*
* @param string $type The type of expansion
* @param integer $size The size of the text
* @return boolean False if this inclusion would take it over the maximum, true otherwise
*/
function incrementIncludeSize( $type, $size ) {
if ( $this->mIncludeSizes[$type] + $size > $this->mOptions->getMaxIncludeSize() ) {
return false;
} else {
$this->mIncludeSizes[$type] += $size;
return true;
}
}

I dunno how to use them to make it into ONE php file and also to convert this to vB stuff, etc...into a create_bbcode plugin or something...
Reply With Quote
 


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 11:37 AM.


Powered by vBulletin® Version 3.8.12 by vBS
Copyright ©2000 - 2025, vBulletin Solutions Inc.
X vBulletin 3.8.12 by vBS Debug Information
  • Page Generation 0.02636 seconds
  • Memory Usage 2,748KB
  • Queries Executed 12 (?)
More Information
Template Usage:
  • (1)SHOWTHREAD
  • (1)ad_footer_end
  • (1)ad_footer_start
  • (1)ad_header_end
  • (1)ad_header_logo
  • (1)ad_navbar_below
  • (1)ad_showthread_beforeqr
  • (3)bbcode_code
  • (1)bbcode_php
  • (3)bbcode_quote
  • (1)footer
  • (1)forumjump
  • (1)forumrules
  • (1)gobutton
  • (1)header
  • (1)headinclude
  • (1)navbar
  • (3)navbar_link
  • (120)option
  • (13)post_thanks_box
  • (13)post_thanks_button
  • (1)post_thanks_javascript
  • (1)post_thanks_navbar_search
  • (13)post_thanks_postbit_info
  • (13)postbit
  • (13)postbit_onlinestatus
  • (13)postbit_wrapper
  • (1)showthread_list
  • (1)spacer_close
  • (1)spacer_open
  • (1)tagbit_wrapper 

Phrase Groups Available:
  • global
  • inlinemod
  • postbit
  • posting
  • reputationlevel
  • showthread
Included Files:
  • ./showthread.php
  • ./global.php
  • ./includes/init.php
  • ./includes/class_core.php
  • ./includes/config.php
  • ./includes/functions.php
  • ./includes/class_hook.php
  • ./includes/modsystem_functions.php
  • ./includes/functions_bigthree.php
  • ./includes/class_postbit.php
  • ./includes/class_bbcode.php
  • ./includes/functions_reputation.php
  • ./includes/functions_threadedmode.php
  • ./includes/functions_post_thanks.php 

Hooks Called:
  • init_startup
  • init_startup_session_setup_start
  • init_startup_session_setup_complete
  • cache_permissions
  • fetch_postinfo_query
  • fetch_postinfo
  • fetch_threadinfo_query
  • fetch_threadinfo
  • fetch_foruminfo
  • style_fetch
  • cache_templates
  • global_start
  • parse_templates
  • global_setup_complete
  • showthread_start
  • showthread_getinfo
  • forumjump
  • showthread_post_start
  • showthread_query_postids_threaded
  • showthread_threaded_construct_link
  • showthread_query
  • bbcode_fetch_tags
  • bbcode_create
  • showthread_postbit_create
  • postbit_factory
  • postbit_display_start
  • post_thanks_function_post_thanks_off_start
  • post_thanks_function_post_thanks_off_end
  • post_thanks_function_fetch_thanks_start
  • post_thanks_function_fetch_thanks_end
  • post_thanks_function_thanked_already_start
  • post_thanks_function_thanked_already_end
  • fetch_musername
  • postbit_imicons
  • bbcode_parse_start
  • bbcode_parse_complete_precache
  • bbcode_parse_complete
  • postbit_display_complete
  • post_thanks_function_can_thank_this_post_start
  • tag_fetchbit_complete
  • forumrules
  • navbits
  • navbits_complete
  • showthread_complete