static function formatLogEntry($type, $action, $title, $sk, $parameters)
 {
     switch ($action) {
         case 'merge':
             if ($parameters[0]) {
                 $msg = 'lqt-log-action-merge-across';
             } else {
                 $msg = 'lqt-log-action-merge-down';
             }
             break;
         default:
             $msg = 'lqt-log-action-' . $action;
             break;
     }
     $options = array('parseinline');
     $forIRC = $sk === null;
     if ($forIRC) {
         global $wgContLang;
         $options['language'] = $wgContLang->getCode();
     }
     $replacements = array_merge(array($title->getPrefixedText()), $parameters);
     $html = wfMsgExt($msg, $options, $replacements);
     if ($forIRC) {
         $html = StringUtils::delimiterReplace('<', '>', '', $html);
     }
     return $html;
 }
/**
 * adding the flag table to the comments form
 *
 * @global SFFormPrinter $sfgFormPrinter from SMW
 * @global Article $wgArticle
 * @param String $sHtml
 * @return boolean
 */
function onAddCommentsFormDiv(&$sHtml)
{
    global $sfgFormPrinter, $wgArticle, $webplatformSectionCommentsSMW;
    $sHtml .= '<a id="comments-flag-link">' . wfMessage('comments-flag-link')->text() . '</a>';
    $sHtml .= '<div id="comment-flags">';
    $sFormName = $webplatformSectionCommentsSMW['form'];
    //$sPageName = 'Comments';
    $oTitle = Title::newFromText($sFormName, SF_NS_FORM);
    $oArticle = new Article($oTitle, 0);
    $sFormDefinition = $oArticle->getContent();
    $sFormDefinition = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $sFormDefinition);
    $aHtml = $sfgFormPrinter->formHTML($sFormDefinition, false, true, $oTitle->getArticleID(), $wgArticle->fetchContent());
    //, $wgArticle->getTitle()->getArticleID(), $wgArticle->fetchContent(), $wgArticle->getTitle()->getText(), null );
    $aMatches = array();
    preg_match_all('#<table.*?</table>#is', $aHtml[0], $aMatches);
    $index = null;
    foreach ($aMatches[0] as $key => $value) {
        $bPos = strrpos($value, $webplatformSectionCommentsSMW['template'] . '[');
        if ($bPos !== false) {
            $index = $key;
            break;
        }
    }
    $sHtml .= $aMatches[0][$index];
    $sHtml .= '</div>';
    return true;
}
Exemple #3
0
 static function formatLogEntry($type, $action, $title, $sk, $parameters)
 {
     $msg = "lqt-log-action-{$action}";
     switch ($action) {
         case 'merge':
             if ($parameters[0]) {
                 $msg = 'lqt-log-action-merge-across';
             } else {
                 $msg = 'lqt-log-action-merge-down';
             }
             break;
         case 'move':
             $smt = new SpecialMoveThread();
             $rightsCheck = $smt->checkUserRights($parameters[1] instanceof Title ? $parameters[1] : Title::newFromText($parameters[1]), $parameters[0] instanceof Title ? $parameters[0] : Title::newFromText($parameters[0]));
             if ($rightsCheck === true) {
                 $parameters[] = Message::rawParam(Linker::link(SpecialPage::getTitleFor('MoveThread', $title), wfMessage('revertmove')->text(), array(), array('dest' => $parameters[0])));
             } else {
                 $parameters[] = '';
             }
             break;
         default:
             // Give grep a chance to find the usages:
             // lqt-log-action-move, lqt-log-action-split, lqt-log-action-subjectedit,
             // lqt-log-action-resort, lqt-log-action-signatureedit
             $msg = "lqt-log-action-{$action}";
             break;
     }
     array_unshift($parameters, $title->getPrefixedText());
     $html = wfMessage($msg, $parameters);
     if ($sk === null) {
         return StringUtils::delimiterReplace('<', '>', '', $html->inContentLanguage()->parse());
     }
     return $html->parse();
 }
Exemple #4
0
 /**
  * Core parser tag hook function for 'pre'.
  * Text is treated roughly as 'nowiki' wrapped in an HTML 'pre' tag;
  * valid HTML attributes are passed on.
  *
  * @param string $text
  * @param array $attribs
  * @param Parser $parser
  * @return string HTML
  */
 public static function pre($text, $attribs, $parser)
 {
     // Backwards-compatibility hack
     $content = StringUtils::delimiterReplace('<nowiki>', '</nowiki>', '$1', $text, 'i');
     $attribs = Sanitizer::validateTagAttributes($attribs, 'pre');
     return Xml::openElement('pre', $attribs) . Xml::escapeTagsOnly($content) . '</pre>';
 }
 function execute($query)
 {
     global $wgRequest, $wgOut;
     $wgOut->disable();
     $this->setHeaders();
     $page_name = $query;
     $title = Title::newFromText($page_name);
     if (is_null($title)) {
         return;
     }
     if (!$title->userCan('read')) {
         return;
     }
     $article = new Article($title);
     $page_text = $article->fetchContent();
     // Remove <noinclude> sections and <includeonly> tags from text
     $page_text = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $page_text);
     $page_text = strtr($page_text, array('<includeonly>' => '', '</includeonly>' => ''));
     $orig_lines = explode("\n", $page_text);
     // ignore lines that are either blank or start with a semicolon
     $page_lines = array();
     foreach ($orig_lines as $i => $line) {
         if ($line != '' && $line[0] != ';') {
             $page_lines[] = $line;
         }
     }
     $headers = EDUtils::getValuesFromCSVLine($page_lines[0]);
     $queried_headers = array();
     foreach ($wgRequest->getValues() as $key => $value) {
         foreach ($headers as $header_index => $header_value) {
             $header_value = str_replace(' ', '_', $header_value);
             if ($key == $header_value) {
                 $queried_headers[$header_index] = $value;
             }
         }
     }
     // include header in output
     $text = $page_lines[0];
     foreach ($page_lines as $i => $line) {
         if ($i == 0) {
             continue;
         }
         $row_values = EDUtils::getValuesFromCSVLine($line);
         $found_match = true;
         foreach ($queried_headers as $i => $query_value) {
             $single_value = str_replace(' ', '_', $row_values[$i]);
             if ($single_value != $query_value) {
                 $found_match = false;
             }
         }
         if ($found_match) {
             if ($text != '') {
                 $text .= "\n";
             }
             $text .= $line;
         }
     }
     print $text;
 }
 /**
  * Core parser tag hook function for 'pre'.
  * Text is treated roughly as 'nowiki' wrapped in an HTML 'pre' tag;
  * valid HTML attributes are passed on.
  *
  * @param string $text
  * @param array $attribs
  * @param Parser $parser
  * @return string HTML
  */
 public static function pre($text, $attribs, $parser)
 {
     // Backwards-compatibility hack
     $content = StringUtils::delimiterReplace('<nowiki>', '</nowiki>', '$1', $text, 'i');
     $attribs = Sanitizer::validateTagAttributes($attribs, 'pre');
     // We need to let both '"' and '&' through,
     // for strip markers and entities respectively.
     $content = str_replace(['>', '<'], ['&gt;', '&lt;'], $content);
     return Html::rawElement('pre', $attribs, $content);
 }
Exemple #7
0
 /**
  * Appends a preview of the actual form, when a page in the "Form"
  * namespace is previewed.
  *
  * @author Solitarius
  * @since 2.4
  *
  * @param EditPage $editpage
  * @param WebRequest $request
  *
  * @return true
  */
 public static function showFormPreview(EditPage $editpage, WebRequest $request)
 {
     global $wgOut, $sfgFormPrinter;
     wfDebug(__METHOD__ . ": enter.\n");
     wfProfileIn(__METHOD__);
     // Exit if we're not in preview mode.
     if (!$editpage->preview) {
         wfProfileOut(__METHOD__);
         return true;
     }
     // Exit if we aren't in the "Form" namespace.
     if ($editpage->getArticle()->getTitle()->getNamespace() != SF_NS_FORM) {
         wfProfileOut(__METHOD__);
         return true;
     }
     $editpage->previewTextAfterContent .= Html::element('h2', null, wfMessage('sf-preview-header')->text()) . "\n" . '<div class="previewnote" style="font-weight: bold">' . $wgOut->parse(wfMessage('sf-preview-note')->text()) . "</div>\n<hr />\n";
     $form_definition = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $editpage->textbox1);
     list($form_text, $javascript_text, $data_text, $form_page_title, $generated_page_name) = $sfgFormPrinter->formHTML($form_definition, null, false, null, null, "Semantic Forms form preview dummy title", null);
     SFUtils::addJavascriptAndCSS();
     $editpage->previewTextAfterContent .= '<div style="margin-top: 15px">' . $form_text . "</div>";
     wfProfileOut(__METHOD__);
     return true;
 }
 private function printForm(&$parameters, WebRequest &$request)
 {
     global $wgOut, $sfgFormPrinter;
     // Prepare parameters for SFFormPrinter::formHTML
     // there is no ONE target page
     $targetTitle = null;
     // formDefinition
     $formName = $request->getText('form');
     // if query string did not contain these variables, try the URL
     if ($formName === '') {
         $queryparts = explode('/', $parameters);
         $formName = isset($queryparts[0]) ? $queryparts[0] : null;
         // if the form name wasn't in the URL either, throw an error
         if (is_null($formName) || $formName === '') {
             throw new SPSException(SPSUtils::buildMessage('spserror-noformname'));
         }
     }
     $formTitle = Title::makeTitleSafe(SF_NS_FORM, $formName);
     if (!$formTitle->exists()) {
         throw new SPSException(SPSUtils::buildMessage('spserror-formunknown', $formName));
     }
     $formArticle = new Article($formTitle);
     $formDefinition = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $formArticle->getContent());
     // formSubmitted
     $formSubmitted = false;
     // pageContents
     $pageContents = null;
     // get 'preload' query value, if it exists
     if ($request->getCheck('preload')) {
         $pageContents = SFFormUtils::getPreloadedText($request->getVal('preload'));
     } else {
         // let other extensions preload the page, if they want
         wfRunHooks('sfEditFormPreloadText', array(&$pageContents, $targetTitle, $formTitle));
     }
     // pageIsSource
     $pageIsSource = $pageContents != null;
     // pageNameFormula
     // parse the form to see if it has a 'page name' value set
     $matches;
     if (preg_match('/{{{info.*page name\\s*=\\s*(.*)}}}/m', $formDefinition, $matches)) {
         $pageNameElements = SFUtils::getFormTagComponents($matches[1]);
         $pageNameFormula = $pageNameElements[0];
     } else {
         return 'sf_formedit_badurl';
     }
     // get the iterator parameters
     $iteratorData = $this->buildIteratorParameters($request);
     // Call SFFormPrinter::formHTML
     list($formText, $javascriptText, $dataText, $formPageTitle, $generatedPageName) = $sfgFormPrinter->formHTML($formDefinition, $formSubmitted, $pageIsSource, $formArticle->getID(), $pageContents, '', $pageNameFormula);
     // Set Special page main header;
     // override the default title for this page if a title was specified in the form
     if ($formPageTitle != null) {
         $wgOut->setPageTitle($formPageTitle);
     } else {
         $wgOut->setPageTitle(SPSUtils::buildMessage('sf_formedit_createtitlenotarget', $formTitle->getText()));
     }
     $preFormHtml = '';
     wfRunHooks('sfHTMLBeforeForm', array(&$targetTitle, &$preFormHtml));
     $text = '<form name="createbox" id="sfForm" action="" method="post" class="createbox">' . $preFormHtml . "\n" . SFFormUtils::hiddenFieldHTML('iteratordata', $iteratorData) . $formText;
     SFUtils::addJavascriptAndCSS();
     if (!empty($javascriptText)) {
         $wgOut->addScript('		<script type="text/javascript">' . "\n{$javascriptText}\n" . '</script>' . "\n");
     }
     $wgOut->addHTML($text);
     return null;
 }
 function getAllFieldsCargo($templateTitle)
 {
     $cargoFieldsOfTemplateParams = array();
     $templateFields = array();
     // First, get the table name, and fields, declared for this
     // template.
     $templatePageID = $templateTitle->getArticleID();
     $tableSchemaString = CargoUtils::getPageProp($templatePageID, 'CargoFields');
     // See if there even is DB storage for this template - if not,
     // exit.
     if (is_null($tableSchemaString)) {
         return null;
     }
     $tableSchema = CargoTableSchema::newFromDBString($tableSchemaString);
     $tableName = CargoUtils::getPageProp($templatePageID, 'CargoTableName');
     // Then, match template params to Cargo table fields, by
     // parsing call(s) to #cargo_store.
     $templateText = SFUtils::getPageText($templateTitle);
     // Ignore 'noinclude' sections and 'includeonly' tags.
     $templateText = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $templateText);
     $templateText = strtr($templateText, array('<includeonly>' => '', '</includeonly>' => ''));
     // Let's find every #cargo_store tag.
     // Unfortunately, it doesn't seem possible to use a regexp
     // search for this, because it's hard to know which set of
     // double brackets represents the end of such a call. Instead,
     // we'll do some manual parsing.
     $cargoStoreLocations = array();
     $curPos = 0;
     while (true) {
         $newPos = strpos($templateText, "#cargo_store:", $curPos);
         if ($newPos === false) {
             break;
         }
         $curPos = $newPos + 13;
         $cargoStoreLocations[] = $curPos;
     }
     $cargoStoreCalls = array();
     foreach ($cargoStoreLocations as $locNum => $startPos) {
         $numUnclosedBrackets = 2;
         if ($locNum < count($cargoStoreLocations) - 1) {
             $lastPos = $cargoStoreLocations[$locNum + 1];
         } else {
             $lastPos = strlen($templateText) - 1;
         }
         $curCargoStoreCall = '';
         $curPos = $startPos;
         while ($curPos <= $lastPos) {
             $curChar = $templateText[$curPos];
             $curCargoStoreCall .= $curChar;
             if ($curChar == '}') {
                 $numUnclosedBrackets--;
             } elseif ($curChar == '{') {
                 $numUnclosedBrackets++;
             }
             if ($numUnclosedBrackets == 0) {
                 break;
             }
             $curPos++;
         }
         $cargoStoreCalls[] = $curCargoStoreCall;
     }
     foreach ($cargoStoreCalls as $cargoStoreCall) {
         if (preg_match_all('/([^|{]*?)=\\s*{{{([^|}]*)/mis', $cargoStoreCall, $matches)) {
             foreach ($matches[1] as $i => $cargoFieldName) {
                 $templateParameter = trim($matches[2][$i]);
                 $cargoFieldsOfTemplateParams[$templateParameter] = $cargoFieldName;
             }
         }
     }
     // Now, combine the two sets of information into an array of
     // SFTemplateFields objects.
     $fieldDescriptions = $tableSchema->mFieldDescriptions;
     foreach ($cargoFieldsOfTemplateParams as $templateParameter => $cargoField) {
         $templateField = SFTemplateField::create($templateParameter, $templateParameter);
         if (array_key_exists($cargoField, $fieldDescriptions)) {
             $fieldDescription = $fieldDescriptions[$cargoField];
             $templateField->setCargoFieldData($tableName, $cargoField, $fieldDescription);
         }
         $templateFields[] = $templateField;
     }
     return $templateFields;
 }
