Example #1
0
 function qpuserchoice(Parser &$parser, PPFrame $frame, array $args)
 {
     $this->frame = $frame;
     $this->args =& $args;
     if (isset($args[0])) {
         # args[0] is a poll address
         $this->pollAddr = trim($this->frame->expand($this->args[0]));
         $this->pollStore = qp_PollStore::newFromAddr($this->pollAddr);
         if ($this->pollStore instanceof qp_PollStore && $this->pollStore->pid !== null) {
             $this->error_message = 'missing_question_id';
             if (isset($args[1])) {
                 # args[1] is question_id
                 $qdata = $this->getQuestionData(trim($frame->expand($args[1])));
                 if ($qdata instanceof qp_QuestionData) {
                     $this->error_message = 'missing_proposal_id';
                     if (isset($args[2])) {
                         # get poll's proposal choice
                         $this->proposal_id = trim($frame->expand($args[2]));
                         $this->error_message = 'invalid_proposal_id';
                         if (preg_match(qp_Setup::PREG_NON_NEGATIVE_INT4_MATCH, $this->proposal_id)) {
                             $this->defaultProposalText = isset($args[3]) ? trim($frame->expand($args[3])) : '';
                             $this->proposal_id = intval($this->proposal_id);
                             $this->error_message = 'missing_proposal_id';
                             if (array_key_exists($this->proposal_id, $qdata->ProposalText)) {
                                 return $this->qpuserchoiceValidResult($qdata);
                             }
                         }
                     }
                 }
             }
         }
     }
     return '<strong class="error">qpuserchoice: ' . wfMsgHTML('qp_func_' . $this->error_message, qp_Setup::specialchars($this->pollAddr), qp_Setup::specialchars($this->question_id), qp_Setup::specialchars($this->proposal_id)) . '</strong>';
 }
Example #2
0
 /**
  * Magic word 'THIS:' to return certain information about the page the word actually is defined on
  */
 static function pfObj_this(Parser &$parser, PPFrame $frame = null, $args = null)
 {
     // if MW version is too old or something is wrong:
     if ($frame === null || $frame->title === null) {
         return '';
     }
     // get part behind 'THIS:' if only 'THIS', use 'FULLPAGENAME'
     $index = isset($args[0]) ? trim($frame->expand($args[0])) : '';
     $newArgs = array();
     if ($index !== '') {
         // clean up arguments as if first argument never were set:
         unset($args[0]);
         foreach ($args as $arg) {
             $newArgs[] = $arg;
         }
         // get magic word ID of the variable name:
         $mwId = self::getVariablesMagicWordId($parser, $index);
         if ($mwId === null) {
             // requested variable doesn't exist, make the thing a template call
             return array(null, 'found' => false);
         }
     } else {
         // if only '{{THIS}}', set magic word id to 'FULLPAGENAME'
         $mwId = 'fullpagename';
     }
     // get value:
     $out = self::getThisVariableValue($mwId, $parser, $frame, $newArgs);
     if ($out === null) {
         // requested variable doesn't support 'THIS:', make the thing a template call
         return array(null, 'found' => false);
     }
     return $out;
 }
Example #3
0
 /**
  * Just "redirect" to $this->IfhascatPf().
  *
  * @param Parser $parser
  * @param PPFrame $frame
  */
 function IfhascatPfObj(&$parser, $frame, $args)
 {
     $page = isset($args[0]) ? trim($frame->expand($args[0])) : '';
     $category = isset($args[1]) ? trim($frame->expand($args[1])) : '';
     $then = isset($args[2]) ? trim($frame->expand($args[2])) : '1';
     $else = isset($args[3]) ? trim($frame->expand($args[3])) : '0';
     return $this->IfhascatPf($parser, $page, $category, $then, $else);
     // *else*
 }
