Ejemplo n.º 1
0
 function getCategoryDefinedByTemplate($templateTitle)
 {
     global $wgContLang;
     $templateText = SFUtils::getPageText($templateTitle);
     $cat_ns_name = $wgContLang->getNsText(NS_TEMPLATE);
     if (preg_match_all("/\\[\\[(Category|{$cat_ns_name}):([^\\]]*)\\]\\]/", $templateText, $matches)) {
         // Get the last match - if there's more than one
         // category tag, there's a good chance that the last
         // one will be the relevant one - the others are
         // probably part of inline queries.
         $categoryName = trim(end($matches[2]));
         // If there's a pipe, remove it and anything after it.
         $locationOfPipe = strpos($categoryName, '|');
         if ($locationOfPipe !== false) {
             $categoryName = substr($categoryName, 0, $locationOfPipe);
         }
         return $categoryName;
     }
     return "";
 }
 public static function createPageWithForm($title, $formName)
 {
     global $sfgFormPrinter;
     $formTitle = Title::makeTitleSafe(SF_NS_FORM, $formName);
     $formDefinition = SFUtils::getPageText($formTitle);
     $preloadContent = null;
     // Allow outside code to set/change the preloaded text.
     Hooks::run('sfEditFormPreloadText', array(&$preloadContent, $title, $formTitle));
     list($formText, $javascriptText, $dataText, $formPageTitle, $generatedPageName) = $sfgFormPrinter->formHTML($formDefinition, false, false, null, $preloadContent, 'Some very long page name that will hopefully never get created ABCDEF123', null);
     $params = array();
     // Get user "responsible" for all auto-generated
     // pages from red links.
     $userID = 1;
     global $sfgAutoCreateUser;
     if (!is_null($sfgAutoCreateUser)) {
         $user = User::newFromName($sfgAutoCreateUser);
         if (!is_null($user)) {
             $userID = $user->getId();
         }
     }
     $params['user_id'] = $userID;
     $params['page_text'] = $dataText;
     $job = new SFCreatePageJob($title, $params);
     $jobs = array($job);
     if (class_exists('JobQueueGroup')) {
         JobQueueGroup::singleton()->push($jobs);
     } else {
         // MW <= 1.20
         Job::batchInsert($jobs);
     }
 }
 /**
  * Automatically creates a page that's red-linked from the page being
  * viewed, if there's a property pointing from anywhere to that page
  * that's defined with the 'Creates pages with form' special property
  */
 static function createLinkedPage($title, $incoming_properties)
 {
     // if we're in a 'special' page, just exit - this is to prevent
     // constant additions being made from the 'Special:RecentChanges'
     // page, which shows pages that were previously deleted as red
     // links, even if they've since been recreated. The same might
     // hold true for other special pages.
     global $wgTitle;
     if (empty($wgTitle)) {
         return false;
     }
     if ($wgTitle->getNamespace() == NS_SPECIAL) {
         return false;
     }
     foreach ($incoming_properties as $property_name) {
         $auto_create_forms = self::getFormsThatPagePointsTo($property_name, SMW_NS_PROPERTY, self::AUTO_CREATE_FORM);
         if (count($auto_create_forms) > 0) {
             global $sfgFormPrinter;
             $form_name = $auto_create_forms[0];
             $form_title = Title::makeTitleSafe(SF_NS_FORM, $form_name);
             $form_definition = SFUtils::getPageText($form_title);
             $preloadContent = null;
             // allow extensions to set/change the preload text
             wfRunHooks('sfEditFormPreloadText', array(&$preloadContent, $title, $form_title));
             list($form_text, $javascript_text, $data_text, $form_page_title, $generated_page_name) = $sfgFormPrinter->formHTML($form_definition, false, false, null, $preloadContent, 'Some very long page name that will hopefully never get created ABCDEF123', null);
             $params = array();
             // Get user "responsible" for all auto-generated
             // pages from red links.
             $userID = 1;
             global $sfgAutoCreateUser;
             if (!is_null($sfgAutoCreateUser)) {
                 $user = User::newFromName($sfgAutoCreateUser);
                 if (!is_null($user)) {
                     $userID = $user->getId();
                 }
             }
             $params['user_id'] = $userID;
             $params['page_text'] = $data_text;
             $job = new SFCreatePageJob($title, $params);
             Job::batchInsert(array($job));
             return true;
         }
     }
     return false;
 }
    function printPage($form_name, $embedded = false)
    {
        global $wgOut, $wgRequest, $sfgFormPrinter, $wgParser, $sfgRunQueryFormAtTop;
        global $wgUser;
        // Get contents of form-definition page.
        $form_title = Title::makeTitleSafe(SF_NS_FORM, $form_name);
        if (!$form_title || !$form_title->exists()) {
            if ($form_name === '') {
                $text = Html::element('p', array('class' => 'error'), wfMessage('sf_runquery_badurl')->text()) . "\n";
            } else {
                $text = Html::rawElement('p', array('class' => 'error'), wfMessage('sf_formstart_badform', SFUtils::linkText(SF_NS_FORM, $form_name))->parse()) . "\n";
            }
            $wgOut->addHTML($text);
            return;
        }
        // Initialize variables.
        $form_definition = SFUtils::getPageText($form_title);
        if ($embedded) {
            $run_query = false;
            $content = null;
            $raw = false;
        } else {
            $run_query = $wgRequest->getCheck('wpRunQuery');
            $content = $wgRequest->getVal('wpTextbox1');
            $raw = $wgRequest->getBool('raw', false);
        }
        $form_submitted = $run_query;
        if ($raw) {
            $wgOut->setArticleBodyOnly(true);
        }
        // If user already made some action, ignore the edited
        // page and just get data from the query string.
        if (!$embedded && $wgRequest->getVal('query') == 'true') {
            $edit_content = null;
            $is_text_source = false;
        } elseif ($content != null) {
            $edit_content = $content;
            $is_text_source = true;
        } else {
            $edit_content = null;
            $is_text_source = true;
        }
        list($form_text, $javascript_text, $data_text, $form_page_title) = $sfgFormPrinter->formHTML($form_definition, $form_submitted, $is_text_source, $form_title->getArticleID(), $edit_content, null, null, true, $embedded);
        $text = "";
        // Get the text of the results.
        $resultsText = '';
        if ($form_submitted) {
            // @TODO - fix RunQuery's parsing so that this check
            // isn't needed.
            if ($wgParser->getOutput() == null) {
                $headItems = array();
            } else {
                $headItems = $wgParser->getOutput()->getHeadItems();
            }
            foreach ($headItems as $key => $item) {
                $wgOut->addHeadItem($key, "\t\t" . $item . "\n");
            }
            $wgParser->mOptions = ParserOptions::newFromUser($wgUser);
            $resultsText = $wgParser->parse($data_text, $this->getTitle(), $wgParser->mOptions)->getText();
        }
        // Get the full text of the form.
        $fullFormText = '';
        $additionalQueryHeader = '';
        $dividerText = '';
        if (!$raw) {
            // Create the "additional query" header, and the
            // divider text - one of these (depending on whether
            // the query form is at the top or bottom) is displayed
            // if the form has already been submitted.
            if ($form_submitted) {
                $additionalQueryHeader = "\n" . Html::element('h2', null, wfMessage('sf_runquery_additionalquery')->text()) . "\n";
                $dividerText = "\n<hr style=\"margin: 15px 0;\" />\n";
            }
            $action = htmlspecialchars($this->getTitle($form_name)->getLocalURL());
            $fullFormText .= <<<END
\t<form id="sfForm" name="createbox" action="{$action}" method="post" class="createbox">

END;
            $fullFormText .= Html::hidden('query', 'true');
            $fullFormText .= $form_text;
        }
        // Either don't display a query form at all, or display the
        // query form at the top, and the results at the bottom, or the
        // other way around, depending on the settings.
        if ($wgRequest->getVal('additionalquery') == 'false') {
            $text .= $resultsText;
        } elseif ($sfgRunQueryFormAtTop) {
            $text .= Html::openElement('div', array('class' => 'sf-runquery-formcontent'));
            $text .= $fullFormText;
            $text .= $dividerText;
            $text .= Html::closeElement('div');
            $text .= $resultsText;
        } else {
            $text .= $resultsText;
            $text .= Html::openElement('div', array('class' => 'sf-runquery-formcontent'));
            $text .= $additionalQueryHeader;
            $text .= $fullFormText;
            $text .= Html::closeElement('div');
        }
        if ($embedded) {
            $text = "<div class='runQueryEmbedded'>{$text}</div>";
        }
        // Armor against doBlockLevels()
        $text = preg_replace('/^ +/m', '', $text);
        // Now write everything to the screen.
        $wgOut->addHTML($text);
        SFUtils::addFormRLModules($embedded ? $wgParser : null);
        $script = "\t\t" . '<script type="text/javascript">' . "\n" . $javascript_text . '</script>' . "\n";
        if ($embedded) {
            if (method_exists('ResourceLoader', 'makeInlineScript')) {
                // MW 1.25+
                $wgParser->getOutput()->addHeadItem(ResourceLoader::makeInlineScript($javascript_text));
            } else {
                $wgParser->getOutput()->addHeadItem($script);
            }
        } else {
            if (method_exists('ResourceLoader', 'makeInlineScript')) {
                // MW 1.25+
                $wgOut->addScript(ResourceLoader::makeInlineScript($javascript_text));
            } else {
                $wgOut->addScript($script);
            }
            $po = $wgParser->getOutput();
            if ($po) {
                // addParserOutputMetadata was introduced in 1.24 when addParserOutputNoText was deprecated
                if (method_exists($wgOut, 'addParserOutputMetadata')) {
                    $wgOut->addParserOutputMetadata($po);
                } else {
                    $wgOut->addParserOutputNoText($po);
                }
            }
        }
        // Finally, set the page title - previously, this had to be
        // called after addParserOutputNoText() for it to take effect;
        // now the order doesn't matter.
        if (!$embedded) {
            if ($form_page_title != null) {
                $wgOut->setPageTitle($form_page_title);
            } else {
                $s = wfMessage('sf_runquery_title', $form_title->getText())->text();
                $wgOut->setPageTitle($s);
            }
        }
    }
 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;
 }
 /**
  * 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);
     if (isset($template_title)) {
         $templateText = SFUtils::getPageText($template_title);
         // 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 php.ini or LocalSettings.php.';
             }
         }
         // 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, #set_internal and
         // #subobject. (Thankfully, they all have similar
         // syntax).
         if (preg_match_all('/#(set|set_internal|subobject):(.*?}}})\\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. (This is really rather
         // optional, since no one seems to use #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;
 }
 /**
  * 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;
 }
Ejemplo n.º 8
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;
 }