Exemple #10
0
 /**
  * Depending on the requested action this method will try to store/preview
  * the data in mOptions or retrieve the edit form.
  *
  * The form and target page will be available in mOptions after execution of
  * the method.
  *
  * Errors and warnings are logged in the API result under the 'errors' key.
  * The general request status is maintained in mStatus.
  *
  * @global $wgRequest
  * @global $wgOut
  * @global $sfgFormPrinter
  * @throws MWException
  */
 public function doAction()
 {
     global $wgOut, $wgRequest, $sfgFormPrinter;
     // if the wiki is read-only, do not save
     if (wfReadOnly()) {
         if ($this->mAction === self::ACTION_SAVE) {
             throw new MWException(wfMessage('sf_autoedit_readonly', wfReadOnlyReason())->parse());
         }
         // even if not saving notify client anyway. Might want to dislay a notice
         $this->logMessage(wfMessage('sf_autoedit_readonly', wfReadOnlyReason())->parse(), self::NOTICE);
     }
     // find the title of the form to be used
     $formTitle = $this->getFormTitle();
     // get the form content
     $formContent = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', WikiPage::factory($formTitle)->getRawText());
     // signals that the form was submitted
     // always true, else we would not be here
     $isFormSubmitted = $this->mAction === self::ACTION_SAVE || $this->mAction === self::ACTION_PREVIEW;
     // the article id of the form to be used
     $formArticleId = $formTitle->getArticleID();
     // source of the data is a page
     $isPageSource = true;
     // the name of the target page; might be empty when using the one-step-process
     $targetName = $this->mOptions['target'];
     // if the target page was not specified, try finding the page name formula
     // (Why is this not done in SFFormPrinter::formHTML?)
     if ($targetName === '') {
         // parse the form to see if it has a 'page name' value set
         if (preg_match('/{{{info.*page name\\s*=\\s*(.*)}}}/m', $formContent, $matches)) {
             $pageNameElements = SFUtils::getFormTagComponents($matches[1]);
             $targetNameFormula = $pageNameElements[0];
         } else {
             throw new MWException(wfMessage('sf_autoedit_notargetspecified')->parse());
         }
         $targetTitle = null;
     } else {
         $targetNameFormula = null;
         $targetTitle = Title::newFromText($targetName);
     }
     $preloadContent = '';
     // save $wgRequest for later restoration
     $oldRequest = $wgRequest;
     // preload data if not explicitly excluded and if the preload page exists
     if (!isset($this->mOptions['preload']) || $this->mOptions['preload'] !== false) {
         if (!isset($this->mOptions['preload']) || $this->mOptions['preload'] === true) {
             $preloadTitle = Title::newFromText($targetName);
         } else {
             $preloadTitle = Title::newFromText($this->mOptions['preload']);
         }
         if ($preloadTitle !== null && $preloadTitle->exists()) {
             // the content of the page that was specified to be used for preloading
             $preloadContent = WikiPage::factory($preloadTitle)->getRawText();
             wfRunHooks('sfEditFormPreloadText', array(&$preloadContent, $targetTitle, $formTitle));
             $isPageSource = true;
             // spoof $wgRequest for SFFormPrinter::formHTML
             $wgRequest = new FauxRequest($this->mOptions, true);
             // save wgOut for later restoration
             $oldOut = $wgOut;
             // spoof wgOut; if we took the general $wgOut some JS modules
             // might attach themselves twice and thus be called twice
             $wgOut = new OutputPage(RequestContext::getMain());
             // call SFFormPrinter::formHTML to get at the form html of the existing page
             list($formHTML, $formJS, $targetContent, $form_page_title, $generatedTargetNameFormula) = $sfgFormPrinter->formHTML($formContent, $isFormSubmitted, $isPageSource, $formArticleId, $preloadContent, $targetName, $targetNameFormula);
             // restore wgOut
             $wgOut = $oldOut;
             // parse the data to be preloaded from the form html of the
             // existing page
             $data = $this->parseDataFromHTMLFrag($formHTML);
             // and merge/overwrite it with the new data
             $this->mOptions = SFUtils::array_merge_recursive_distinct($data, $this->mOptions);
         } else {
             if (isset($this->mOptions['preload'])) {
                 $this->logMessage(wfMessage('sf_autoedit_invalidpreloadspecified', $this->mOptions['preload'])->parse(), self::WARNING);
             }
         }
     }
     // we already preloaded stuff for saving/previewing, do not do it again
     if ($this->mAction === self::ACTION_SAVE || $this->mAction === self::ACTION_PREVIEW) {
         $preloadContent = '';
         $isPageSource = false;
     }
     // spoof wgRequest for SFFormPrinter::formHTML
     $wgRequest = new FauxRequest($this->mOptions, true);
     // get wikitext for submitted data and form
     list($formHTML, $formJS, $targetContent, $generatedFormName, $generatedTargetNameFormula) = $sfgFormPrinter->formHTML($formContent, $isFormSubmitted, $isPageSource, $formArticleId, $preloadContent, $targetName, $targetNameFormula);
     // restore original request
     $wgRequest = $oldRequest;
     if ($generatedFormName !== '') {
         $formTitle = Title::newFromText($generatedFormName);
         $this->mOptions['form'] = $formTitle->getText();
     }
     $this->mOptions['formHTML'] = $formHTML;
     $this->mOptions['formJS'] = $formJS;
     if ($this->mAction === self::ACTION_SAVE || $this->mAction === self::ACTION_PREVIEW) {
         // if the target page was not specified, see if something was generated
         // from the target name formula
         if ($this->mOptions['target'] === '') {
             // if no name was generated, we can not save => give up
             if ($generatedTargetNameFormula === '') {
                 throw new MWException(wfMessage('sf_autoedit_notargetspecified')->parse());
             }
             $this->mOptions['target'] = $this->generateTargetName($generatedTargetNameFormula);
         }
         // Lets other code process additional form-definition syntax
         wfRunHooks('sfWritePageData', array($this->mOptions['form'], Title::newFromText($this->mOptions['target']), &$targetContent));
         $editor = $this->setupEditPage($targetContent);
         // perform the requested action
         if ($this->mAction === self::ACTION_PREVIEW) {
             $this->doPreview($editor);
         } else {
             $this->doStore($editor);
         }
     } else {
         if ($this->mAction === self::ACTION_FORMEDIT) {
             $this->doFormEdit($formHTML, $formJS);
         }
     }
 }