Example #4
0
 /**
  * Method for handling the declare parser function.
  * 
  * @since 1.5.3
  * 
  * @param Parser $parser
  * @param PPFrame $frame
  * @param array $args
  */
 public static function render(Parser &$parser, PPFrame $frame, array $args)
 {
     if ($frame->isTemplate()) {
         foreach ($args as $arg) {
             if (trim($arg) !== '') {
                 $expanded = trim($frame->expand($arg));
                 $parts = explode('=', $expanded, 2);
                 if (count($parts) == 1) {
                     $propertystring = $expanded;
                     $argumentname = $expanded;
                 } else {
                     $propertystring = $parts[0];
                     $argumentname = $parts[1];
                 }
                 $property = SMWPropertyValue::makeUserProperty($propertystring);
                 $argument = $frame->getArgument($argumentname);
                 $valuestring = $frame->expand($argument);
                 if ($property->isValid()) {
                     $type = $property->getPropertyTypeID();
                     if ($type == '_wpg') {
                         $matches = array();
                         preg_match_all('/\\[\\[([^\\[\\]]*)\\]\\]/u', $valuestring, $matches);
                         $objects = $matches[1];
                         if (count($objects) == 0) {
                             if (trim($valuestring) !== '') {
                                 SMWParseData::addProperty($propertystring, $valuestring, false, $parser, true);
                             }
                         } else {
                             foreach ($objects as $object) {
                                 SMWParseData::addProperty($propertystring, $object, false, $parser, true);
                             }
                         }
                     } elseif (trim($valuestring) !== '') {
                         SMWParseData::addProperty($propertystring, $valuestring, false, $parser, true);
                     }
                     // $value = SMWDataValueFactory::newPropertyObjectValue( $property->getDataItem(), $valuestring );
                     // if (!$value->isValid()) continue;
                 }
             }
         }
     } else {
         // @todo Save as metadata
     }
     global $wgTitle;
     if (!is_null($wgTitle) && $wgTitle->isSpecialPage()) {
         global $wgOut;
         SMWOutputs::commitToOutputPage($wgOut);
     } else {
         SMWOutputs::commitToParser($parser);
     }
     return '';
 }
 /**
  * #coordinates parser function callback
  * 
  * @param Parser $parser
  * @param PPFrame $frame
  * @param Array $args
  * @return Mixed
  */
 public function coordinates($parser, $frame, $args)
 {
     if ($parser != $this->parser) {
         throw new MWException(__METHOD__ . '() called by wrong parser');
     }
     $this->output = $parser->getOutput();
     if (!isset($this->output->geoData)) {
         $this->output->geoData = new CoordinatesOutput();
     }
     $this->unnamed = array();
     $this->named = array();
     $first = trim($frame->expand(array_shift($args)));
     $this->addArg($first);
     foreach ($args as $arg) {
         $bits = $arg->splitArg();
         $value = trim($frame->expand($bits['value']));
         if ($bits['index'] === '') {
             $this->named[trim($frame->expand($bits['name']))] = $value;
         } else {
             $this->addArg($value);
         }
     }
     $this->parseTagArgs();
     $status = GeoData::parseCoordinates($this->unnamed, $this->named['globe']);
     if ($status->isGood()) {
         $coord = $status->value;
         $status = $this->applyTagArgs($coord);
         if ($status->isGood()) {
             $status = $this->applyCoord($coord);
             if ($status->isGood()) {
                 return '';
             }
         }
     }
     $parser->addTrackingCategory('geodata-broken-tags-category');
     $errorText = $this->errorText($status);
     if ($errorText == '&lt;&gt;') {
         // Error that doesn't require a message,
         // can't think of a better way to pass this condition
         return '';
     }
     return array("<span class=\"error\">{$errorText}</span>", 'noparse' => false);
 }
 /**
  * Function executed by use of {{#infoboxbuilder:}} parser function.
  * It gets the code from InfoboxBuilder.lua and creates new module object
  * from it. The module is then invoked and the result is returned.
  * @param  Parser  $parser Parser object
  * @param  PPFrame $frame  PPFrame object
  * @param  array   $args   Array of arguments passed from $frame object
  * @return string          A string returned by InfoboxBuilder.lua
  */
 public static function parserFunctionHook(\Parser $parser, $frame, $args)
 {
     wfProfileIn(__METHOD__);
     try {
         /**
          * Add the registered SCSS with the default theme
          */
         $parser->getOutput()->addModuleStyles('ext.wikia.InfoboxBuilder');
         $engine = \Scribunto::getParserEngine($parser);
         unset($args[0]);
         $childFrame = $frame->newChild($args, $parser->getTitle(), 1);
         $moduleText = file_get_contents(__DIR__ . '/includes/lua/InfoboxBuilder.lua');
         $module = new \Scribunto_LuaModule($engine, $moduleText, 'InfoboxBuilder');
         $result = $module->invoke('builder', $childFrame);
         $result = \UtfNormal::cleanUp(strval($result));
         wfProfileOut(__METHOD__);
         return $result;
     } catch (\ScribuntoException $e) {
         $trace = $e->getScriptTraceHtml(array('msgOptions' => array('content')));
         $html = \Html::element('p', array(), $e->getMessage());
         if ($trace !== false) {
             $html .= \Html::element('p', array(), wfMessage('scribunto-common-backtrace')->inContentLanguage()->text()) . $trace;
         }
         $out = $parser->getOutput();
         if (!isset($out->scribunto_errors)) {
             $out->addOutputHook('ScribuntoError');
             $out->scribunto_errors = array();
             $parser->addTrackingCategory('scribunto-common-error-category');
         }
         $out->scribunto_errors[] = $html;
         $id = 'mw-scribunto-error-' . (count($out->scribunto_errors) - 1);
         $parserError = wfMessage('scribunto-parser-error')->inContentLanguage()->text() . $parser->insertStripItem('<!--' . htmlspecialchars($e->getMessage()) . '-->');
         wfProfileOut(__METHOD__);
         // #iferror-compatible error element
         return "<strong class=\"error\"><span class=\"scribunto-error\" id=\"{$id}\">" . $parserError . "</span></strong>";
     }
 }
	/**
	 * Make 'Parser Fun' extensions 'THIS' function work with our variables/functions
	 */
	static function onGetThisVariableValueSwitch( Parser &$parser, Title $title, &$magicWordId, &$ret, PPFrame $frame, array $args ) {
		$expArgs = array();
		foreach( $args as $arg ) {
			$expArgs[] = trim( $frame->expand( $arg ) );
		}
		$expArgs[] = '1=' . $title->getPrefixedText();
		
		return self::variableValueSwitch( $parser, $magicWordId, $ret, $expArgs );
	}