Exemple #11
0
    /**
     * Pick apart some CSS and check it for forbidden or unsafe structures.
     * Returns a sanitized string. This sanitized string will have
     * character references and escape sequences decoded and comments
     * stripped (unless it is itself one valid comment, in which case the value
     * will be passed through). If the input is just too evil, only a comment
     * complaining about evilness will be returned.
     *
     * Currently URL references, 'expression', 'tps' are forbidden.
     *
     * NOTE: Despite the fact that character references are decoded, the
     * returned string may contain character references given certain
     * clever input strings. These character references must
     * be escaped before the return value is embedded in HTML.
     *
     * @param string $value
     * @return string
     */
    static function checkCss($value)
    {
        // Decode character references like &#123;
        $value = Sanitizer::decodeCharReferences($value);
        // Decode escape sequences and line continuation
        // See the grammar in the CSS 2 spec, appendix D.
        // This has to be done AFTER decoding character references.
        // This means it isn't possible for this function to return
        // unsanitized escape sequences. It is possible to manufacture
        // input that contains character references that decode to
        // escape sequences that decode to character references, but
        // it's OK for the return value to contain character references
        // because the caller is supposed to escape those anyway.
        static $decodeRegex;
        if (!$decodeRegex) {
            $space = '[\\x20\\t\\r\\n\\f]';
            $nl = '(?:\\n|\\r\\n|\\r|\\f)';
            $backslash = '\\\\';
            $decodeRegex = "/ {$backslash}\n\t\t\t\t(?:\n\t\t\t\t\t({$nl}) |  # 1. Line continuation\n\t\t\t\t\t([0-9A-Fa-f]{1,6}){$space}? |  # 2. character number\n\t\t\t\t\t(.) | # 3. backslash cancelling special meaning\n\t\t\t\t\t() | # 4. backslash at end of string\n\t\t\t\t)/xu";
        }
        $value = preg_replace_callback($decodeRegex, array(__CLASS__, 'cssDecodeCallback'), $value);
        // Normalize Halfwidth and Fullwidth Unicode block that IE6 might treat as ascii
        $value = preg_replace_callback('/[!-[]-z]/u', function ($matches) {
            $cp = utf8ToCodepoint($matches[0]);
            if ($cp === false) {
                return '';
            }
            return chr($cp - 65248);
            // ASCII range \x21-\x7A
        }, $value);
        // Convert more characters IE6 might treat as ascii
        // U+0280, U+0274, U+207F, U+029F, U+026A, U+207D, U+208D
        $value = str_replace(array('ʀ', 'ɴ', 'ⁿ', 'ʟ', 'ɪ', '⁽', '₍'), array('r', 'n', 'n', 'l', 'i', '(', '('), $value);
        // Let the value through if it's nothing but a single comment, to
        // allow other functions which may reject it to pass some error
        // message through.
        if (!preg_match('! ^ \\s* /\\* [^*\\/]* \\*/ \\s* $ !x', $value)) {
            // Remove any comments; IE gets token splitting wrong
            // This must be done AFTER decoding character references and
            // escape sequences, because those steps can introduce comments
            // This step cannot introduce character references or escape
            // sequences, because it replaces comments with spaces rather
            // than removing them completely.
            $value = StringUtils::delimiterReplace('/*', '*/', ' ', $value);
            // Remove anything after a comment-start token, to guard against
            // incorrect client implementations.
            $commentPos = strpos($value, '/*');
            if ($commentPos !== false) {
                $value = substr($value, 0, $commentPos);
            }
        }
        // S followed by repeat, iteration, or prolonged sound marks,
        // which IE will treat as "ss"
        $value = preg_replace('/s(?:
				\\xE3\\x80\\xB1 | # U+3031
				\\xE3\\x82\\x9D | # U+309D
				\\xE3\\x83\\xBC | # U+30FC
				\\xE3\\x83\\xBD | # U+30FD
				\\xEF\\xB9\\xBC | # U+FE7C
				\\xEF\\xB9\\xBD | # U+FE7D
				\\xEF\\xBD\\xB0   # U+FF70
			)/ix', 'ss', $value);
        // Reject problematic keywords and control characters
        if (preg_match('/[\\000-\\010\\013\\016-\\037\\177]/', $value)) {
            return '/* invalid control char */';
        } elseif (preg_match('! expression
				| filter\\s*:
				| accelerator\\s*:
				| -o-link\\s*:
				| -o-link-source\\s*:
				| -o-replace\\s*:
				| url\\s*\\(
				| image\\s*\\(
				| image-set\\s*\\(
			!ix', $value)) {
            return '/* insecure input */';
        }
        return $value;
    }
Exemple #12
0
 public function formSerialize($form_def = '', $source_is_page = false, $existing_page_content = null, $page_title = null)
 {
     //	public function formSerialize($form_def, $source_is_page, $existing_page_content = null, $page_title = null, $page_name_formula = null) {
     global $wgRequest, $wgUser, $wgParser;
     global $sfgTabIndex;
     // used to represent the current tab index in the form
     global $sfgFieldNum;
     // used for setting various HTML IDs
     global $sfgJSValidationCalls;
     // array of Javascript calls to determine if page can be saved
     # define a var for all fields
     $__fields = array();
     // initialize some variables
     $sfgTabIndex = 1;
     $sfgFieldNum = 1;
     $source_page_matches_this_form = false;
     $form_page_title = NULL;
     // $form_is_partial is true if:
     // (a) 'partial' == 1 in the arguments
     // (b) 'partial form' is found in the form definition
     // in the latter case, it may remain false until close to the end of
     // the parsing, so we have to assume that it will become a possibility
     $form_is_partial = false;
     $new_text = "";
     // if we have existing content and we're not in an active replacement
     // situation, preserve the original content. We do this because we want
     // to pass the original content on IF this is a partial form
     // TODO: A better approach here would be to pass the revision id of the
     // existing page content through the replace value, which would
     // minimize the html traffic and would allow us to do a concurrent
     // update check.  For now, we pass it through the hidden text field...
     if (!$wgRequest->getCheck('partial')) {
         $original_page_content = $existing_page_content;
     } else {
         $original_page_content = null;
         if ($wgRequest->getCheck('free_text')) {
             $existing_page_content = $wgRequest->getVal('free_text');
             $form_is_partial = true;
         }
     }
     // disable all form elements if user doesn't have edit permission -
     // two different checks are needed, because editing permissions can be
     // set in different ways
     // HACK - sometimes we don't know the page name in advance, but we still
     // need to set a title here for testing permissions
     if ($page_title == '') {
         $this->mPageTitle = Title::newFromText("Semantic Forms permissions test");
     } else {
         $this->mPageTitle = Title::newFromText($page_title);
     }
     if ($wgUser->isAllowed('edit') && $this->mPageTitle->userCanEdit()) {
         $form_is_disabled = false;
         $form_text = "";
         // show "Your IP address will be recorded" warning if user is
         // anonymous - wikitext for bolding has to be replaced with HTML
         if ($wgUser->isAnon()) {
             $anon_edit_warning = preg_replace("/'''(.*)'''/", "<strong>\$1</strong>", wfMsg('anoneditwarning'));
             $form_text .= "<p>{$anon_edit_warning}</p>\n";
         }
     } else {
         $form_is_disabled = true;
         // display a message to the user explaining why they can't edit the
         // page - borrowed heavily from EditPage.php
         if ($wgUser->isAnon()) {
             $skin = $wgUser->getSkin();
             $loginTitle = SpecialPage::getTitleFor('Userlogin');
             $loginLink = $skin->makeKnownLinkObj($loginTitle, wfMsgHtml('loginreqlink'));
             $form_text = wfMsgWikiHtml('whitelistedittext', $loginLink);
         } else {
             $form_text = wfMsg('protectedpagetext');
         }
     }
     $javascript_text = "";
     $sfgJSValidationCalls = array();
     $fields_javascript_text = "";
     // Remove <noinclude> sections and <includeonly> tags from form definition
     $form_def = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $form_def);
     $form_def = strtr($form_def, array('<includeonly>' => '', '</includeonly>' => ''));
     // parse wiki-text
     // add '<nowiki>' tags around every triple-bracketed form definition
     // element, so that the wiki parser won't touch it - the parser will
     // remove the '<nowiki>' tags, leaving us with what we need
     global $sfgDisableWikiTextParsing;
     if (!$sfgDisableWikiTextParsing) {
         $form_def = "__NOEDITSECTION__" . strtr($form_def, array('{{{' => '<nowiki>{{{', '}}}' => '}}}</nowiki>'));
         $wgParser->mOptions = new ParserOptions();
         $wgParser->mOptions->initialiseFromUser($wgUser);
         $form_def = $wgParser->parse($form_def, $this->mPageTitle, $wgParser->mOptions)->getText();
     }
     // turn form definition file into an array of sections, one for each
     // template definition (plus the first section)
     $form_def_sections = array();
     $start_position = 0;
     $section_start = 0;
     $free_text_was_included = false;
     $free_text_preload_page = null;
     $all_values_for_template = array();
     // unencode and HTML-encoded representations of curly brackets and
     // pipes - this is a hack to allow for forms to include templates
     // that themselves contain form elements - the escaping is needed
     // to make sure that those elements don't get parsed too early
     $form_def = str_replace(array('&#123;', '&#124;', '&#125;'), array('{', '|', '}'), $form_def);
     // and another hack - replace the 'free text' standard input with
     // a field declaration to get it to be handled as a field
     $form_def = str_replace('standard input|free text', 'field|<freetext>', $form_def);
     while ($brackets_loc = strpos($form_def, "{{{", $start_position)) {
         $brackets_end_loc = strpos($form_def, "}}}", $brackets_loc);
         $bracketed_string = substr($form_def, $brackets_loc + 3, $brackets_end_loc - ($brackets_loc + 3));
         $tag_components = explode('|', $bracketed_string);
         $tag_title = trim($tag_components[0]);
         if ($tag_title == 'for template' || $tag_title == 'end template') {
             // create a section for everything up to here
             $section = substr($form_def, $section_start, $brackets_loc - $section_start);
             $form_def_sections[] = $section;
             $section_start = $brackets_loc;
         }
         $start_position = $brackets_loc + 1;
     }
     // end while
     $form_def_sections[] = trim(substr($form_def, $section_start));
     // cycle through form definition file (and possibly an existing article
     // as well), finding template and field declarations and replacing them
     // with form elements, either blank or pre-populated, as appropriate
     $all_fields = array();
     $data_text = "";
     $template_name = "";
     $allow_multiple = false;
     $instance_num = 0;
     $all_instances_printed = false;
     $strict_parsing = false;
     // initialize list of choosers (dropdowns with available templates)
     $choosers = array();
     for ($section_num = 0; $section_num < count($form_def_sections); $section_num++) {
         $tif = new SFTemplateInForm();
         $start_position = 0;
         $template_text = "";
         // the append is there to ensure that the original array doesn't get
         // modified; is it necessary?
         $section = " " . $form_def_sections[$section_num];
         while ($brackets_loc = strpos($section, '{{{', $start_position)) {
             $brackets_end_loc = strpos($section, "}}}", $brackets_loc);
             $bracketed_string = substr($section, $brackets_loc + 3, $brackets_end_loc - ($brackets_loc + 3));
             $tag_components = explode('|', $bracketed_string);
             $tag_title = trim($tag_components[0]);
             // =====================================================
             // for template processing
             // =====================================================
             if ($tag_title == 'for template') {
                 $old_template_name = $template_name;
                 $template_name = trim($tag_components[1]);
                 $tif->template_name = $template_name;
                 $query_template_name = str_replace(' ', '_', $template_name);
                 // also replace periods with underlines, since that's what
                 // POST does to strings anyway
                 $query_template_name = str_replace('.', '_', $query_template_name);
                 $chooser_name = false;
                 $chooser_caption = false;
                 // cycle through the other components
                 for ($i = 2; $i < count($tag_components); $i++) {
                     $component = $tag_components[$i];
                     if ($component == 'multiple') {
                         $allow_multiple = true;
                     }
                     if ($component == 'strict') {
                         $strict_parsing = true;
                     }
                     $sub_components = explode('=', $component);
                     if (count($sub_components) == 2) {
                         if ($sub_components[0] == 'label') {
                             $template_label = $sub_components[1];
                         } elseif ($sub_components[0] == 'chooser') {
                             $allow_multiple = true;
                             $chooser_name = $sub_components[1];
                         } elseif ($sub_components[0] == 'chooser caption') {
                             $chooser_caption = $sub_components[1];
                         }
                     }
                 }
                 // if this is the first instance, add the label in the form
                 if ($old_template_name != $template_name && isset($template_label)) {
                     // add a placeholder to the form text so the fieldset can be
                     // hidden if chooser support demands it
                     if ($chooser_name !== false) {
                         $form_text .= "<fieldset [[placeholder]] haschooser=true>\n";
                     } else {
                         $form_text .= "<fieldset>\n";
                     }
                     $form_text .= "<legend>{$template_label}</legend>\n";
                 }
                 $template_text .= "{{" . $tif->template_name;
                 # reads all the fields of the template definition page
                 $all_fields = $tif->getAllFields();
                 // remove template tag
                 $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                 $template_instance_query_values = $wgRequest->getArray($query_template_name);
                 // if we are editing a page, and this template can be found more than
                 // once in that page, and multiple values are allowed, repeat this
                 // section
                 $existing_template_text = null;
                 // replace underlines with spaces in template name, to allow for
                 // searching on either
                 $search_template_str = str_replace('_', ' ', $tif->template_name);
                 if ($source_is_page || $form_is_partial) {
                     if ($allow_multiple) {
                         // find instances of this template in the page -
                         // if there's at least one, re-parse this section of the
                         // definition form for the subsequent template instances in
                         // this page; if there's none, don't include fields at all.
                         // there has to be a more efficient way to handle multiple
                         // instances of templates, one that doesn't involve re-parsing
                         // the same tags, but I don't know what it is.
                         if (stripos(str_replace('_', ' ', $existing_page_content), '{{' . $search_template_str) !== false) {
                             $instance_num++;
                         } else {
                             $all_instances_printed = true;
                         }
                     }
                     // get the first instance of this template on the page being edited,
                     // even if there are more
                     if (($start_char = stripos(str_replace('_', ' ', $existing_page_content), '{{' . $search_template_str)) !== false) {
                         $fields_start_char = $start_char + 2 + strlen($search_template_str);
                         // skip ahead to the first real character
                         while (in_array($existing_page_content[$fields_start_char], array(' ', '\\n', '|'))) {
                             $fields_start_char++;
                         }
                         $template_contents = array('0' => '');
                         // cycle through template call, splitting it up by pipes ('|'),
                         // except when that pipe is part of a piped link
                         $field = "";
                         $uncompleted_square_brackets = 0;
                         $uncompleted_curly_brackets = 2;
                         $template_ended = false;
                         for ($i = $fields_start_char; !$template_ended && $i < strlen($existing_page_content); $i++) {
                             $c = $existing_page_content[$i];
                             if ($c == '[') {
                                 $uncompleted_square_brackets++;
                             } elseif ($c == ']' && $uncompleted_square_brackets > 0) {
                                 $uncompleted_square_brackets--;
                             } elseif ($c == '{') {
                                 $uncompleted_curly_brackets++;
                             } elseif ($c == '}' && $uncompleted_curly_brackets > 0) {
                                 $uncompleted_curly_brackets--;
                             }
                             // handle an end to a field and/or template declaration
                             $template_ended = $uncompleted_curly_brackets == 0 && $uncompleted_square_brackets == 0;
                             $field_ended = $c == '|' && $uncompleted_square_brackets == 0;
                             if ($template_ended || $field_ended) {
                                 // if this was the last character in the template, remove
                                 // the closing curly brackets
                                 if ($template_ended) {
                                     $field = substr($field, 0, -1);
                                 }
                                 // either there's an equals sign near the beginning or not -
                                 // handling is similar in either way; if there's no equals
                                 // sign, the index of this field becomes the key
                                 $sub_fields = explode('=', $field, 2);
                                 if (count($sub_fields) > 1) {
                                     $template_contents[trim($sub_fields[0])] = trim($sub_fields[1]);
                                 } else {
                                     $template_contents[] = trim($sub_fields[0]);
                                 }
                                 $field = '';
                             } else {
                                 $field .= $c;
                             }
                         }
                         $existing_template_text = substr($existing_page_content, $start_char, $i - $start_char);
                         // now remove this template from the text being edited
                         // if this is a partial form, establish a new insertion point
                         if ($existing_page_content && $form_is_partial && $wgRequest->getCheck('partial')) {
                             // if something already exists, set the new insertion point
                             // to its position; otherwise just let it lie
                             if (strpos($existing_page_content, $existing_template_text) !== false) {
                                 $existing_page_content = str_replace('{{{insertionpoint}}}', '', $existing_page_content);
                                 $existing_page_content = str_replace($existing_template_text, '{{{insertionpoint}}}', $existing_page_content);
                             }
                         } else {
                             $existing_page_content = str_replace($existing_template_text, '', $existing_page_content);
                         }
                         // if this is not a multiple-instance template, and we've found
                         // a match in the source page, there's a good chance that this
                         // page was created with this form - note that, so we don't
                         // send the user a warning
                         // (multiple-instance templates have a greater chance of
                         // getting repeated from one form to the next)
                         if (!$allow_multiple) {
                             $source_page_matches_this_form = true;
                         }
                     }
                 }
                 // if the input is from the form (meaning the user has hit one
                 // of the bottom row of buttons), and we're dealing with a
                 // multiple template, get the values for this instance of this
                 // template, then delete them from the array, so we can get the
                 // next group next time - the next() command for arrays doesn't
                 // seem to work here
                 if (!$source_is_page && $allow_multiple && $wgRequest) {
                     $all_instances_printed = true;
                     if ($old_template_name != $template_name) {
                         $all_values_for_template = $wgRequest->getArray($query_template_name);
                     }
                     if ($all_values_for_template) {
                         $cur_key = key($all_values_for_template);
                         // skip the input coming in from the "starter" div
                         if ($cur_key == 'num') {
                             unset($all_values_for_template[$cur_key]);
                             $cur_key = key($all_values_for_template);
                         }
                         if ($template_instance_query_values = current($all_values_for_template)) {
                             $all_instances_printed = false;
                             unset($all_values_for_template[$cur_key]);
                         }
                     }
                 }
                 //  save the template name
                 $field = array();
                 $field['tmpl_name'] = $tif->template_name;
                 // =====================================================
                 // end template processing
                 // =====================================================
             } elseif ($tag_title == 'end template') {
                 // remove this tag, reset some variables, and close off form HTML tag
                 $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                 $template_name = null;
                 if (isset($template_label)) {
                     $form_text .= "</fieldset>\n";
                     unset($template_label);
                 }
                 $allow_multiple = false;
                 $all_instances_printed = false;
                 $instance_num = 0;
                 // if the hiding placeholder is still around, this fieldset should
                 // be hidden because it is empty and choosers are being used. So,
                 // hide it.
                 $form_text = str_replace("[[placeholder]]", "style='display:none'", $form_text);
                 $__fields["template" . count($__fields)] = $field;
                 // =====================================================
                 // field processing
                 // =====================================================
             } elseif ($tag_title == 'field') {
                 $field_name = trim($tag_components[1]);
                 // cycle through the other components
                 $is_mandatory = false;
                 $is_hidden = false;
                 $is_restricted = false;
                 $is_uploadable = false;
                 $is_list = false;
                 $input_type = null;
                 $field_args = array();
                 $default_value = "";
                 $possible_values = null;
                 $preload_page = null;
                 for ($i = 2; $i < count($tag_components); $i++) {
                     $component = trim($tag_components[$i]);
                     if ($component == 'mandatory') {
                         $is_mandatory = true;
                     } elseif ($component == 'hidden') {
                         $is_hidden = true;
                     } elseif ($component == 'restricted') {
                         $is_restricted = true;
                     } elseif ($component == 'uploadable') {
                         $field_args['is_uploadable'] = true;
                     } elseif ($component == 'list') {
                         $is_list = true;
                     } elseif ($component == 'autocomplete') {
                         $field_args['autocomplete'] = true;
                     } elseif ($component == 'no autocomplete') {
                         $field_args['no autocomplete'] = true;
                     } elseif ($component == 'remote autocompletion') {
                         $field_args['remote autocompletion'] = true;
                     } else {
                         $sub_components = explode('=', $component);
                         if (count($sub_components) == 2) {
                             if ($sub_components[0] == 'input type') {
                                 $input_type = $sub_components[1];
                             } elseif ($sub_components[0] == 'default') {
                                 $default_value = $sub_components[1];
                             } elseif ($sub_components[0] == 'preload') {
                                 // free text field has special handling
                                 if ($field_name == 'free text' || ($field_name = '<freetext>')) {
                                     $free_text_preload_page = $sub_components[1];
                                 } else {
                                     // this variable is not used
                                     $preload_page = $sub_components[1];
                                 }
                             } elseif ($sub_components[0] == 'values') {
                                 $possible_values = explode(',', $sub_components[1]);
                             } elseif ($sub_components[0] == 'values from category') {
                                 $possible_values = SFUtils::getAllPagesForCategory($sub_components[1], 10);
                             } elseif ($sub_components[0] == 'values from concept') {
                                 $possible_values = SFUtils::getAllPagesForConcept($sub_components[1]);
                             } else {
                                 $field_args[$sub_components[0]] = $sub_components[1];
                             }
                             // for backwards compatibility
                             if ($sub_components[0] == 'autocomplete on' && $sub_components[1] == null) {
                                 $field_args['no autocomplete'] = true;
                             }
                         }
                     }
                 }
                 $field_args['part_of_multiple'] = $allow_multiple;
                 // get the value from the request, if it's there, and if it's not
                 // an array
                 $escaped_field_name = str_replace("'", "\\'", $field_name);
                 if (isset($template_instance_query_values) && $template_instance_query_values != null && array_key_exists($escaped_field_name, $template_instance_query_values)) {
                     $field_query_val = $template_instance_query_values[$escaped_field_name];
                     if ($field_query_val && !is_array($field_query_val)) {
                         $cur_value = $field_query_val;
                     }
                 } else {
                     $cur_value = '';
                 }
                 if ($cur_value && !is_array($cur_value)) {
                     # no escaping needed
                     // $cur_value = str_replace('"', '&quot;', $cur_value);
                 }
                 if ($cur_value == null) {
                     // set to default value specified in the form, if it's there
                     $cur_value = $default_value;
                 }
                 // if the user is starting to edit a page, and that page contains
                 // the current template being processed, get the current template
                 // field's value in the existing page
                 if ($source_is_page && !empty($existing_template_text)) {
                     if (isset($template_contents[$field_name])) {
                         $cur_value = $template_contents[$field_name];
                     } else {
                         $cur_value = '';
                     }
                     if ($cur_value) {
                         # no escaping needed
                         // $cur_value = str_replace('"', '&quot;', $cur_value);
                     }
                 }
                 // handle the free text field - if it was declared as
                 // "field|free text" (a deprecated usage), it has to be outside
                 // of a template
                 if ($template_name == '' && $field_name == 'free text' || $field_name == '<freetext>') {
                     // add placeholders for the free text in both the form and
                     // the page, using <free_text> tags - once all the free text
                     // is known (at the end), it will get substituted in
                     if ($is_hidden) {
                         $new_text = SFFormUtils::hiddenFieldHTML('free_text', '<free_text>');
                     } else {
                         if (!array_key_exists('rows', $field_args)) {
                             $field_args['rows'] = 5;
                         }
                         if (!array_key_exists('cols', $field_args)) {
                             $field_args['cols'] = 80;
                         }
                         $sfgTabIndex++;
                         $sfgFieldNum++;
                         list($new_text, $new_javascript_text) = SFFormInputs::textAreaHTML('<free_text>', 'free_text', false, $form_is_disabled || $is_restricted, $field_args);
                         $fields_javascript_text .= $new_javascript_text;
                     }
                     $free_text_was_included = true;
                     // add a similar placeholder to the data text
                     $data_text .= "<free_text>\n";
                 }
                 if ($template_name == '') {
                     $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                 } else {
                     if (is_array($cur_value)) {
                         // first, check if it's a list
                         if (array_key_exists('is_list', $cur_value) && $cur_value['is_list'] == true) {
                             $cur_value_in_template = "";
                             if (array_key_exists('delimiter', $field_args)) {
                                 $delimiter = $field_args['delimiter'];
                             } else {
                                 $delimiter = ",";
                             }
                             foreach ($cur_value as $key => $val) {
                                 if ($key !== "is_list") {
                                     if ($cur_value_in_template != "") {
                                         $cur_value_in_template .= $delimiter . " ";
                                     }
                                     $cur_value_in_template .= $val;
                                 }
                             }
                         } else {
                             // otherwise:
                             // if it has 1 or 2 elements, assume it's a checkbox; if it has
                             // 3 elements, assume it's a date
                             // - this handling will have to get more complex if other
                             // possibilities get added
                             if (count($cur_value) == 1) {
                                 // manually load SMW's message values here, in case they
                                 // didn't get loaded before
                                 wfLoadExtensionMessages('SemanticMediaWiki');
                                 $words_for_false = explode(',', wfMsgForContent('smw_false_words'));
                                 // for each language, there's a series of words that are
                                 // equal to false - get the word in the series that matches
                                 // "no"; generally, that's the third word
                                 $index_of_no = 2;
                                 if (count($words_for_false) > $index_of_no) {
                                     $no = ucwords($words_for_false[$index_of_no]);
                                 } elseif (count($words_for_false) == 0) {
                                     $no = "0";
                                     // some safe value if no words are found
                                 } else {
                                     $no = ucwords($words_for_false[0]);
                                 }
                                 $cur_value_in_template = $no;
                             } elseif (count($cur_value) == 2) {
                                 wfLoadExtensionMessages('SemanticMediaWiki');
                                 $words_for_true = explode(',', wfMsgForContent('smw_true_words'));
                                 // get the value in the 'true' series that tends to be "yes",
                                 // and go with that one - generally, that's the third word
                                 $index_of_yes = 2;
                                 if (count($words_for_true) > $index_of_yes) {
                                     $yes = ucwords($words_for_true[$index_of_yes]);
                                 } elseif (count($words_for_true) == 0) {
                                     $yes = "1";
                                     // some safe value if no words are found
                                 } else {
                                     $yes = ucwords($words_for_true[0]);
                                 }
                                 $cur_value_in_template = $yes;
                                 // if it's 3 or greater, assume it's a date or datetime
                             } elseif (count($cur_value) >= 3) {
                                 $month = $cur_value['month'];
                                 $day = $cur_value['day'];
                                 if ($day != '') {
                                     global $wgAmericanDates;
                                     if ($wgAmericanDates == false) {
                                         // pad out day to always be two digits
                                         $day = str_pad($day, 2, "0", STR_PAD_LEFT);
                                     }
                                 }
                                 $year = $cur_value['year'];
                                 if (isset($cur_value['hour'])) {
                                     $hour = $cur_value['hour'];
                                 }
                                 if (isset($cur_value['minute'])) {
                                     $minute = $cur_value['minute'];
                                 }
                                 if (isset($cur_value['second'])) {
                                     $second = $cur_value['second'];
                                 }
                                 if (isset($cur_value['ampm24h'])) {
                                     $ampm24h = $cur_value['ampm24h'];
                                 }
                                 if (isset($cur_value['timezone'])) {
                                     $timezone = $cur_value['timezone'];
                                 }
                                 if ($month != '' && $day != '' && $year != '') {
                                     // special handling for American dates - otherwise, just
                                     // the standard year/month/day (where month is a number)
                                     global $wgAmericanDates;
                                     if ($wgAmericanDates == true) {
                                         $cur_value_in_template = "{$month} {$day}, {$year}";
                                     } else {
                                         $cur_value_in_template = "{$year}/{$month}/{$day}";
                                     }
                                     // include whatever time information we have
                                     if (isset($hour)) {
                                         $cur_value_in_template .= " " . str_pad(intval(substr($hour, 0, 2)), 2, '0', STR_PAD_LEFT) . ":" . str_pad(intval(substr($minute, 0, 2)), 2, '0', STR_PAD_LEFT);
                                     }
                                     if (isset($second)) {
                                         $cur_value_in_template .= ":" . str_pad(intval(substr($second, 0, 2)), 2, '0', STR_PAD_LEFT);
                                     }
                                     if (isset($ampm24h)) {
                                         $cur_value_in_template .= " {$ampm24h}";
                                     }
                                     if (isset($timezone)) {
                                         $cur_value_in_template .= " {$timezone}";
                                     }
                                 } else {
                                     $cur_value_in_template = "";
                                 }
                             }
                         }
                     } else {
                         // value is not an array
                         $cur_value_in_template = $cur_value;
                     }
                     if ($query_template_name == null || $query_template_name == '') {
                         $input_name = $field_name;
                     } elseif ($allow_multiple) {
                         // 'num' will get replaced by an actual index, either in PHP
                         // or in Javascript, later on
                         $input_name = $query_template_name . '[num][' . $field_name . ']';
                     } else {
                         $input_name = $query_template_name . '[' . $field_name . ']';
                     }
                     // disable this field if either the whole form is disabled, or
                     // it's a restricted field and user doesn't have sysop privileges
                     $is_disabled = $form_is_disabled || $is_restricted && (!$wgUser || !$wgUser->isAllowed('editrestrictedfields'));
                     // create an SFFormTemplateField instance based on all the
                     // parameters in the form definition, and any information from
                     // the template definition (contained in the $all_fields parameter)
                     # creation of a form field from the definition page
                     $possible_values['_element'] = "value";
                     $form_field = $this->createFromDefinitionForSerialization($field_name, $input_name, $is_mandatory, $is_hidden, $is_uploadable, $possible_values, $is_disabled, $is_list, $input_type, $field_args, $all_fields, $strict_parsing);
                     // if this is not part of a 'multiple' template, incrememt the
                     // global tab index (used for correct tabbing)
                     if (!$field_args['part_of_multiple']) {
                         $sfgTabIndex++;
                     }
                     // increment the global field number regardless
                     $sfgFieldNum++;
                     // if the field is a date field, and its default value was set
                     // to 'now', and it has no current value, set $cur_value to be
                     // the current date
                     if ($default_value == 'now' && ($cur_value == '' || $cur_value == 'now')) {
                         if ($input_type == 'date' || $input_type == 'datetime' || $input_type == 'datetime with timezone' || $input_type == '' && $form_field->template_field->field_type == 'Date') {
                             $cur_time = time();
                             $year = date("Y", $cur_time);
                             $month = date("n", $cur_time);
                             $day = date("j", $cur_time);
                             global $wgAmericanDates, $sfg24HourTime;
                             if ($wgAmericanDates == true) {
                                 $month_names = SFFormUtils::getMonthNames();
                                 $month_name = $month_names[$month - 1];
                                 $cur_value_in_template = "{$month_name} {$day}, {$year}";
                             } else {
                                 $cur_value_in_template = "{$year}/{$month}/{$day}";
                             }
                             if ($input_type == 'datetime' || $input_type == 'datetime with timezone') {
                                 if ($sfg24HourTime) {
                                     $hour = str_pad(intval(substr(date("G", $cur_time), 0, 2)), 2, '0', STR_PAD_LEFT);
                                 } else {
                                     $hour = str_pad(intval(substr(date("g", $cur_time), 0, 2)), 2, '0', STR_PAD_LEFT);
                                 }
                                 $minute = str_pad(intval(substr(date("i", $cur_time), 0, 2)), 2, '0', STR_PAD_LEFT);
                                 $second = str_pad(intval(substr(date("s", $cur_time), 0, 2)), 2, '0', STR_PAD_LEFT);
                                 if ($sfg24HourTime) {
                                     $cur_value_in_template .= " {$hour}:{$minute}:{$second}";
                                 } else {
                                     $ampm = date("A", $cur_time);
                                     $cur_value_in_template .= " {$hour}:{$minute}:{$second} {$ampm}";
                                 }
                             }
                             if ($input_type == 'datetime with timezone') {
                                 $timezone = date("T", $cur_time);
                                 $cur_value_in_template .= " {$timezone}";
                             }
                         }
                     }
                     // if the field is a text field, and its default value was set
                     // to 'current user', and it has no current value, set $cur_value
                     // to be the current user
                     if ($default_value == 'current user' && ($cur_value == '' || $cur_value == 'current user')) {
                         if ($input_type == 'text' || $input_type == '') {
                             $cur_value_in_template = $wgUser->getName();
                             $cur_value = $cur_value_in_template;
                         }
                     }
                     # field + field value
                     $form_field->cur_value = $cur_value;
                     # possible_values hack
                     $__tmpValues = $form_field->template_field->possible_values;
                     $form_field->template_field->possible_values = array();
                     if ($__tmpValues != NULL) {
                         foreach ($__tmpValues as $key => $value) {
                             $form_field->template_field->possible_values["value" . $key] = $value;
                         }
                     }
                     $field["field" . count($field)] = $this->toArrayForSerialize($form_field);
                     $new_text = "dummy";
                     // set only in order to break
                     if ($new_text) {
                         $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                     } else {
                         $start_position = $brackets_end_loc;
                     }
                 }
             } else {
                 // tag is not one of the three allowed values
                 // ignore tag
                 $start_position = $brackets_end_loc;
             }
             // end if
         }
         // end while
     }
     // end for
     // get free text, and add to page data, as well as retroactively
     // inserting it into the form
     // If $form_is_partial is true then either:
     // (a) we're processing a replacement (param 'partial' == 1)
     // (b) we're sending out something to be replaced (param 'partial' is missing)
     if ($form_is_partial) {
         if (!$wgRequest->getCheck('partial')) {
             $free_text = $original_page_content;
             $form_text .= SFFormUtils::hiddenFieldHTML('partial', 1);
         } else {
             $free_text = null;
             $existing_page_content = preg_replace('/²\\{(.*?)\\}²/s', '{{\\1}}', $existing_page_content);
             $existing_page_content = preg_replace('/\\{\\{\\{insertionpoint\\}\\}\\}/', '', $existing_page_content);
             $existing_page_content = Sanitizer::safeEncodeAttribute($existing_page_content);
         }
     } elseif ($source_is_page) {
         // if the page is the source, free_text will just be whatever in the
         // page hasn't already been inserted into the form
         $free_text = trim($existing_page_content);
         // or get it from a form submission
     } elseif ($wgRequest->getCheck('free_text')) {
         $free_text = $wgRequest->getVal('free_text');
         if (!$free_text_was_included) {
             $data_text .= "<free_text>";
         }
         // or get it from the form definition
     } elseif ($free_text_preload_page != null) {
         $free_text = SFFormUtils::getPreloadedText($free_text_preload_page);
     } else {
         $free_text = null;
     }
     # the free text is set here
     // if the FCKeditor extension is installed, use that for the free text input
     global $wgFCKEditorDir;
     if ($wgFCKEditorDir) {
         $showFCKEditor = SFFormUtils::getShowFCKEditor();
         $free_text = htmlspecialchars($free_text);
         if ($showFCKEditor & RTE_VISIBLE) {
             $free_text = SFFormUtils::prepareTextForFCK($free_text);
         }
     } else {
         $showFCKEditor = 0;
         $free_text = Sanitizer::safeEncodeAttribute($free_text);
     }
     // now that we have it, substitute free text into the form and page
     $form_text = str_replace('<free_text>', $free_text, $form_text);
     $data_text = str_replace('<free_text>', $free_text, $data_text);
     # return the fields
     return $__fields;
 }
Exemple #13
0
 /**
  * Strips a text string of wikitext for use in a section anchor
  *
  * Accepts a text string and then removes all wikitext from the
  * string and leaves only the resultant text (i.e. the result of
  * [[User:WikiSysop|Sysop]] would be "Sysop" and the result of
  * [[User:WikiSysop]] would be "User:WikiSysop") - this is intended
  * to create valid section anchors by mimicing the output of the
  * parser when headings are parsed.
  *
  * @param string $text text string to be stripped of wikitext
  * for use in a Section anchor
  * @return string Filtered text string
  */
 public function stripSectionName($text)
 {
     # Strip internal link markup
     $text = preg_replace('/\\[\\[:?([^[|]+)\\|([^[]+)\\]\\]/', '$2', $text);
     $text = preg_replace('/\\[\\[:?([^[]+)\\|?\\]\\]/', '$1', $text);
     # Strip external link markup
     # @todo FIXME: Not tolerant to blank link text
     # I.E. [https://www.mediawiki.org] will render as [1] or something depending
     # on how many empty links there are on the page - need to figure that out.
     $text = preg_replace('/\\[(?i:' . $this->mUrlProtocols . ')([^ ]+?) ([^[]+)\\]/', '$2', $text);
     # Parse wikitext quotes (italics & bold)
     $text = $this->doQuotes($text);
     # Strip HTML tags
     $text = StringUtils::delimiterReplace('<', '>', '', $text);
     return $text;
 }
 /**
  * Get the fields of the template, along with the semantic property
  * attached to each one (if any), by parsing the text of the template.
  */
 function getAllFields()
 {
     global $wgContLang;
     $templateFields = array();
     $fieldNamesArray = array();
     // The way this works is that fields are found and then stored
     // in an array based on their location in the template text, so
     // that they can be returned in the order in which they appear
     // in the template, not the order in which they were found.
     // Some fields can be found more than once (especially if
     // they're part of an "#if" statement), so they're only
     // recorded the first time they're found.
     $template_title = Title::makeTitleSafe(NS_TEMPLATE, $this->mTemplateName);
     $template_article = null;
     if (isset($template_title)) {
         $template_article = new Article($template_title, 0);
     }
     if (isset($template_article)) {
         $templateText = $template_article->getContent();
         // Ignore 'noinclude' sections and 'includeonly' tags.
         $templateText = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $templateText);
         $templateText = strtr($templateText, array('<includeonly>' => '', '</includeonly>' => ''));
         // First, look for "arraymap" parser function calls
         // that map a property onto a list.
         if ($ret = preg_match_all('/{{#arraymap:{{{([^|}]*:?[^|}]*)[^\\[]*\\[\\[([^:]*:?[^:]*)::/mis', $templateText, $matches)) {
             foreach ($matches[1] as $i => $field_name) {
                 if (!in_array($field_name, $fieldNamesArray)) {
                     $propertyName = $matches[2][$i];
                     $this->handlePropertySettingInTemplate($field_name, $propertyName, true, $templateFields, $templateText);
                     $fieldNamesArray[] = $field_name;
                 }
             }
         } elseif ($ret === false) {
             // There was an error in the preg_match_all()
             // call - let the user know about it.
             if (preg_last_error() == PREG_BACKTRACK_LIMIT_ERROR) {
                 print 'Semantic Forms error: backtrace limit exceeded during parsing! Please increase the value of <a href="http://www.php.net/manual/en/pcre.configuration.php#ini.pcre.backtrack-limit">pcre.backtrack-limit</a> in the PHP settings.';
             }
         }
         // Second, look for normal property calls.
         if (preg_match_all('/\\[\\[([^:|\\[\\]]*:*?[^:|\\[\\]]*)::{{{([^\\]\\|}]*).*?\\]\\]/mis', $templateText, $matches)) {
             foreach ($matches[1] as $i => $propertyName) {
                 $field_name = trim($matches[2][$i]);
                 if (!in_array($field_name, $fieldNamesArray)) {
                     $propertyName = trim($propertyName);
                     $this->handlePropertySettingInTemplate($field_name, $propertyName, false, $templateFields, $templateText);
                     $fieldNamesArray[] = $field_name;
                 }
             }
         }
         // Then, get calls to #set and #set_internal
         // (thankfully, they have basically the same syntax).
         if (preg_match_all('/#(set|set_internal):(.*?}}})\\s*}}/mis', $templateText, $matches)) {
             foreach ($matches[2] as $match) {
                 if (preg_match_all('/([^|{]*?)=\\s*{{{([^|}]*)/mis', $match, $matches2)) {
                     foreach ($matches2[1] as $i => $propertyName) {
                         $fieldName = trim($matches2[2][$i]);
                         if (!in_array($fieldName, $fieldNamesArray)) {
                             $propertyName = trim($propertyName);
                             $this->handlePropertySettingInTemplate($fieldName, $propertyName, false, $templateFields, $templateText);
                             $fieldNamesArray[] = $fieldName;
                         }
                     }
                 }
             }
         }
         // Then, get calls to #declare.
         if (preg_match_all('/#declare:(.*?)}}/mis', $templateText, $matches)) {
             foreach ($matches[1] as $match) {
                 $setValues = explode('|', $match);
                 foreach ($setValues as $valuePair) {
                     $keyAndVal = explode('=', $valuePair);
                     if (count($keyAndVal) == 2) {
                         $propertyName = trim($keyAndVal[0]);
                         $fieldName = trim($keyAndVal[1]);
                         if (!in_array($fieldName, $fieldNamesArray)) {
                             $this->handlePropertySettingInTemplate($fieldName, $propertyName, false, $templateFields, $templateText);
                             $fieldNamesArray[] = $fieldName;
                         }
                     }
                 }
             }
         }
         // Finally, get any non-semantic fields defined.
         if (preg_match_all('/{{{([^|}]*)/mis', $templateText, $matches)) {
             foreach ($matches[1] as $fieldName) {
                 $fieldName = trim($fieldName);
                 if (!empty($fieldName) && !in_array($fieldName, $fieldNamesArray)) {
                     $cur_pos = stripos($templateText, $fieldName);
                     $templateFields[$cur_pos] = SFTemplateField::create($fieldName, $wgContLang->ucfirst($fieldName));
                     $fieldNamesArray[] = $fieldName;
                 }
             }
         }
     }
     ksort($templateFields);
     return $templateFields;
 }
 function compute($vars)
 {
     $parameters = $this->mParameters;
     $result = null;
     switch ($this->mMethod) {
         case 'diff':
             $text1Var = $parameters['oldtext-var'];
             $text2Var = $parameters['newtext-var'];
             $text1 = $vars->getVar($text1Var)->toString();
             $text2 = $vars->getVar($text2Var)->toString();
             $result = wfDiff($text1, $text2);
             $result = trim(preg_replace("/^\\\\ No newline at end of file\n/m", '', $result));
             break;
         case 'diff-split':
             $diff = $vars->getVar($parameters['diff-var'])->toString();
             $line_prefix = $parameters['line-prefix'];
             $diff_lines = explode("\n", $diff);
             $interest_lines = array();
             foreach ($diff_lines as $line) {
                 if (substr($line, 0, 1) === $line_prefix) {
                     $interest_lines[] = substr($line, strlen($line_prefix));
                 }
             }
             $result = $interest_lines;
             break;
         case 'links-from-wikitext':
             // This should ONLY be used when sharing a parse operation with the edit.
             $article = $parameters['article'];
             if ($article) {
                 $textVar = $parameters['text-var'];
                 $new_text = $vars->getVar($textVar)->toString();
                 $editInfo = $article->prepareTextForEdit($new_text);
                 $links = array_keys($editInfo->output->getExternalLinks());
                 $result = $links;
                 break;
             }
             // Otherwise fall back to database
         // Otherwise fall back to database
         case 'links-from-wikitext-nonedit':
         case 'links-from-wikitext-or-database':
             $article = self::articleFromTitle($parameters['namespace'], $parameters['title']);
             if ($vars->getVar('context')->toString() == 'filter') {
                 $links = $this->getLinksFromDB($article);
                 wfDebug("AbuseFilter: loading old links from DB\n");
             } else {
                 wfDebug("AbuseFilter: loading old links from Parser\n");
                 $textVar = $parameters['text-var'];
                 $wikitext = $vars->getVar($textVar)->toString();
                 $editInfo = $this->parseNonEditWikitext($wikitext, $article);
                 $links = array_keys($editInfo->output->getExternalLinks());
             }
             $result = $links;
             break;
         case 'link-diff-added':
         case 'link-diff-removed':
             $oldLinkVar = $parameters['oldlink-var'];
             $newLinkVar = $parameters['newlink-var'];
             $oldLinks = $vars->getVar($oldLinkVar)->toString();
             $newLinks = $vars->getVar($newLinkVar)->toString();
             $oldLinks = explode("\n", $oldLinks);
             $newLinks = explode("\n", $newLinks);
             if ($this->mMethod == 'link-diff-added') {
                 $result = array_diff($newLinks, $oldLinks);
             }
             if ($this->mMethod == 'link-diff-removed') {
                 $result = array_diff($oldLinks, $newLinks);
             }
             break;
         case 'parse-wikitext':
             // Should ONLY be used when sharing a parse operation with the edit.
             $article = $parameters['article'];
             if ($article) {
                 $textVar = $parameters['wikitext-var'];
                 $new_text = $vars->getVar($textVar)->toString();
                 $editInfo = $article->prepareTextForEdit($new_text);
                 $newHTML = $editInfo->output->getText();
                 // Kill the PP limit comments. Ideally we'd just remove these by not setting the
                 // parser option, but then we can't share a parse operation with the edit, which is bad.
                 $result = preg_replace('/<!--\\s*NewPP limit report[^>]*-->\\s*$/si', '', $newHTML);
                 break;
             }
             // Otherwise fall back to database
         // Otherwise fall back to database
         case 'parse-wikitext-nonedit':
             $article = self::articleFromTitle($parameters['namespace'], $parameters['title']);
             $textVar = $parameters['wikitext-var'];
             $text = $vars->getVar($textVar)->toString();
             $editInfo = $this->parseNonEditWikitext($text, $article);
             $result = $editInfo->output->getText();
             break;
         case 'strip-html':
             $htmlVar = $parameters['html-var'];
             $html = $vars->getVar($htmlVar)->toString();
             $result = StringUtils::delimiterReplace('<', '>', '', $html);
             break;
         case 'load-recent-authors':
             $cutOff = $parameters['cutoff'];
             $title = Title::makeTitle($parameters['namespace'], $parameters['title']);
             if (!$title->exists()) {
                 $result = '';
                 break;
             }
             $dbr = wfGetDB(DB_SLAVE);
             $res = $dbr->select('revision', 'DISTINCT rev_user_text', array('rev_page' => $title->getArticleId(), 'rev_timestamp<' . $dbr->addQuotes($dbr->timestamp($cutOff))), __METHOD__, array('ORDER BY' => 'rev_timestamp DESC', 'LIMIT' => 10));
             $users = array();
             foreach ($res as $row) {
                 $users[] = $row->rev_user_text;
             }
             $result = $users;
             break;
         case 'get-page-restrictions':
             $action = $parameters['action'];
             $title = Title::makeTitle($parameters['namespace'], $parameters['title']);
             $rights = $title->getRestrictions($action);
             $rights = count($rights) ? $rights : array();
             $result = $rights;
             break;
         case 'simple-user-accessor':
             $user = $parameters['user'];
             $method = $parameters['method'];
             if (!$user) {
                 throw new MWException('No user parameter given.');
             }
             $obj = self::userObjectFromName($user);
             if (!$obj) {
                 throw new MWException("Invalid username {$user}");
             }
             $result = call_user_func(array($obj, $method));
             break;
         case 'user-age':
             $user = $parameters['user'];
             $asOf = $parameters['asof'];
             $obj = self::userObjectFromName($user);
             if ($obj->getId() == 0) {
                 $result = 0;
                 break;
             }
             $registration = $obj->getRegistration();
             $result = wfTimestamp(TS_UNIX, $asOf) - wfTimestampOrNull(TS_UNIX, $registration);
             break;
         case 'user-groups':
             $user = $parameters['user'];
             $obj = self::userObjectFromName($user);
             $result = $obj->getEffectiveGroups();
             break;
         case 'length':
             $s = $vars->getVar($parameters['length-var'])->toString();
             $result = strlen($s);
             break;
         case 'subtract':
             $v1 = $vars->getVar($parameters['val1-var'])->toFloat();
             $v2 = $vars->getVar($parameters['val2-var'])->toFloat();
             $result = $v1 - $v2;
             break;
         case 'revision-text-by-id':
             $rev = Revision::newFromId($parameters['revid']);
             $result = $rev->getText();
             break;
         case 'revision-text-by-timestamp':
             $timestamp = $parameters['timestamp'];
             $title = Title::makeTitle($parameters['namespace'], $parameters['title']);
             $dbr = wfGetDB(DB_SLAVE);
             $rev = Revision::loadFromTimestamp($dbr, $title, $timestamp);
             if ($rev) {
                 $result = $rev->getText();
             } else {
                 $result = '';
             }
             break;
         default:
             if (wfRunHooks('AbuseFilter-computeVariable', array($this->mMethod, $vars))) {
                 throw new AFPException('Unknown variable compute type ' . $this->mMethod);
             }
     }
     return $result instanceof AFPData ? $result : AFPData::newFromPHPVar($result);
 }
 /**
  * Depending on the requested action this method will try to store/preview
  * the data in mOptions or retrieve the edit form.
  *
  * The form and target page will be available in mOptions after execution of
  * the method.
  *
  * Errors and warnings are logged in the API result under the 'errors' key.
  * The general request status is maintained in mStatus.
  *
  * @global $wgRequest
  * @global $wgOut
  * @global SFFormPrinter $sfgFormPrinter
  * @throws MWException
  */
 public function doAction()
 {
     global $wgOut, $wgParser, $wgRequest, $sfgFormPrinter;
     // if the wiki is read-only, do not save
     if (wfReadOnly()) {
         if ($this->mAction === self::ACTION_SAVE) {
             throw new MWException(wfMessage('sf_autoedit_readonly', wfReadOnlyReason())->parse());
         }
         // even if not saving notify client anyway. Might want to dislay a notice
         $this->logMessage(wfMessage('sf_autoedit_readonly', wfReadOnlyReason())->parse(), self::NOTICE);
     }
     // find the title of the form to be used
     $formTitle = $this->getFormTitle();
     // get the form content
     $formContent = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $this->getTextForPage($formTitle));
     // signals that the form was submitted
     // always true, else we would not be here
     $isFormSubmitted = $this->mAction === self::ACTION_SAVE || $this->mAction === self::ACTION_PREVIEW || $this->mAction === self::ACTION_DIFF;
     // the article id of the form to be used
     $formArticleId = $formTitle->getArticleID();
     // the name of the target page; might be empty when using the one-step-process
     $targetName = $this->mOptions['target'];
     // if the target page was not specified, try finding the page name formula
     // (Why is this not done in SFFormPrinter::formHTML?)
     if ($targetName === '') {
         // Parse the form to see if it has a 'page name' value set.
         if (preg_match('/{{{\\s*info.*page name\\s*=\\s*(.*)}}}/msU', $formContent, $matches)) {
             $pageNameElements = SFUtils::getFormTagComponents(trim($matches[1]));
             $targetNameFormula = $pageNameElements[0];
         } else {
             throw new MWException(wfMessage('sf_autoedit_notargetspecified')->parse());
         }
         $targetTitle = null;
     } else {
         $targetNameFormula = null;
         $targetTitle = Title::newFromText($targetName);
     }
     $preloadContent = '';
     // save $wgRequest for later restoration
     $oldRequest = $wgRequest;
     $pageExists = false;
     // preload data if not explicitly excluded and if the preload page exists
     if (!isset($this->mOptions['preload']) || $this->mOptions['preload'] !== false) {
         if (isset($this->mOptions['preload']) && is_string($this->mOptions['preload'])) {
             $preloadTitle = Title::newFromText($this->mOptions['preload']);
         } else {
             $preloadTitle = Title::newFromText($targetName);
         }
         if ($preloadTitle !== null && $preloadTitle->exists()) {
             // the content of the page that was specified to be used for preloading
             $preloadContent = $this->getTextForPage($preloadTitle);
             $pageExists = true;
         } else {
             if (isset($this->mOptions['preload'])) {
                 $this->logMessage(wfMessage('sf_autoedit_invalidpreloadspecified', $this->mOptions['preload'])->parse(), self::WARNING);
             }
         }
     }
     // Allow extensions to set/change the preload text, for new
     // pages.
     if (!$pageExists) {
         Hooks::run('sfEditFormPreloadText', array(&$preloadContent, $targetTitle, $formTitle));
     }
     // Flag to keep track of formHTML() runs.
     $formHtmlHasRun = false;
     if ($preloadContent !== '') {
         // @HACK - we need to set this for the preload to take
         // effect in the form.
         $pageExists = true;
         // Spoof $wgRequest for SFFormPrinter::formHTML().
         if (isset($_SESSION)) {
             $wgRequest = new FauxRequest($this->mOptions, true, $_SESSION);
         } else {
             $wgRequest = new FauxRequest($this->mOptions, true);
         }
         // Call SFFormPrinter::formHTML() to get at the form
         // HTML of the existing page.
         list($formHTML, $formJS, $targetContent, $form_page_title, $generatedTargetNameFormula) = $sfgFormPrinter->formHTML($formContent, $isFormSubmitted, $pageExists, $formArticleId, $preloadContent, $targetName, $targetNameFormula);
         // Parse the data to be preloaded from the form HTML of
         // the existing page.
         $data = $this->parseDataFromHTMLFrag($formHTML);
         // ...and merge/overwrite it with the new data.
         $this->mOptions = SFUtils::array_merge_recursive_distinct($data, $this->mOptions);
     }
     // We already preloaded stuff for saving/previewing -
     // do not do this again.
     if ($isFormSubmitted && !$wgRequest->getCheck('partial')) {
         $preloadContent = '';
         $pageExists = false;
     } else {
         // Source of the data is a page.
         $pageExists = is_a($targetTitle, 'Title') && $targetTitle->exists();
     }
     // Spoof $wgRequest for SFFormPrinter::formHTML().
     if (isset($_SESSION)) {
         $wgRequest = new FauxRequest($this->mOptions, true, $_SESSION);
     } else {
         $wgRequest = new FauxRequest($this->mOptions, true);
     }
     // get wikitext for submitted data and form
     list($formHTML, $formJS, $targetContent, $generatedFormName, $generatedTargetNameFormula) = $sfgFormPrinter->formHTML($formContent, $isFormSubmitted, $pageExists, $formArticleId, $preloadContent, $targetName, $targetNameFormula);
     // Restore original request.
     $wgRequest = $oldRequest;
     if ($generatedFormName !== '') {
         $formTitle = Title::newFromText($generatedFormName);
         $this->mOptions['formtitle'] = $formTitle->getText();
     }
     $this->mOptions['formHTML'] = $formHTML;
     $this->mOptions['formJS'] = $formJS;
     if ($isFormSubmitted) {
         // If the target page was not specified, see if
         // something was generated from the target name formula.
         if ($this->mOptions['target'] === '') {
             // If no name was generated, we cannot save => give up
             if ($generatedTargetNameFormula === '') {
                 throw new MWException(wfMessage('sf_autoedit_notargetspecified')->parse());
             }
             $this->mOptions['target'] = $this->generateTargetName($generatedTargetNameFormula);
         }
         // Lets other code process additional form-definition syntax
         Hooks::run('sfWritePageData', array($this->mOptions['form'], Title::newFromText($this->mOptions['target']), &$targetContent));
         $editor = $this->setupEditPage($targetContent);
         // Perform the requested action.
         if ($this->mAction === self::ACTION_PREVIEW) {
             $this->doPreview($editor);
         } else {
             if ($this->mAction === self::ACTION_DIFF) {
                 $this->doDiff($editor);
             } else {
                 $this->doStore($editor);
             }
         }
     } else {
         if ($this->mAction === self::ACTION_FORMEDIT) {
             $parserOutput = $wgParser->getOutput();
             if (method_exists($wgOut, 'addParserOutputMetadata')) {
                 $wgOut->addParserOutputMetadata($parserOutput);
             } else {
                 $wgOut->addParserOutputNoText($parserOutput);
             }
             $this->doFormEdit($formHTML, $formJS);
         }
     }
 }
 /**
  * Parse the form definition and return it
  */
 public static function getFormDefinition(Parser $parser, $form_def = null, $form_id = null)
 {
     if ($form_id !== null) {
         $cachedDef = self::getFormDefinitionFromCache($form_id, $parser);
         if ($cachedDef !== null) {
             return $cachedDef;
         }
     }
     if ($form_id !== null) {
         $form_title = Title::newFromID($form_id);
         $form_def = SFUtils::getPageText($form_title);
     } elseif ($form_def == null) {
         // No id, no text -> nothing to do
         return '';
     }
     // Remove <noinclude> sections and <includeonly> tags from form definition
     $form_def = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $form_def);
     $form_def = strtr($form_def, array('<includeonly>' => '', '</includeonly>' => ''));
     // We need to replace all SF tags in the form definition by strip items. But we can not just use
     // the Parser strip state because the Parser would during parsing replace all strip items and then
     // mangle them into HTML code. So we have to use our own. Which means we also can not just use
     // Parser::insertStripItem() (see below).
     $rnd = wfRandomString(32);
     // This regexp will find any SF triple braced tags (including correct handling of contained braces), i.e.
     // {{{field|foo|default={{Bar}}}}} is not a problem. When used with preg_match and friends, $matches[0] will
     // contain the whole SF tag, $matches[1] will contain the tag without the enclosing triple braces.
     $regexp = '#\\{\\{\\{((?>[^\\{\\}]+)|(\\{((?>[^\\{\\}]+)|(?-2))*\\}))*\\}\\}\\}#';
     $items = array();
     // replace all SF tags by strip markers
     $form_def = preg_replace_callback($regexp, function (array $matches) use(&$items, $rnd) {
         $markerIndex = count($items);
         $items[] = $matches[0];
         return "{$rnd}-item-{$markerIndex}-{$rnd}";
     }, $form_def);
     // parse wiki-text
     if (isset($parser->mInParse) && $parser->mInParse === true) {
         $form_def = $parser->recursiveTagParse($form_def);
         $output = $parser->getOutput();
     } else {
         $title = is_object($parser->getTitle()) ? $parser->getTitle() : new Title();
         $output = $parser->parse($form_def, $title, $parser->getOptions());
         $form_def = $output->getText();
     }
     $form_def = preg_replace_callback("/{$rnd}-item-(\\d+)-{$rnd}/", function (array $matches) use($items) {
         $markerIndex = (int) $matches[1];
         return $items[$markerIndex];
     }, $form_def);
     if ($output->getCacheTime() == -1) {
         $form_article = Article::newFromID($form_id);
         self::purgeCache($form_article);
         wfDebug("Caching disabled for form definition {$form_id}\n");
     } elseif ($form_id !== null) {
         self::cacheFormDefinition($form_id, $form_def, $parser);
     }
     return $form_def;
 }
Exemple #18
0
 /**
  * Take a fragment of (potentially invalid) HTML and return
  * a version with any tags removed, encoded suitably for literal
  * inclusion in an attribute value.
  *
  * @param string $text HTML fragment
  * @return string
  */
 static function stripAllTags($text)
 {
     # Actual <tags>
     $text = StringUtils::delimiterReplace('<', '>', '', $text);
     # Normalize &entities and whitespace
     $text = Sanitizer::normalizeAttributeValue($text);
     # Will be placed into "double-quoted" attributes,
     # make sure remaining bits are safe.
     $text = str_replace(array('<', '>', '"'), array('&lt;', '&gt;', '&quot;'), $text);
     return $text;
 }
function wiki_get_template($widgetName, &$widgetCode, &$smarty_obj)
{
    $widgetTitle = Title::newFromText($widgetName, NS_WIDGET);
    if ($widgetTitle && $widgetTitle->exists()) {
        $widgetArticle = new Article($widgetTitle);
        $widgetCode = $widgetArticle->getContent();
        // Remove <noinclude> sections and <includeonly> tags from form definition
        $widgetCode = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $widgetCode);
        $widgetCode = strtr($widgetCode, array('<includeonly>' => '', '</includeonly>' => ''));
        return true;
    } else {
        return false;
    }
}
Exemple #20
0
 static function printForm(&$form_name, &$target_name, $alt_forms = array(), $redirectOnError = false)
 {
     global $wgOut, $wgRequest, $wgUser, $sfgFormPrinter;
     // initialize some variables
     $target_title = null;
     $page_name_formula = null;
     $form_title = Title::makeTitleSafe(SF_NS_FORM, $form_name);
     // If the given form is not a valid title, bail out.
     if (!$form_title) {
         return 'sf_formedit_badurl';
     }
     $form_article = new Article($form_title, 0);
     $form_definition = $form_article->getContent();
     // If the form page is a redirect, use the other form
     // instead.
     if ($form_title->isRedirect()) {
         $form_title = Title::newFromRedirectRecurse($form_definition);
         $form_article = new Article($form_title, 0);
         $form_definition = $form_article->getContent();
     }
     $form_definition = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $form_definition);
     if (is_null($target_name)) {
         $target_name = '';
     }
     if ($target_name === '') {
         // parse the form to see if it has a 'page name' value set
         $matches;
         if (preg_match('/{{{info.*page name\\s*=\\s*(.*)}}}/m', $form_definition, $matches)) {
             $page_name_elements = SFUtils::getFormTagComponents($matches[1]);
             $page_name_formula = $page_name_elements[0];
         } elseif (count($alt_forms) == 0) {
             return 'sf_formedit_badurl';
         }
     } else {
         $target_title = Title::newFromText($target_name);
         if ($target_title && $target_title->exists()) {
             if ($wgRequest->getVal('query') == 'true') {
                 $page_contents = null;
                 //$page_is_source = false;
             } else {
                 // If page already exists and 'redlink'
                 // is in the query string, redirect to
                 // the actual page, just like
                 // MediaWiki does it.
                 if ($wgRequest->getBool('redlink')) {
                     $wgOut->redirect($target_title->getFullURL());
                     wfProfileOut(__METHOD__);
                     return;
                 }
                 $target_article = new Article($target_title, 0);
                 $page_contents = $target_article->getContent();
                 //$page_is_source = true;
             }
         } else {
             $target_name = str_replace('_', ' ', $target_name);
         }
     }
     if (!$form_title || !$form_title->exists()) {
         if (count($alt_forms) > 0) {
             $text = '<div class="infoMessage">' . wfMsg('sf_formedit_altformsonly') . ' ' . self::printAltFormsList($alt_forms, $form_name) . "</div>\n";
         } else {
             $text = Html::rawElement('p', array('class' => 'error'), wfMsgExt('sf_formstart_badform', 'parseinline', SFUtils::linkText(SF_NS_FORM, $form_name))) . "\n";
         }
     } elseif ($target_name === '' && $page_name_formula === '') {
         $text = Html::element('p', array('class' => 'error'), wfMsg('sf_formedit_badurl')) . "\n";
     } else {
         $save_page = $wgRequest->getCheck('wpSave');
         $preview_page = $wgRequest->getCheck('wpPreview');
         $diff_page = $wgRequest->getCheck('wpDiff');
         $form_submitted = $save_page || $preview_page || $diff_page;
         // get 'preload' query value, if it exists
         if (!$form_submitted) {
             if ($wgRequest->getCheck('preload')) {
                 $page_is_source = true;
                 $page_contents = SFFormUtils::getPreloadedText($wgRequest->getVal('preload'));
             } else {
                 // let other extensions preload the page, if they want
                 wfRunHooks('sfEditFormPreloadText', array(&$page_contents, $target_title, $form_title));
                 $page_is_source = $page_contents != null;
             }
         } else {
             $page_is_source = false;
             $page_contents = null;
         }
         list($form_text, $javascript_text, $data_text, $form_page_title, $generated_page_name) = $sfgFormPrinter->formHTML($form_definition, $form_submitted, $page_is_source, $form_article->getID(), $page_contents, $target_name, $page_name_formula);
         // Before we do anything else, set the form header
         // title - this needs to be done after formHTML() is
         // called, because otherwise it doesn't take hold
         // for some reason if the form is disabled.
         if (empty($target_title)) {
             $s = wfMsg('sf_formedit_createtitlenotarget', $form_title->getText());
         } elseif ($target_title->exists()) {
             $s = wfMsg('sf_formedit_edittitle', $form_title->getText(), $target_title->getPrefixedText());
         } else {
             $s = wfMsg('sf_formedit_createtitle', $form_title->getText(), $target_title->getPrefixedText());
         }
         $wgOut->setPageTitle($s);
         if ($form_submitted) {
             if (!is_null($page_name_formula) && $page_name_formula !== '') {
                 $target_name = $generated_page_name;
                 // prepend a super-page, if one was specified
                 if ($wgRequest->getCheck('super_page')) {
                     $target_name = $wgRequest->getVal('super_page') . '/' . $target_name;
                 }
                 // prepend a namespace, if one was specified
                 if ($wgRequest->getCheck('namespace')) {
                     $target_name = $wgRequest->getVal('namespace') . ':' . $target_name;
                 }
                 // replace "unique number" tag with one
                 // that won't get erased by the next line
                 $target_name = preg_replace('/<unique number(.*)>/', '{num\\1}', $target_name, 1);
                 // if any formula stuff is still in the
                 // name after the parsing, just remove it
                 $target_name = StringUtils::delimiterReplace('<', '>', '', $target_name);
                 // now run the parser on it
                 global $wgParser;
                 // ...but first, replace spaces back
                 // with underlines, in case a magic word
                 // or parser function name contains
                 // underlines - hopefully this won't
                 // cause problems of its own
                 $target_name = str_replace(' ', '_', $target_name);
                 $target_name = $wgParser->preprocess($target_name, $wgOut->getTitle(), ParserOptions::newFromUser(null));
                 $title_number = "";
                 $isRandom = false;
                 $randomNumHasPadding = false;
                 $randomNumDigits = 6;
                 if (strpos($target_name, '{num') !== false) {
                     // Random number
                     if (preg_match('/{num;random(;(0)?([1-9][0-9]*))?}/', $target_name, $matches)) {
                         $isRandom = true;
                         $randomNumHasPadding = array_key_exists(2, $matches);
                         $randomNumDigits = array_key_exists(3, $matches) ? $matches[3] : $randomNumDigits;
                         $title_number = self::makeRandomNumber($randomNumDigits, $randomNumHasPadding);
                     } else {
                         // get unique number start value
                         // from target name; if it's not
                         // there, or it's not a positive
                         // number, start it out as blank
                         preg_match('/{num.*start[_]*=[_]*([^;]*).*}/', $target_name, $matches);
                         if (count($matches) == 2 && is_numeric($matches[1]) && $matches[1] >= 0) {
                             // the "start" value"
                             $title_number = $matches[1];
                         }
                     }
                     // set target title
                     $target_title = Title::newFromText(preg_replace('/{num.*}/', $title_number, $target_name));
                     // if title exists already
                     // cycle through numbers for
                     // this tag until we find one
                     // that gives a nonexistent page
                     // title
                     while ($target_title->exists()) {
                         if ($isRandom) {
                             $title_number = self::makeRandomNumber($randomNumDigits, $randomNumHasPadding);
                         } elseif ($title_number == "") {
                             $title_number = 2;
                         } else {
                             $title_number = str_pad($title_number + 1, strlen($title_number), '0', STR_PAD_LEFT);
                         }
                         $target_title = Title::newFromText(preg_replace('/{num.*}/', $title_number, $target_name));
                     }
                     $target_name = $target_title->getPrefixedText();
                 } else {
                     $target_title = Title::newFromText($target_name);
                 }
             }
             if (is_null($target_title)) {
                 if ($target_name) {
                     return array('sf_formstart_badtitle', array($target_name));
                 } else {
                     return 'sf_formedit_emptytitle';
                 }
             }
             if ($save_page) {
                 $permErrors = $target_title->getUserPermissionsErrors('edit', $wgUser);
                 if ($permErrors) {
                     // just return the first error and let them fix it one by one
                     return array_shift($permErrors);
                 }
                 // Set up all the variables for the
                 // page save.
                 $data = array('wpTextbox1' => $data_text, 'wpSummary' => $wgRequest->getVal('wpSummary'), 'wpStarttime' => $wgRequest->getVal('wpStarttime'), 'wpEdittime' => $wgRequest->getVal('wpEdittime'), 'wpEditToken' => $wgUser->isLoggedIn() ? $wgUser->editToken() : EDIT_TOKEN_SUFFIX, 'wpSave' => '', 'action' => 'submit');
                 if ($wgRequest->getCheck('wpMinoredit')) {
                     $data['wpMinoredit'] = true;
                 }
                 if ($wgRequest->getCheck('wpWatchthis')) {
                     $data['wpWatchthis'] = true;
                 }
                 $request = new FauxRequest($data, true);
                 // Find existing article if it exists,
                 // or create a new one.
                 $article = new Article($target_title, 0);
                 $editor = new EditPage($article);
                 $editor->importFormData($request);
                 // Try to save the page!
                 $resultDetails = array();
                 $saveResult = $editor->internalAttemptSave($resultDetails);
                 // Return value was made an object in MW 1.19
                 if (is_object($saveResult)) {
                     $saveResultCode = $saveResult->value;
                 } else {
                     $saveResultCode = $saveResult;
                 }
                 if (($saveResultCode == EditPage::AS_HOOK_ERROR || $saveResultCode == EditPage::AS_HOOK_ERROR_EXPECTED) && $redirectOnError) {
                     $wgOut->clearHTML();
                     $wgOut->setArticleBodyOnly(true);
                     // Lets other code process additional form-definition syntax
                     wfRunHooks('sfWritePageData', array($form_name, $target_title, &$data_text));
                     $text = SFUtils::printRedirectForm($target_title, $data_text, $wgRequest->getVal('wpSummary'), $save_page, $preview_page, $diff_page, $wgRequest->getCheck('wpMinoredit'), $wgRequest->getCheck('wpWatchthis'), $wgRequest->getVal('wpStarttime'), $wgRequest->getVal('wpEdittime'));
                 } else {
                     if ($saveResultCode == EditPage::AS_SUCCESS_UPDATE || $saveResultCode == EditPage::AS_SUCCESS_NEW_ARTICLE) {
                         $wgOut->redirect($target_title->getFullURL());
                     }
                     return SFUtils::processEditErrors($saveResultCode);
                 }
             } else {
                 // Lets other code process additional form-definition syntax
                 wfRunHooks('sfWritePageData', array($form_name, $target_title, &$data_text));
                 $text = SFUtils::printRedirectForm($target_title, $data_text, $wgRequest->getVal('wpSummary'), $save_page, $preview_page, $diff_page, $wgRequest->getCheck('wpMinoredit'), $wgRequest->getCheck('wpWatchthis'), $wgRequest->getVal('wpStarttime'), $wgRequest->getVal('wpEdittime'));
                 // extract its data
             }
         } else {
             // override the default title for this page if
             // a title was specified in the form
             if ($form_page_title != null) {
                 if ($target_name === '') {
                     $wgOut->setPageTitle($form_page_title);
                 } else {
                     $wgOut->setPageTitle("{$form_page_title}: {$target_title->getPrefixedText()}");
                 }
             }
             $text = "";
             if (count($alt_forms) > 0) {
                 $text .= '<div class="infoMessage">' . wfMsg('sf_formedit_altforms') . ' ';
                 $text .= self::printAltFormsList($alt_forms, $target_name);
                 $text .= "</div>\n";
             }
             $text .= '<form name="createbox" id="sfForm" method="post" class="createbox">';
             $pre_form_html = '';
             wfRunHooks('sfHTMLBeforeForm', array(&$target_title, &$pre_form_html));
             $text .= $pre_form_html;
             $text .= $form_text;
         }
     }
     SFUtils::addJavascriptAndCSS();
     if (!empty($javascript_text)) {
         $wgOut->addScript('		<script type="text/javascript">' . "\n{$javascript_text}\n" . '</script>' . "\n");
     }
     $wgOut->addHTML($text);
     return null;
 }
 /**
  * @param $vars AbuseFilterVariableHolder
  * @return AFPData|array|int|mixed|null|string
  * @throws MWException
  * @throws AFPException
  */
 function compute($vars)
 {
     $parameters = $this->mParameters;
     $result = null;
     if (!wfRunHooks('AbuseFilter-interceptVariable', array($this->mMethod, $vars, $parameters, &$result))) {
         return $result instanceof AFPData ? $result : AFPData::newFromPHPVar($result);
     }
     switch ($this->mMethod) {
         case 'diff':
             $text1Var = $parameters['oldtext-var'];
             $text2Var = $parameters['newtext-var'];
             $text1 = $vars->getVar($text1Var)->toString() . "\n";
             $text2 = $vars->getVar($text2Var)->toString() . "\n";
             $result = wfDiff($text1, $text2);
             break;
         case 'diff-split':
             $diff = $vars->getVar($parameters['diff-var'])->toString();
             $line_prefix = $parameters['line-prefix'];
             $diff_lines = explode("\n", $diff);
             $interest_lines = array();
             foreach ($diff_lines as $line) {
                 if (substr($line, 0, 1) === $line_prefix) {
                     $interest_lines[] = substr($line, strlen($line_prefix));
                 }
             }
             $result = $interest_lines;
             break;
         case 'links-from-wikitext':
             // This should ONLY be used when sharing a parse operation with the edit.
             /* @var WikiPage $article */
             $article = $parameters['article'];
             if ($article !== null && (!defined('MW_SUPPORTS_CONTENTHANDLER') || $article->getContentModel() === CONTENT_MODEL_WIKITEXT)) {
                 $textVar = $parameters['text-var'];
                 // XXX: Use prepareContentForEdit. But we need a Content object for that.
                 $new_text = $vars->getVar($textVar)->toString();
                 $content = ContentHandler::makeContent($new_text, $article->getTitle());
                 $editInfo = $article->prepareContentForEdit($content);
                 $links = array_keys($editInfo->output->getExternalLinks());
                 $result = $links;
                 break;
             }
             // Otherwise fall back to database
         // Otherwise fall back to database
         case 'links-from-wikitext-nonedit':
         case 'links-from-wikitext-or-database':
             // TODO: use Content object instead, if available! In any case, use WikiPage, not Article.
             $article = self::articleFromTitle($parameters['namespace'], $parameters['title']);
             if ($vars->getVar('context')->toString() == 'filter') {
                 $links = $this->getLinksFromDB($article);
                 wfDebug("AbuseFilter: loading old links from DB\n");
             } elseif (!defined('MW_SUPPORTS_CONTENTHANDLER') || $article->getContentModel() === CONTENT_MODEL_WIKITEXT) {
                 wfDebug("AbuseFilter: loading old links from Parser\n");
                 $textVar = $parameters['text-var'];
                 $wikitext = $vars->getVar($textVar)->toString();
                 $editInfo = $this->parseNonEditWikitext($wikitext, $article);
                 $links = array_keys($editInfo->output->getExternalLinks());
             } else {
                 // TODO: Get links from Content object. But we don't have the content object.
                 //      And for non-text content, $wikitext is usually not going to be a valid
                 //      serialization, but rather some dummy text for filtering.
                 $links = array();
             }
             $result = $links;
             break;
         case 'link-diff-added':
         case 'link-diff-removed':
             $oldLinkVar = $parameters['oldlink-var'];
             $newLinkVar = $parameters['newlink-var'];
             $oldLinks = $vars->getVar($oldLinkVar)->toString();
             $newLinks = $vars->getVar($newLinkVar)->toString();
             $oldLinks = explode("\n", $oldLinks);
             $newLinks = explode("\n", $newLinks);
             if ($this->mMethod == 'link-diff-added') {
                 $result = array_diff($newLinks, $oldLinks);
             }
             if ($this->mMethod == 'link-diff-removed') {
                 $result = array_diff($oldLinks, $newLinks);
             }
             break;
         case 'parse-wikitext':
             // Should ONLY be used when sharing a parse operation with the edit.
             $article = $parameters['article'];
             if ($article !== null && (!defined('MW_SUPPORTS_CONTENTHANDLER') || $article->getContentModel() === CONTENT_MODEL_WIKITEXT)) {
                 $textVar = $parameters['wikitext-var'];
                 // XXX: Use prepareContentForEdit. But we need a Content object for that.
                 $new_text = $vars->getVar($textVar)->toString();
                 $editInfo = $article->prepareTextForEdit($new_text);
                 if (isset($parameters['pst']) && $parameters['pst']) {
                     $result = $editInfo->pstContent->serialize($editInfo->format);
                 } else {
                     $newHTML = $editInfo->output->getText();
                     // Kill the PP limit comments. Ideally we'd just remove these by not setting the
                     // parser option, but then we can't share a parse operation with the edit, which is bad.
                     $result = preg_replace('/<!--\\s*NewPP limit report[^>]*-->\\s*$/si', '', $newHTML);
                 }
                 break;
             }
             // Otherwise fall back to database
         // Otherwise fall back to database
         case 'parse-wikitext-nonedit':
             // TODO: use Content object instead, if available! In any case, use WikiPage, not Article.
             $article = self::articleFromTitle($parameters['namespace'], $parameters['title']);
             $textVar = $parameters['wikitext-var'];
             if (!defined('MW_SUPPORTS_CONTENTHANDLER') || $article->getContentModel() === CONTENT_MODEL_WIKITEXT) {
                 if (isset($parameters['pst']) && $parameters['pst']) {
                     // $textVar is already PSTed when it's not loaded from an ongoing edit.
                     $result = $vars->getVar($textVar)->toString();
                 } else {
                     $text = $vars->getVar($textVar)->toString();
                     $editInfo = $this->parseNonEditWikitext($text, $article);
                     $result = $editInfo->output->getText();
                 }
             } else {
                 // TODO: Parser Output from Content object. But we don't have the content object.
                 //      And for non-text content, $wikitext is usually not going to be a valid
                 //      serialization, but rather some dummy text for filtering.
                 $result = '';
             }
             break;
         case 'strip-html':
             $htmlVar = $parameters['html-var'];
             $html = $vars->getVar($htmlVar)->toString();
             $result = StringUtils::delimiterReplace('<', '>', '', $html);
             break;
         case 'load-recent-authors':
             $cutOff = $parameters['cutoff'];
             $title = Title::makeTitle($parameters['namespace'], $parameters['title']);
             if (!$title->exists()) {
                 $result = '';
                 break;
             }
             $dbr = wfGetDB(DB_SLAVE);
             $res = $dbr->select('revision', 'DISTINCT rev_user_text', array('rev_page' => $title->getArticleID(), 'rev_timestamp<' . $dbr->addQuotes($dbr->timestamp($cutOff))), __METHOD__, array('ORDER BY' => 'rev_timestamp DESC', 'LIMIT' => 10));
             $users = array();
             foreach ($res as $row) {
                 $users[] = $row->rev_user_text;
             }
             $result = $users;
             break;
         case 'get-page-restrictions':
             $action = $parameters['action'];
             $title = Title::makeTitle($parameters['namespace'], $parameters['title']);
             $rights = $title->getRestrictions($action);
             $rights = count($rights) ? $rights : array();
             $result = $rights;
             break;
         case 'simple-user-accessor':
             $user = $parameters['user'];
             $method = $parameters['method'];
             if (!$user) {
                 throw new MWException('No user parameter given.');
             }
             $obj = self::getUserObject($user);
             if (!$obj) {
                 throw new MWException("Invalid username {$user}");
             }
             $result = call_user_func(array($obj, $method));
             break;
         case 'user-age':
             $user = $parameters['user'];
             $asOf = $parameters['asof'];
             $obj = self::getUserObject($user);
             if ($obj->getId() == 0) {
                 $result = 0;
                 break;
             }
             $registration = $obj->getRegistration();
             $result = wfTimestamp(TS_UNIX, $asOf) - wfTimestampOrNull(TS_UNIX, $registration);
             break;
         case 'user-groups':
             // Deprecated but needed by old log entries
             $user = $parameters['user'];
             $obj = self::getUserObject($user);
             $result = $obj->getEffectiveGroups();
             break;
         case 'length':
             $s = $vars->getVar($parameters['length-var'])->toString();
             $result = strlen($s);
             break;
         case 'subtract':
             $v1 = $vars->getVar($parameters['val1-var'])->toFloat();
             $v2 = $vars->getVar($parameters['val2-var'])->toFloat();
             $result = $v1 - $v2;
             break;
         case 'revision-text-by-id':
             $rev = Revision::newFromId($parameters['revid']);
             $result = AbuseFilter::revisionToString($rev);
             break;
         case 'revision-text-by-timestamp':
             $timestamp = $parameters['timestamp'];
             $title = Title::makeTitle($parameters['namespace'], $parameters['title']);
             $dbr = wfGetDB(DB_SLAVE);
             $rev = Revision::loadFromTimestamp($dbr, $title, $timestamp);
             $result = AbuseFilter::revisionToString($rev);
             break;
         default:
             if (wfRunHooks('AbuseFilter-computeVariable', array($this->mMethod, $vars, $parameters, &$result))) {
                 throw new AFPException('Unknown variable compute type ' . $this->mMethod);
             }
     }
     return $result instanceof AFPData ? $result : AFPData::newFromPHPVar($result);
 }