Example #8
0
 /**
  * Base function for operations with multiple arrays given thru n parameters
  * $operationFunc expects a function name prefix (suffix 'multi_') with two parameters
  * $array1 and $array2 which will perform an action between $array1 and $array2 which
  * will result into a new $array1. There can be 1 to n $hash2 in the whole process.
  *
  * Note: This function is similar to that of Extension:HashTables.
  *
  * @since 2.0
  *
  * @param $frame PPFrame
  * @param $args array
  * @param $operationFunc string name of the function calling this. There must be a counterpart
  *        function with prefix 'multi_' which should have two parameters. Both parameters
  *        will receive an array, the function must return the result array of the processing.
  * @param $runFuncOnSingleArray boolean whether the $operationFunc function should be run in case
  *        only one array id is given. If not, the original array will end up in the new array.
  */
 protected function multiArrayOperation(PPFrame $frame, array $args, $operationFunc, $runFuncOnSingleArray = true)
 {
     $lastArray = null;
     $operationRan = false;
     $finalArrayId = trim($frame->expand($args[0]));
     $operationFunc = 'multi_' . preg_replace('/^pfObj_/', '', $operationFunc);
     // For all arrays given in parameters 2 to n (ignore 1 because this is the name of the new array)
     for ($i = 1; $i < count($args); $i++) {
         // just make sure we don't fall into gaps of given arguments:
         if (!array_key_exists($i, $args)) {
             continue;
         }
         $argArrayId = trim($frame->expand($args[$i]));
         // ignore all tables which do not exist
         if ($this->arrayExists($argArrayId)) {
             $argArray = $this->getArray($argArrayId);
             if ($lastArray === null) {
                 // first valid array, process together with second...
                 $lastArray = $argArray;
             } else {
                 // second or later hash table, process with previous:
                 $lastArray = $this->{$operationFunc}($lastArray, $argArray);
                 // perform action between last and current array
                 $operationRan = true;
             }
         }
     }
     // in case no array was given at all:
     if ($lastArray === null) {
         $lastArray = array();
     }
     global $egArraysCompatibilityMode;
     if (!$operationRan && $egArraysCompatibilityMode && $operationFunc !== 'multi_arraymerge') {
         /*
          * COMPATIBILITY-MODE:
          * Before version 2.0 we didn't create a new array in case only one array was given.
          * The only exception was 'arraymerge' which did duplicate the array.
          */
         return '';
     }
     // if the operation didn't run because there was only one or no array:
     if (!$operationRan && $runFuncOnSingleArray) {
         $lastArray = $this->{$operationFunc}($lastArray);
     }
     // re-organize all keys since some 'multi_' functions will preserve keys!
     $lastArray = array_merge($lastArray);
     $this->setArray($finalArrayId, $lastArray);
 }
Example #9
0
 /**
  * Generic function handling '#forargs' and '#fornumargs' as one
  */
 protected static function perform_forargs(Parser &$parser, PPFrame $frame, array $funcArgs, array $templateArgs, $prefix = '')
 {
     // if not called within template instance:
     if (!$frame->isTemplate()) {
         return '';
     }
     // name of the variable to store the argument name:
     $keyVar = array_shift($funcArgs);
     $keyVar = $keyVar !== null ? trim($frame->expand($keyVar)) : '';
     // name of the variable to store the argument value:
     $valVar = array_shift($funcArgs);
     $valVar = $valVar !== null ? trim($frame->expand($valVar)) : '';
     // unexpanded code:
     $rawCode = array_shift($funcArgs);
     $rawCode = $rawCode !== null ? $rawCode : '';
     $output = '';
     // if prefix contains numbers only or isn't set, get all arguments, otherwise just non-numeric
     $tArgs = preg_match('/^([1-9][0-9]*)?$/', $prefix) > 0 ? $frame->getArguments() : $frame->getNamedArguments();
     foreach ($templateArgs as $argName => $argVal) {
         // if no filter or prefix in argument name:
         if ($prefix !== '' && strpos($argName, $prefix) !== 0) {
             continue;
         }
         if ($keyVar !== $valVar) {
             // variable with the argument name without prefix as value:
             self::setVariable($parser, $keyVar, substr($argName, strlen($prefix)));
         }
         // variable with the arguments value:
         self::setVariable($parser, $valVar, $argVal);
         // expand current run:
         $output .= trim($frame->expand($rawCode));
     }
     return $output;
 }