Exemple #22
0
 /**
  * Parse the form definition and return it
  */
 public static function getFormDefinition(&$parser, &$form_def = null, &$form_id = null)
 {
     $cachedDef = self::getFormDefinitionFromCache($form_id, $parser);
     if ($cachedDef) {
         return $cachedDef;
     }
     if ($form_id !== null) {
         $form_article = Article::newFromID($form_id);
         $form_def = $form_article->getContent();
     } elseif ($form_def == null) {
         // No id, no text -> nothing to do
         return '';
     }
     // Remove <noinclude> sections and <includeonly> tags from form definition
     $form_def = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $form_def);
     $form_def = strtr($form_def, array('<includeonly>' => '', '</includeonly>' => ''));
     // add '<nowiki>' tags around every triple-bracketed form
     // definition element, so that the wiki parser won't touch
     // it - the parser will remove the '<nowiki>' tags, leaving
     // us with what we need
     $form_def = "__NOEDITSECTION__" . strtr($form_def, array('{{{' => '<nowiki>{{{', '}}}' => '}}}</nowiki>'));
     $title = is_object($parser->getTitle()) ? $parser->getTitle() : new Title();
     // parse wiki-text
     $output = $parser->parse($form_def, $title, $parser->getOptions());
     $form_def = $output->getText();
     self::cacheFormDefinition($form_id, $parser, $output);
     return $form_def;
 }
Exemple #23
0
 /**
  * Take a fragment of (potentially invalid) HTML and return
  * a version with any tags removed, encoded as plain text.
  *
  * Warning: this return value must be further escaped for literal
  * inclusion in HTML output as of 1.10!
  *
  * @param string $text HTML fragment
  * @return string
  */
 static function stripAllTags($text)
 {
     # Actual <tags>
     $text = StringUtils::delimiterReplace('<', '>', '', $text);
     # Normalize &entities and whitespace
     $text = self::decodeCharReferences($text);
     $text = self::normalizeWhitespace($text);
     return $text;
 }
Exemple #24
0
 public static function wiki_get_template($widgetName, &$widgetCode, &$smarty_obj)
 {
     global $wgWidgetsUseFlaggedRevs;
     $widgetTitle = Title::newFromText($widgetName, NS_WIDGET);
     if ($widgetTitle && $widgetTitle->exists()) {
         if ($wgWidgetsUseFlaggedRevs) {
             $flaggedWidgetArticle = FlaggedArticle::getTitleInstance($widgetTitle);
             $flaggedWidgetArticleRevision = $flaggedWidgetArticle->getStableRev();
             if ($flaggedWidgetArticleRevision) {
                 $widgetCode = $flaggedWidgetArticleRevision->getRevText();
             } else {
                 $widgetCode = '';
             }
         } else {
             $widgetArticle = new Article($widgetTitle, 0);
             $widgetCode = $widgetArticle->getContent();
         }
         // Remove <noinclude> sections and <includeonly> tags from form definition
         $widgetCode = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $widgetCode);
         $widgetCode = strtr($widgetCode, array('<includeonly>' => '', '</includeonly>' => ''));
         return true;
     } else {
         return false;
     }
 }