function drawDiagram(Parser $parser, PPFrame $frame)
{
    global $wgTitle;
    $sumEditing = 0;
    $pagesList = CDParameters::getInstance()->getPagesList();
    $pageWithChanges = array();
    foreach ($pagesList as $thisPageTitle) {
        $names = getPageEditorsFromDb($thisPageTitle);
        $changesForUsersForPage = getCountsOfEditing($names);
        $thisPageTitleKey = $thisPageTitle->getText();
        if ($thisPageTitle->getNsText() != "") {
            $thisPageTitleKey = $thisPageTitle->getNsText() . ":" . $thisPageTitleKey;
            // we can't use Title object this is a key with an array so we generate the Ns:Name key
        }
        $pageWithChanges[$thisPageTitleKey] = $changesForUsersForPage;
        $sumEditing += evaluateCountOfAllEdits($changesForUsersForPage);
    }
    $text = drawPreamble();
    foreach ($pageWithChanges as $thisPageTitleKey => $changesForUsersForPage) {
        $drawer = CDDrawerFactory::getDrawer($changesForUsersForPage, $sumEditing, $thisPageTitleKey);
        $text .= $drawer->draw();
    }
    $text .= "}</graphviz>";
    // $text = getPie($changesForUsers, $sumEditing, $thisPageTitle);
    $parser->disableCache();
    $parser->setTitle(Title::newFromText("Main_page"));
    $frame->getTitle(Title::newFromText("Main_page"));
    $text = $parser->recursiveTagParse($text, $frame);
    //this stuff just render my page
    return $text;
}
Example #11
0
 /**
  * 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['title']: the title, i.e. the part before the |
  *  $piece['parts']: the parameter array
  *  $piece['lineStart']: whether the brace was at the start of a line
  * @param PPFrame $frame The current frame, contains template arguments
  * @throws MWException
  * @return string The text of the template
  * @private
  */
 function braceSubstitution($piece, $frame)
 {
     wfProfileIn(__METHOD__);
     wfProfileIn(__METHOD__ . '-setup');
     # Flags
     $found = false;
     # $text has been filled
     $nowiki = false;
     # wiki markup in $text should be escaped
     $isHTML = false;
     # $text is HTML, armour it against wikitext transformation
     $forceRawInterwiki = false;
     # Force interwiki transclusion to be done in raw mode not rendered
     $isChildObj = false;
     # $text is a DOM node needing expansion in a child frame
     $isLocalObj = false;
     # $text is a DOM node needing expansion in the current frame
     # Title object, where $text came from
     $title = false;
     # $part1 is the bit before the first |, and must contain only title characters.
     # Various prefixes will be stripped from it later.
     $titleWithSpaces = $frame->expand($piece['title']);
     $part1 = trim($titleWithSpaces);
     $titleText = false;
     # Original title text preserved for various purposes
     $originalTitle = $part1;
     # $args is a list of argument nodes, starting from index 0, not including $part1
     # @todo FIXME: If piece['parts'] is null then the call to getLength() below won't work b/c this $args isn't an object
     $args = null == $piece['parts'] ? array() : $piece['parts'];
     wfProfileOut(__METHOD__ . '-setup');
     $titleProfileIn = null;
     // profile templates
     # SUBST
     wfProfileIn(__METHOD__ . '-modifiers');
     if (!$found) {
         $substMatch = $this->mSubstWords->matchStartAndRemove($part1);
         # Possibilities for substMatch: "subst", "safesubst" or FALSE
         # Decide whether to expand template or keep wikitext as-is.
         if ($this->ot['wiki']) {
             if ($substMatch === false) {
                 $literal = true;
                 # literal when in PST with no prefix
             } else {
                 $literal = false;
                 # expand when in PST with subst: or safesubst:
             }
         } else {
             if ($substMatch == 'subst') {
                 $literal = true;
                 # literal when not in PST with plain subst:
             } else {
                 $literal = false;
                 # expand when not in PST with safesubst: or no prefix
             }
         }
         if ($literal) {
             $text = $frame->virtualBracketedImplode('{{', '|', '}}', $titleWithSpaces, $args);
             $isLocalObj = true;
             $found = true;
         }
     }
     # Variables
     if (!$found && $args->getLength() == 0) {
         $id = $this->mVariables->matchStartToEnd($part1);
         if ($id !== false) {
             $text = $this->getVariableValue($id, $frame);
             if (MagicWord::getCacheTTL($id) > -1) {
                 $this->mOutput->updateCacheExpiry(MagicWord::getCacheTTL($id));
             }
             $found = 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');
     # Parser functions
     if (!$found) {
         wfProfileIn(__METHOD__ . '-pfunc');
         $colonPos = strpos($part1, ':');
         if ($colonPos !== false) {
             $func = substr($part1, 0, $colonPos);
             $funcArgs = array(trim(substr($part1, $colonPos + 1)));
             for ($i = 0; $i < $args->getLength(); $i++) {
                 $funcArgs[] = $args->item($i);
             }
             try {
                 $result = $this->callParserFunction($frame, $func, $funcArgs);
             } catch (Exception $ex) {
                 wfProfileOut(__METHOD__ . '-pfunc');
                 wfProfileOut(__METHOD__);
                 throw $ex;
             }
             # The interface for parser functions allows for extracting
             # flags into the local scope. Extract any forwarded flags
             # here.
             extract($result);
         }
         wfProfileOut(__METHOD__ . '-pfunc');
     }
     # Finish mangling title and then check for loops.
     # Set $title to a Title object and $titleText to the PDBK
     if (!$found) {
         $ns = NS_TEMPLATE;
         # Split the title into page and subpage
         $subpage = '';
         $relative = $this->maybeDoSubpageLink($part1, $subpage);
         if ($part1 !== $relative) {
             $part1 = $relative;
             $ns = $this->mTitle->getNamespace();
         }
         $title = Title::newFromText($part1, $ns);
         if ($title) {
             $titleText = $title->getPrefixedText();
             # Check for language variants if the template is not found
             if ($this->getConverterLanguage()->hasVariants() && $title->getArticleID() == 0) {
                 $this->getConverterLanguage()->findVariantLink($part1, $title, true);
             }
             # Do recursion depth check
             $limit = $this->mOptions->getMaxTemplateDepth();
             if ($frame->depth >= $limit) {
                 $found = true;
                 $text = '<span class="error">' . wfMessage('parser-template-recursion-depth-warning')->numParams($limit)->inContentLanguage()->text() . '</span>';
             }
         }
     }
     # Load from database
     if (!$found && $title) {
         if (!Profiler::instance()->isPersistent()) {
             # Too many unique items can kill profiling DBs/collectors
             $titleProfileIn = __METHOD__ . "-title-" . $title->getPrefixedDBkey();
             wfProfileIn($titleProfileIn);
             // template in
         }
         wfProfileIn(__METHOD__ . '-loadtpl');
         if (!$title->isExternal()) {
             if ($title->isSpecialPage() && $this->mOptions->getAllowSpecialInclusion() && $this->ot['html']) {
                 // Pass the template arguments as URL parameters.
                 // "uselang" will have no effect since the Language object
                 // is forced to the one defined in ParserOptions.
                 $pageArgs = array();
                 for ($i = 0; $i < $args->getLength(); $i++) {
                     $bits = $args->item($i)->splitArg();
                     if (strval($bits['index']) === '') {
                         $name = trim($frame->expand($bits['name'], PPFrame::STRIP_COMMENTS));
                         $value = trim($frame->expand($bits['value']));
                         $pageArgs[$name] = $value;
                     }
                 }
                 // Create a new context to execute the special page
                 $context = new RequestContext();
                 $context->setTitle($title);
                 $context->setRequest(new FauxRequest($pageArgs));
                 $context->setUser($this->getUser());
                 $context->setLanguage($this->mOptions->getUserLangObj());
                 $ret = SpecialPageFactory::capturePath($title, $context);
                 if ($ret) {
                     $text = $context->getOutput()->getHTML();
                     $this->mOutput->addOutputPageMetadata($context->getOutput());
                     $found = true;
                     $isHTML = true;
                     $this->disableCache();
                 }
             } elseif (MWNamespace::isNonincludable($title->getNamespace())) {
                 $found = false;
                 # access denied
                 wfDebug(__METHOD__ . ": template inclusion denied for " . $title->getPrefixedDBkey() . "\n");
             } else {
                 list($text, $title) = $this->getTemplateDom($title);
                 if ($text !== false) {
                     $found = true;
                     $isChildObj = 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;
             } else {
                 $text = $this->interwikiTransclude($title, 'raw');
                 # Preprocess it like a template
                 $text = $this->preprocessToDom($text, self::PTD_FOR_INCLUSION);
                 $isChildObj = true;
             }
             $found = true;
         }
         # Do infinite loop check
         # This has to be done after redirect resolution to avoid infinite loops via redirects
         if (!$frame->loopCheck($title)) {
             $found = true;
             $text = '<span class="error">' . wfMessage('parser-template-loop-warning', $titleText)->inContentLanguage()->text() . '</span>';
             wfDebug(__METHOD__ . ": template loop broken at '{$titleText}'\n");
         }
         wfProfileOut(__METHOD__ . '-loadtpl');
     }
     # If we haven't found text to substitute by now, we're done
     # Recover the source wikitext and return it
     if (!$found) {
         $text = $frame->virtualBracketedImplode('{{', '|', '}}', $titleWithSpaces, $args);
         if ($titleProfileIn) {
             wfProfileOut($titleProfileIn);
             // template out
         }
         wfProfileOut(__METHOD__);
         return array('object' => $text);
     }
     # Expand DOM-style return values in a child frame
     if ($isChildObj) {
         # Clean up argument array
         $newFrame = $frame->newChild($args, $title);
         if ($nowiki) {
             $text = $newFrame->expand($text, PPFrame::RECOVER_ORIG);
         } elseif ($titleText !== false && $newFrame->isEmpty()) {
             # Expansion is eligible for the empty-frame cache
             if (isset($this->mTplExpandCache[$titleText])) {
                 $text = $this->mTplExpandCache[$titleText];
             } else {
                 $text = $newFrame->expand($text);
                 $this->mTplExpandCache[$titleText] = $text;
             }
         } else {
             # Uncached expansion
             $text = $newFrame->expand($text);
         }
     }
     if ($isLocalObj && $nowiki) {
         $text = $frame->expand($text, PPFrame::RECOVER_ORIG);
         $isLocalObj = false;
     }
     if ($titleProfileIn) {
         wfProfileOut($titleProfileIn);
         // template out
     }
     # Replace raw HTML by a placeholder
     if ($isHTML) {
         $text = $this->insertStripItem($text);
     } elseif ($nowiki && ($this->ot['html'] || $this->ot['pre'])) {
         # Escape nowiki-style return values
         $text = wfEscapeWikiText($text);
     } elseif (is_string($text) && !$piece['lineStart'] && preg_match('/^(?:{\\||:|;|#|\\*)/', $text)) {
         # Bug 529: if the template begins with a table or block-level
         # element, it should be treated as beginning a new line.
         # This behavior is somewhat controversial.
         $text = "\n" . $text;
     }
     if (is_string($text) && !$this->incrementIncludeSize('post-expand', strlen($text))) {
         # Error, oversize inclusion
         if ($titleText !== false) {
             # Make a working, properly escaped link if possible (bug 23588)
             $text = "[[:{$titleText}]]";
         } else {
             # This will probably not be a working link, but at least it may
             # provide some hint of where the problem is
             preg_replace('/^:/', '', $originalTitle);
             $text = "[[:{$originalTitle}]]";
         }
         $text .= $this->insertStripItem('<!-- WARNING: template omitted, post-expand include size too large -->');
         $this->limitationWarn('post-expand-template-inclusion');
     }
     if ($isLocalObj) {
         $ret = array('object' => $text);
     } else {
         $ret = array('text' => $text);
     }
     wfProfileOut(__METHOD__);
     return $ret;
 }
Example #12
0
 /**
  * Parser function to extension tag adaptor
  * @param Parser $parser
  * @param PPFrame $frame
  * @param array $args
  * @return string
  */
 public static function tagObj($parser, $frame, $args)
 {
     if (!count($args)) {
         return '';
     }
     $tagName = strtolower(trim($frame->expand(array_shift($args))));
     if (count($args)) {
         $inner = $frame->expand(array_shift($args));
     } else {
         $inner = null;
     }
     $stripList = $parser->getStripList();
     if (!in_array($tagName, $stripList)) {
         return '<span class="error">' . wfMessage('unknown_extension_tag', $tagName)->inContentLanguage()->text() . '</span>';
     }
     $attributes = array();
     foreach ($args as $arg) {
         $bits = $arg->splitArg();
         if (strval($bits['index']) === '') {
             $name = trim($frame->expand($bits['name'], PPFrame::STRIP_COMMENTS));
             $value = trim($frame->expand($bits['value']));
             if (preg_match('/^(?:["\'](.+)["\']|""|\'\')$/s', $value, $m)) {
                 $value = isset($m[1]) ? $m[1] : '';
             }
             $attributes[$name] = $value;
         }
     }
     $params = array('name' => $tagName, 'inner' => $inner, 'attributes' => $attributes, 'close' => "</{$tagName}>");
     return $parser->extensionSubstitution($params, $frame);
 }
 /**
  * Function ensures that arrays are used for merging
  *
  * @param PPFrame $frame
  *
  * @return array
  */
 protected function getFrameParams(PPFrame $frame)
 {
     //we use both getNamedArguments and getArguments to ensure we acquire variables no matter what frame is used
     $namedArgs = $frame->getNamedArguments();
     $namedArgs = isset($namedArgs) ? is_array($namedArgs) ? $namedArgs : [$namedArgs] : [];
     $args = $frame->getArguments();
     $args = isset($args) ? is_array($args) ? $args : [$args] : [];
     return array_merge($namedArgs, $args);
 }
Example #14
0
 /**
  * Returns either the text result of the function, or an array with the
  * text in element 0, and a number of flags in the other elements.
  * 
  * @param Parser $parser
  * @param PPFrame $frame
  * @param array $args
  * @return string Html output
  */
 public static function onParserFunctionHook($parser, $frame, $args)
 {
     $arguments = array();
     // transform objects to strings
     foreach ($args as $arg) {
         $arguments[] = trim($frame->expand($arg));
     }
     // if no argument given, we receive an array with one empty string, remove it
     if (count($arguments) == 1 && reset($arguments) == '') {
         array_shift($arguments);
     }
     // instanciate
     $child_class = get_called_class();
     $widget = new $child_class($parser, $frame);
     // execute
     return $widget->execute($arguments);
 }
Example #15
0
 /**
  * Returns a value from the last performed regex match
  * 
  * @index $parser Parser instance of running Parser
  * @param $index Integer index of the last match which should be returnd or a string containing $n as indexes to be replaced
  * @param $defaultVal Integer default value which will be returned when the result with the given index doesn't exist or is a void string
  */
 public static function pfObj_regex_var(Parser &$parser, PPFrame $frame, array $args)
 {
     $index = isset($args[0]) ? trim($frame->expand($args[0])) : 0;
     $defaultVal = isset($args[1]) ? trim($frame->expand($args[1])) : '';
     // get matches from last #regex
     $lastMatches = self::getLastMatches($frame);
     if ($lastMatches === null) {
         // last regex was invalid or none executed yet
         return $defaultVal;
     }
     // if requested index is numerical:
     if (preg_match('/^\\d+$/', $index)) {
         // if requested index is in matches and isn't '':
         if (array_key_exists($index, $lastMatches) && $lastMatches[$index] !== '') {
             return $lastMatches[$index];
         } else {
             // no match! Return just the default value:
             return $defaultVal;
         }
     } else {
         // complex string is given, something like "$1, $2 and $3":
         // limit check, only in complex mode:
         if (self::limitExceeded($parser)) {
             return self::msgLimitExceeded();
         }
         self::increaseRegexCount($parser);
         // do the actual transformation:
         return self::regexVarReplace($index, $lastMatches, false);
     }
 }
Example #16
0
 /**
  * Return the text to be used for a given extension tag.
  * This is the ghost of strip().
  *
  * @param array $params Associative array of parameters:
  *     name       PPNode for the tag name
  *     attr       PPNode for unparsed text where tag attributes are thought to be
  *     attributes Optional associative array of parsed attributes
  *     inner      Contents of extension element
  *     noClose    Original text did not have a close tag
  * @param PPFrame $frame
  */
 function extensionSubstitution($params, $frame)
 {
     global $wgRawHtml, $wgContLang;
     $name = $frame->expand($params['name']);
     $attrText = !isset($params['attr']) ? null : $frame->expand($params['attr']);
     $content = !isset($params['inner']) ? null : $frame->expand($params['inner']);
     $marker = "{$this->mUniqPrefix}-{$name}-" . sprintf('%08X', $this->mMarkerIndex++) . self::MARKER_SUFFIX;
     if ($this->ot['html']) {
         $name = strtolower($name);
         $attributes = Sanitizer::decodeTagAttributes($attrText);
         if (isset($params['attributes'])) {
             $attributes = $attributes + $params['attributes'];
         }
         switch ($name) {
             case 'html':
                 if ($wgRawHtml) {
                     $output = $content;
                     break;
                 } else {
                     throw new MWException('<html> extension tag encountered unexpectedly');
                 }
             case 'nowiki':
                 $content = strtr($content, array('-{' => '-&#123;', '}-' => '&#125;-'));
                 $output = Xml::escapeTagsOnly($content);
                 break;
             case 'math':
                 $output = $wgContLang->armourMath(MathRenderer::renderMath($content, $attributes));
                 break;
             case 'gallery':
                 $output = $this->renderImageGallery($content, $attributes);
                 break;
             default:
                 if (isset($this->mTagHooks[$name])) {
                     # Workaround for PHP bug 35229 and similar
                     if (!is_callable($this->mTagHooks[$name])) {
                         throw new MWException("Tag hook for {$name} is not callable\n");
                     }
                     $output = call_user_func_array($this->mTagHooks[$name], array($content, $attributes, $this));
                 } else {
                     $output = '<span class="error">Invalid tag extension name: ' . htmlspecialchars($name) . '</span>';
                 }
         }
     } else {
         if (is_null($attrText)) {
             $attrText = '';
         }
         if (isset($params['attributes'])) {
             foreach ($params['attributes'] as $attrName => $attrValue) {
                 $attrText .= ' ' . htmlspecialchars($attrName) . '="' . htmlspecialchars($attrValue) . '"';
             }
         }
         if ($content === null) {
             $output = "<{$name}{$attrText}/>";
         } else {
             $close = is_null($params['close']) ? '' : $frame->expand($params['close']);
             $output = "<{$name}{$attrText}>{$content}{$close}";
         }
     }
     if ($name === 'html' || $name === 'nowiki') {
         $this->mStripState->nowiki->setPair($marker, $output);
     } else {
         $this->mStripState->general->setPair($marker, $output);
     }
     return $marker;
 }
Example #17
0
 /**
  * Return the text to be used for a given extension tag.
  * This is the ghost of strip().
  *
  * @param array $params Associative array of parameters:
  *     name       PPNode for the tag name
  *     attr       PPNode for unparsed text where tag attributes are thought to be
  *     attributes Optional associative array of parsed attributes
  *     inner      Contents of extension element
  *     noClose    Original text did not have a close tag
  * @param PPFrame $frame
  *
  * @throws MWException
  * @return string
  */
 public function extensionSubstitution($params, $frame)
 {
     $name = $frame->expand($params['name']);
     $attrText = !isset($params['attr']) ? null : $frame->expand($params['attr']);
     $content = !isset($params['inner']) ? null : $frame->expand($params['inner']);
     $marker = self::MARKER_PREFIX . "-{$name}-" . sprintf('%08X', $this->mMarkerIndex++) . self::MARKER_SUFFIX;
     $isFunctionTag = isset($this->mFunctionTagHooks[strtolower($name)]) && ($this->ot['html'] || $this->ot['pre']);
     if ($isFunctionTag) {
         $markerType = 'none';
     } else {
         $markerType = 'general';
     }
     if ($this->ot['html'] || $isFunctionTag) {
         $name = strtolower($name);
         $attributes = Sanitizer::decodeTagAttributes($attrText);
         if (isset($params['attributes'])) {
             $attributes = $attributes + $params['attributes'];
         }
         if (isset($this->mTagHooks[$name])) {
             # Workaround for PHP bug 35229 and similar
             if (!is_callable($this->mTagHooks[$name])) {
                 throw new MWException("Tag hook for {$name} is not callable\n");
             }
             $output = call_user_func_array($this->mTagHooks[$name], array($content, $attributes, $this, $frame));
         } elseif (isset($this->mFunctionTagHooks[$name])) {
             list($callback, ) = $this->mFunctionTagHooks[$name];
             if (!is_callable($callback)) {
                 throw new MWException("Tag hook for {$name} is not callable\n");
             }
             $output = call_user_func_array($callback, array(&$this, $frame, $content, $attributes));
         } else {
             $output = '<span class="error">Invalid tag extension name: ' . htmlspecialchars($name) . '</span>';
         }
         if (is_array($output)) {
             # Extract flags to local scope (to override $markerType)
             $flags = $output;
             $output = $flags[0];
             unset($flags[0]);
             extract($flags);
         }
     } else {
         if (is_null($attrText)) {
             $attrText = '';
         }
         if (isset($params['attributes'])) {
             foreach ($params['attributes'] as $attrName => $attrValue) {
                 $attrText .= ' ' . htmlspecialchars($attrName) . '="' . htmlspecialchars($attrValue) . '"';
             }
         }
         if ($content === null) {
             $output = "<{$name}{$attrText}/>";
         } else {
             $close = is_null($params['close']) ? '' : $frame->expand($params['close']);
             $output = "<{$name}{$attrText}>{$content}{$close}";
         }
     }
     if ($markerType === 'none') {
         return $output;
     } elseif ($markerType === 'nowiki') {
         $this->mStripState->addNoWiki($marker, $output);
     } elseif ($markerType === 'general') {
         $this->mStripState->addGeneral($marker, $output);
     } else {
         throw new MWException(__METHOD__ . ': invalid marker type');
     }
     return $marker;
 }
 /**
  * Handler for rendering the function hook registered by Parser::setFunctionHook() together
  * with object style arguments (SFH_OBJECT_ARGS flag).
  *
  * @since 0.4.13
  * 
  * @param Parser &$parser
  * @param PPFrame $frame
  * @param type $args
  * @return array 
  */
 public function renderFunctionObj(Parser &$parser, PPFrame $frame, $args)
 {
     $this->frame = $frame;
     // create non-object args for old style 'renderFunction()'
     $oldStyleArgs = array(&$parser);
     foreach ($args as $arg) {
         $oldStyleArgs[] = trim($frame->expand($arg));
     }
     /*
      * since we can't validate un-expandet arguments, we just go on with old-style function
      * handling from here. Only advantage is that we have $this->frame set properly.
      */
     return call_user_func_array(array($this, 'renderFunction'), $oldStyleArgs);
 }
 /**
  * Parser function to extension tag adaptor
  * @param Parser $parser
  * @param PPFrame $frame
  * @param PPNode[] $args
  * @return string
  */
 public static function tagObj($parser, $frame, $args)
 {
     if (!count($args)) {
         return '';
     }
     $tagName = strtolower(trim($frame->expand(array_shift($args))));
     if (count($args)) {
         $inner = $frame->expand(array_shift($args));
     } else {
         $inner = null;
     }
     $attributes = [];
     foreach ($args as $arg) {
         $bits = $arg->splitArg();
         if (strval($bits['index']) === '') {
             $name = trim($frame->expand($bits['name'], PPFrame::STRIP_COMMENTS));
             $value = trim($frame->expand($bits['value']));
             if (preg_match('/^(?:["\'](.+)["\']|""|\'\')$/s', $value, $m)) {
                 $value = isset($m[1]) ? $m[1] : '';
             }
             $attributes[$name] = $value;
         }
     }
     $stripList = $parser->getStripList();
     if (!in_array($tagName, $stripList)) {
         // we can't handle this tag (at least not now), so just re-emit it as an ordinary tag
         $attrText = '';
         foreach ($attributes as $name => $value) {
             $attrText .= ' ' . htmlspecialchars($name) . '="' . htmlspecialchars($value) . '"';
         }
         if ($inner === null) {
             return "<{$tagName}{$attrText}/>";
         }
         return "<{$tagName}{$attrText}>{$inner}</{$tagName}>";
     }
     $params = ['name' => $tagName, 'inner' => $inner, 'attributes' => $attributes, 'close' => "</{$tagName}>"];
     return $parser->extensionSubstitution($params, $frame);
 }
 /**
  * Base function for operations with multiple hashes given thru n parameters
  * $operationFunc expects a function name prefix (suffix 'multi_') with two parameters
  * $hash1 and $hash2 which will perform an action between $hash1 and hash2 which will
  * result into a new $hash1. There can be 1 to n $hash2 in the whole process.
  * 
  * @param $frame PPFrame
  * @param $args array
  * @param $operationFunc string name of the function calling this. There must be a counterpart
  *        function with prefix 'multi_' which should have two parameters. Both parameters
  *        will receive a hash (array), the function must return the result hash of the
  *        processing.
  * @param $runFuncOnSingleHash boolean whether the $operationFunc function should be run in case
  *        only one hash table id is given. If not, the original hash will end up in the new hash.
  */
 protected function multiHashOperation(PPFrame $frame, array $args, $operationFunc, $runFuncOnSingleHash = true)
 {
     $lastHash = null;
     $operationRan = false;
     $finalHashId = trim($frame->expand($args[0]));
     $operationFunc = 'multi_' . preg_replace('/^pfObj_/', '', $operationFunc);
     // For all hashes given in parameters 2 to n (ignore 1 because this is the name of the new hash)
     for ($i = 1; $i < count($args); $i++) {
         // just make sure we don't fall into gaps of given arguments:
         if (!array_key_exists($i, $args)) {
             continue;
         }
         $argHashId = trim($frame->expand($args[$i]));
         // ignore all tables which do not exist
         if ($this->hashExists($argHashId)) {
             $argHash = $this->getHash($argHashId);
             if ($lastHash === null) {
                 // first valid hash table, process together with second...
                 $lastHash = $argHash;
             } else {
                 // second or later hash table, process with previous:
                 $lastHash = $this->{$operationFunc}($lastHash, $argHash);
                 // perform action between last and current hash
                 $operationRan = true;
             }
         }
     }
     // in case no hash was given at all:
     if ($lastHash === null) {
         $lastHash = array();
     }
     // if the operation didn't run because there was only one or no array:
     if (!$operationRan && $runFuncOnSingleHash) {
         $lastHash = $this->{$operationFunc}($lastHash);
     }
     $this->setHash($finalHashId, $lastHash);
 }