Exemple #25
0
 public static function stripHTML($text)
 {
     return StringUtils::delimiterReplace('<', '>', '', $text);
 }
Exemple #26
0
 function getAllFieldsCargo($templateTitle)
 {
     $cargoFieldsOfTemplateParams = array();
     $templateFields = array();
     // First, get the table name, and fields, declared for this
     // template.
     $templatePageID = $templateTitle->getArticleID();
     $tableSchemaString = CargoUtils::getPageProp($templatePageID, 'CargoFields');
     // See if there even is DB storage for this template - if not,
     // exit.
     if (is_null($tableSchemaString)) {
         return null;
     }
     $tableSchema = CargoTableSchema::newFromDBString($tableSchemaString);
     $tableName = CargoUtils::getPageProp($templatePageID, 'CargoTableName');
     // Then, match template params to Cargo table fields, by
     // parsing call(s) to #cargo_store.
     $templateText = SFUtils::getPageText($templateTitle);
     // Ignore 'noinclude' sections and 'includeonly' tags.
     $templateText = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $templateText);
     $templateText = strtr($templateText, array('<includeonly>' => '', '</includeonly>' => ''));
     if (preg_match_all('/#cargo_store:(.*?}})\\s*}}/mis', $templateText, $matches)) {
         foreach ($matches[1] as $match) {
             if (preg_match_all('/([^|{]*?)=\\s*{{{([^|}]*)/mis', $match, $matches2)) {
                 foreach ($matches2[1] as $i => $cargoFieldName) {
                     $templateParameter = trim($matches2[2][$i]);
                     $cargoFieldsOfTemplateParams[$templateParameter] = $cargoFieldName;
                 }
             }
         }
     }
     // Now, combine the two sets of information into an array of
     // SFTemplateFields objects.
     $fieldDescriptions = $tableSchema->mFieldDescriptions;
     foreach ($cargoFieldsOfTemplateParams as $templateParameter => $cargoField) {
         $templateField = SFTemplateField::create($templateParameter, $templateParameter);
         if (array_key_exists($cargoField, $fieldDescriptions)) {
             $fieldDescription = $fieldDescriptions[$cargoField];
             $templateField->setCargoFieldData($tableName, $cargoField, $fieldDescription);
         }
         $templateFields[] = $templateField;
     }
     return $templateFields;
 }