Example #1
0
 public function testConstruction()
 {
     $e = new ReadOnlyError();
     $this->assertEquals('readonly', $e->title);
     $this->assertEquals('readonlytext', $e->msg);
     $this->assertEquals(wfReadOnlyReason() ?: array(), $e->params);
 }
Example #2
0
 function __construct(Article $article)
 {
     // Set instance variables.
     $this->mArticle = $article;
     $this->mTitle = $article->getTitle();
     $this->mApplicableTypes = $this->mTitle->getRestrictionTypes();
     $this->mContext = $article->getContext();
     // Check if the form should be disabled.
     // If it is, the form will be available in read-only to show levels.
     $this->mPermErrors = $this->mTitle->getUserPermissionsErrors('protect', $this->mContext->getUser(), $this->mContext->getRequest()->wasPosted() ? 'secure' : 'full');
     if (wfReadOnly()) {
         $this->mPermErrors[] = ['readonlytext', wfReadOnlyReason()];
     }
     $this->disabled = $this->mPermErrors != [];
     $this->disabledAttrib = $this->disabled ? ['disabled' => 'disabled'] : [];
     $this->loadData();
 }
 function __construct(Page $article)
 {
     global $wgUser;
     // Set instance variables.
     $this->mArticle = $article;
     $this->mTitle = $article->getTitle();
     $this->mApplicableTypes = $this->mTitle->getRestrictionTypes();
     // Check if the form should be disabled.
     // If it is, the form will be available in read-only to show levels.
     $this->mPermErrors = $this->mTitle->getUserPermissionsErrors('protect', $wgUser);
     if (wfReadOnly()) {
         $this->mPermErrors[] = array('readonlytext', wfReadOnlyReason());
     }
     $this->disabled = $this->mPermErrors != array();
     $this->disabledAttrib = $this->disabled ? array('disabled' => 'disabled') : array();
     $this->loadData();
 }
 /**
  * Get status of database clusters
  *
  * Returns:
  * - clusters: associative array of cluster statuses
  *   cluster name is the key and one of "ok", "warning", "critical" as a value
  * - messages: list of notices
  * - errors: list of errors
  */
 public function databases()
 {
     $cluster = $this->getVal('cluster');
     $clusters = $this->getAllClusters();
     if ($cluster) {
         $clusters = array_intersect([$cluster], $clusters);
     }
     $this->clusters = $clusters;
     $this->testClusters();
     $this->setVal('clusters', $this->status);
     if ($this->errors) {
         $this->setVal('errors', $this->errors);
     }
     if ($this->messages) {
         $this->setVal('messages', $this->messages);
     }
     $this->setVal('readWrite', ['status' => !wfReadOnly(), 'reason' => wfReadOnlyReason()]);
 }
    /**
     * This function is the real heart of the entire Semantic Forms
     * extension. It handles two main actions: (1) displaying a form on the
     * screen, given a form definition and possibly page contents (if an
     * existing page is being edited); and (2) creating actual page
     * contents, if the form was already submitted by the user.
     *
     * It also does some related tasks, like figuring out the page name (if
     * only a page formula exists).
     */
    function formHTML($form_def, $form_submitted, $source_is_page, $form_id = null, $existing_page_content = null, $page_name = null, $page_name_formula = null, $is_query = false, $is_embedded = false)
    {
        global $wgRequest, $wgUser, $wgParser;
        global $sfgTabIndex;
        // used to represent the current tab index in the form
        global $sfgFieldNum;
        // used for setting various HTML IDs
        // initialize some variables
        $wiki_page = new SFWikiPage();
        $sfgTabIndex = 1;
        $sfgFieldNum = 1;
        $source_page_matches_this_form = false;
        $form_page_title = null;
        $generated_page_name = $page_name_formula;
        // $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 a hidden text field.
        if (!$wgRequest->getCheck('partial')) {
            $original_page_content = $existing_page_content;
        } else {
            $original_page_content = null;
            if ($wgRequest->getCheck('sf_free_text')) {
                if (!isset($existing_page_content) || $existing_page_content == '') {
                    $existing_page_content = $wgRequest->getVal('sf_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 ($is_embedded) {
            // If this is an embedded form (probably a 'RunQuery'),
            // just use the name of the actual page we're on.
            global $wgTitle;
            $this->mPageTitle = $wgTitle;
        } elseif ($is_query) {
            // We're in Special:RunQuery - just use that as the
            // title.
            global $wgTitle;
            $this->mPageTitle = $wgTitle;
        } elseif ($page_name === '' || $page_name === null) {
            $this->mPageTitle = Title::newFromText($wgRequest->getVal('namespace') . ":Semantic Forms permissions test");
        } else {
            $this->mPageTitle = Title::newFromText($page_name);
        }
        global $wgOut;
        // Show previous set of deletions for this page, if it's been
        // deleted before.
        if (!$form_submitted && ($this->mPageTitle && !$this->mPageTitle->exists() && is_null($page_name_formula))) {
            $this->showDeletionLog($wgOut);
        }
        // Unfortunately, we can't just call userCan() here because,
        // since MW 1.16, it has a bug in which it ignores a setting of
        // "$wgEmailConfirmToEdit = true;". Instead, we'll just get the
        // permission errors from the start, and use those to determine
        // whether the page is editable.
        if (!$is_query) {
            // $userCanEditPage = ( $wgUser->isAllowed( 'edit' ) && $this->mPageTitle->userCan( 'edit' ) );
            $permissionErrors = $this->mPageTitle->getUserPermissionsErrors('edit', $wgUser);
            // The handling of $wgReadOnly and $wgReadOnlyFile
            // has to be done separately.
            if (wfReadOnly()) {
                $permissionErrors = array(array('readonlytext', array(wfReadOnlyReason())));
            }
            $userCanEditPage = count($permissionErrors) == 0;
            Hooks::run('sfUserCanEditPage', array($this->mPageTitle, &$userCanEditPage));
        }
        $form_text = "";
        if ($is_query || $userCanEditPage) {
            $form_is_disabled = false;
            // Show "Your IP address will be recorded" warning if
            // user is anonymous, and it's not a query.
            if ($wgUser->isAnon() && !$is_query) {
                // Based on code in MediaWiki's EditPage.php.
                $anonEditWarning = wfMessage('anoneditwarning', '{{fullurl:Special:UserLogin|returnto={{FULLPAGENAMEE}}}}', '{{fullurl:Special:UserLogin/signup|returnto={{FULLPAGENAMEE}}}}')->parse();
                $form_text .= Html::rawElement('div', array('id' => 'mw-anon-edit-warning', 'class' => 'warningbox'), $anonEditWarning);
            }
        } else {
            $form_is_disabled = true;
            $wgOut->setPageTitle(wfMessage('badaccess')->text());
            $wgOut->addWikiText($wgOut->formatPermissionsErrorMessage($permissionErrors, 'edit'));
            $wgOut->addHTML("\n<hr />\n");
        }
        //		$oldParser = $wgParser;
        //		$wgParser = unserialize( serialize( $oldParser ) ); // deep clone of parser
        if (!$wgParser->Options()) {
            $wgParser->Options(ParserOptions::newFromUser($wgUser));
        }
        $wgParser->Title($this->mPageTitle);
        // This is needed in order to make sure $parser->mLinkHolders
        // is set.
        $wgParser->clearState();
        $form_def = SFFormUtils::getFormDefinition($wgParser, $form_def, $form_id);
        // 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;
        // Unencode any 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 was 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 = SFUtils::getFormTagComponents($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 the 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.
        $tif = null;
        // This array will keep track of all the replaced @<name>@ strings
        $placeholderFields = array();
        for ($section_num = 0; $section_num < count($form_def_sections); $section_num++) {
            $start_position = 0;
            // 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 = SFUtils::getFormTagComponents($bracketed_string);
                $tag_title = trim($tag_components[0]);
                // =====================================================
                // for template processing
                // =====================================================
                if ($tag_title == 'for template') {
                    if ($tif) {
                        $previous_template_name = $tif->getTemplateName();
                    } else {
                        $previous_template_name = '';
                    }
                    $template_name = str_replace('_', ' ', $tag_components[1]);
                    $is_new_template = $template_name != $previous_template_name;
                    if ($is_new_template) {
                        $tif = SFTemplateInForm::newFromFormTag($tag_components);
                    }
                    // Remove template tag.
                    $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    // 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.
                    if ($source_is_page) {
                        $tif->setPageRelatedInfo($existing_page_content);
                        // Get the first instance of
                        // this template on the page
                        // being edited, even if there
                        // are more.
                        if ($tif->pageCallsThisTemplate()) {
                            $tif->setFieldValuesFromPage($existing_page_content);
                            $existing_template_text = $tif->getFullTextInPage();
                            // 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("\n" . '{{{insertionpoint}}}', '', $existing_page_content);
                                    $existing_page_content = str_replace($existing_template_text, '{{{insertionpoint}}}', $existing_page_content);
                                }
                            } else {
                                $existing_page_content = $this->strReplaceFirst($existing_template_text, '', $existing_page_content);
                            }
                            // If 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.
                            $source_page_matches_this_form = true;
                        }
                    }
                    if ($form_submitted) {
                        $tif->setFieldValuesFromSubmit();
                    }
                    $tif->checkIfAllInstancesPrinted($form_submitted, $source_is_page);
                    if (!$tif->allInstancesPrinted()) {
                        $wiki_page->addTemplate($tif);
                    }
                    // =====================================================
                    // end template processing
                    // =====================================================
                } elseif ($tag_title == 'end template') {
                    if ($source_is_page) {
                        // Add any unhandled template fields
                        // in the page as hidden variables.
                        $form_text .= SFFormUtils::unhandledFieldsHTML($tif);
                    }
                    // Remove this tag from the $section variable.
                    $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    $tif = null;
                    // =====================================================
                    // field processing
                    // =====================================================
                } elseif ($tag_title == 'field') {
                    // If the template is null, that (hopefully)
                    // means we're handling the free text field.
                    // Make the template a dummy variable.
                    if ($tif == null) {
                        $tif = new SFTemplateInForm();
                    }
                    // We get the field name both here
                    // and in the SFFormField constructor,
                    // because SFFormField isn't equipped
                    // to deal with the <freetext> hack,
                    // among others.
                    $field_name = trim($tag_components[1]);
                    $form_field = SFFormField::newFromFormFieldTag($tag_components, $tif, $form_is_disabled);
                    $cur_value = $form_field->getCurrentValue($tif->getValuesFromSubmit(), $form_submitted, $source_is_page);
                    if ($form_field->holdsTemplate()) {
                        $placeholderFields[] = self::placeholderFormat($tif->getTemplateName(), $field_name);
                    }
                    // If the user is editing a page, and that page contains a call to
                    // the template being processed, get the current field's value
                    // from the template call
                    if ($source_is_page && ($tif->getFullTextInPage() != '' && !$form_submitted)) {
                        if ($tif->hasValueFromPageForField($field_name)) {
                            // Get value, and remove it,
                            // so that at the end we
                            // can have a list of all
                            // the fields that weren't
                            // handled by the form.
                            $cur_value = $tif->getAndRemoveValueFromPageForField($field_name);
                            // If the field is a placeholder, the contents of this template
                            // parameter should be treated as elements parsed by an another
                            // multiple template form.
                            // By putting that at the very end of the parsed string, we'll
                            // have it processed as a regular multiple template form.
                            if ($form_field->holdsTemplate()) {
                                $existing_page_content .= $cur_value;
                            }
                        } elseif (isset($cur_value) && !empty($cur_value)) {
                            // Do nothing.
                        } else {
                            $cur_value = '';
                        }
                    }
                    // Handle the free text field.
                    if ($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 ($form_field->isHidden()) {
                            $new_text = Html::hidden('sf_free_text', '!free_text!');
                        } else {
                            $sfgTabIndex++;
                            $sfgFieldNum++;
                            if ($cur_value === '' || is_null($cur_value)) {
                                $default_value = '!free_text!';
                            } else {
                                $default_value = $cur_value;
                            }
                            $new_text = SFTextAreaInput::getHTML($default_value, 'sf_free_text', false, $form_is_disabled || $form_field->isRestricted(), $form_field->getFieldArgs());
                            if ($form_field->hasFieldArg('edittools')) {
                                // borrowed from EditPage::showEditTools()
                                $edittools_text = $wgParser->recursiveTagParse(wfMessage('edittools', array('content'))->text());
                                $new_text .= <<<END
\t\t<div class="mw-editTools">
\t\t{$edittools_text}
\t\t</div>

END;
                            }
                        }
                        $free_text_was_included = true;
                        $wiki_page->addFreeTextSection();
                    }
                    if ($tif->getTemplateName() === '' || $field_name == '<freetext>') {
                        $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    } else {
                        if (is_array($cur_value)) {
                            // @TODO - is this code ever called?
                            $delimiter = $form_field->getFieldArg('is_list');
                            // first, check if it's a list
                            if (array_key_exists('is_list', $cur_value) && $cur_value['is_list'] == true) {
                                $cur_value_in_template = "";
                                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 {
                                // If it's not a list, it's probably from a checkbox or date input -
                                // convert the values into a string.
                                $cur_value_in_template = self::getStringFromPassedInArray($cur_value, $delimiter);
                            }
                        } else {
                            // value is not an array
                            $cur_value_in_template = $cur_value;
                        }
                        // If we're creating the page name from a formula based on
                        // form values, see if the current input is part of that formula,
                        // and if so, substitute in the actual value.
                        if ($form_submitted && $generated_page_name !== '') {
                            // This line appears to be unnecessary.
                            // $generated_page_name = str_replace('.', '_', $generated_page_name);
                            $generated_page_name = str_replace(' ', '_', $generated_page_name);
                            $escaped_input_name = str_replace(' ', '_', $form_field->getInputName());
                            $generated_page_name = str_ireplace("<{$escaped_input_name}>", $cur_value_in_template, $generated_page_name);
                            // Once the substitution is done, replace underlines back
                            // with spaces.
                            $generated_page_name = str_replace('_', ' ', $generated_page_name);
                        }
                        // Call hooks - unfortunately this has to be split into two
                        // separate calls, because of the different variable names in
                        // each case.
                        if ($form_submitted) {
                            Hooks::run('sfCreateFormField', array(&$form_field, &$cur_value_in_template, true));
                        } else {
                            if (!empty($cur_value) && ($form_field->hasFieldArg('mapping template') || $form_field->hasFieldArg('mapping property') || $form_field->hasFieldArg('mapping cargo table') && $form_field->hasFieldArg('mapping cargo field'))) {
                                $cur_value = SFUtils::valuesToLabels($cur_value, $delimiter, $form_field->getPossibleValues());
                            }
                            Hooks::run('sfCreateFormField', array(&$form_field, &$cur_value, false));
                        }
                        // if this is not part of a 'multiple' template, increment the
                        // global tab index (used for correct tabbing)
                        if (!$form_field->hasFieldArg('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 ($form_field->getDefaultValue() == 'now' && ($cur_value == '' || $cur_value == 'now')) {
                            $input_type = $form_field->getInputType();
                            if ($input_type == 'date' || $input_type == 'datetime' || $input_type == 'year' || $input_type == '' && $form_field->getTemplateField()->getPropertyType() == '_dat') {
                                $cur_value_in_template = self::getStringForCurrentTime($input_type == 'datetime', $form_field->hasFieldArg('include 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 ($form_field->getDefaultValue() == 'current user' && ($cur_value === '' || $cur_value == 'current user')) {
                            $cur_value_in_template = $wgUser->getName();
                            $cur_value = $cur_value_in_template;
                        }
                        // If all instances have been
                        // printed, that means we're
                        // now printing a "starter"
                        // div - set the current value
                        // to null.
                        // (Ideally it wouldn't get
                        // set at all, but that seems a
                        // little harder.)
                        if ($tif->allInstancesPrinted()) {
                            $cur_value = null;
                        }
                        $new_text = $this->formFieldHTML($form_field, $cur_value);
                        $new_text .= $form_field->additionalHTMLForInput($cur_value, $field_name, $tif->getTemplateName());
                        if ($new_text) {
                            $wiki_page->addTemplateParam($template_name, $tif->getInstanceNum(), $field_name, $cur_value_in_template);
                            $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                        } else {
                            $start_position = $brackets_end_loc;
                        }
                    }
                    // =====================================================
                    // standard input processing
                    // =====================================================
                } elseif ($tag_title == 'standard input') {
                    // handle all the possible values
                    $input_name = $tag_components[1];
                    $input_label = null;
                    $attr = array();
                    // if it's a query, ignore all standard inputs except run query
                    if ($is_query && $input_name != 'run query' || !$is_query && $input_name == 'run query') {
                        $new_text = "";
                        $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                        continue;
                    }
                    // set a flag so that the standard 'form bottom' won't get displayed
                    $this->standardInputsIncluded = true;
                    // cycle through the other components
                    $is_checked = false;
                    for ($i = 2; $i < count($tag_components); $i++) {
                        $component = $tag_components[$i];
                        $sub_components = array_map('trim', explode('=', $component));
                        if (count($sub_components) == 1) {
                            if ($sub_components[0] == 'checked') {
                                $is_checked = true;
                            }
                        } elseif (count($sub_components) == 2) {
                            switch ($sub_components[0]) {
                                case 'label':
                                    $input_label = $wgParser->recursiveTagParse($sub_components[1]);
                                    break;
                                case 'class':
                                case 'style':
                                    $attr[$sub_components[0]] = $sub_components[1];
                                    break;
                            }
                        }
                    }
                    if ($input_name == 'summary') {
                        $value = $wgRequest->getVal('wpSummary');
                        $new_text = SFFormUtils::summaryInputHTML($form_is_disabled, $input_label, $attr, $value);
                    } elseif ($input_name == 'minor edit') {
                        $is_checked = $wgRequest->getCheck('wpMinoredit');
                        $new_text = SFFormUtils::minorEditInputHTML($form_submitted, $form_is_disabled, $is_checked, $input_label, $attr);
                    } elseif ($input_name == 'watch') {
                        $is_checked = $wgRequest->getCheck('wpWatchthis');
                        $new_text = SFFormUtils::watchInputHTML($form_submitted, $form_is_disabled, $is_checked, $input_label, $attr);
                    } elseif ($input_name == 'save') {
                        $new_text = SFFormUtils::saveButtonHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'save and continue') {
                        $new_text = SFFormUtils::saveAndContinueButtonHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'preview') {
                        $new_text = SFFormUtils::showPreviewButtonHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'changes') {
                        $new_text = SFFormUtils::showChangesButtonHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'cancel') {
                        $new_text = SFFormUtils::cancelLinkHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'run query') {
                        $new_text = SFFormUtils::runQueryButtonHTML($form_is_disabled, $input_label, $attr);
                    }
                    $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    // =====================================================
                    // for section processing
                    // =====================================================
                } elseif ($tag_title == 'section') {
                    $section_name = trim($tag_components[1]);
                    $page_section_in_form = SFPageSection::newFromFormTag($tag_components);
                    // Split the existing page contents into the textareas in the form.
                    $default_value = "";
                    $section_start_loc = 0;
                    if ($source_is_page && $existing_page_content !== null) {
                        // For the last section of the page, there is no trailing newline in
                        // $existing_page_content, but the code below expects it. This code
                        // ensures that there is always trailing newline. T72202
                        if (substr($existing_page_content, -1) !== "\n") {
                            $existing_page_content .= "\n";
                        }
                        $equalsSigns = str_pad('', $page_section_in_form->getSectionLevel(), '=');
                        $searchStr = '/^' . preg_quote($equalsSigns, '/') . '[ ]*?' . preg_quote($section_name, '/') . '[ ]*?' . preg_quote($equalsSigns, '/') . '$/m';
                        if (preg_match($searchStr, $existing_page_content, $matches, PREG_OFFSET_CAPTURE)) {
                            $section_start_loc = $matches[0][1];
                            $header_text = $matches[0][0];
                            $existing_page_content = str_replace($header_text, '', $existing_page_content);
                        } else {
                            $section_start_loc = 0;
                        }
                        $section_end_loc = -1;
                        // get the position of the next template or section defined in the form
                        $next_section_start_loc = strpos($section, '{{{', $brackets_end_loc);
                        if ($next_section_start_loc == false) {
                            $section_end_loc = strpos($existing_page_content, '{{', $section_start_loc);
                        } else {
                            $next_section_end_loc = strpos($section, '}}}', $next_section_start_loc);
                            $bracketed_string_next_section = substr($section, $next_section_start_loc + 3, $next_section_end_loc - ($next_section_start_loc + 3));
                            $tag_components_next_section = SFUtils::getFormTagComponents($bracketed_string_next_section);
                            $tag_title_next_section = trim($tag_components_next_section[0]);
                            if ($tag_title_next_section == 'section') {
                                if (preg_match('/(^={1,6}[ ]*?' . $tag_components_next_section[1] . '[ ]*?={1,6}\\s*?$)/m', $existing_page_content, $matches, PREG_OFFSET_CAPTURE)) {
                                    $section_end_loc = $matches[0][1];
                                }
                            }
                        }
                        if ($section_end_loc === -1) {
                            $section_text = $existing_page_content;
                            $existing_page_content = '';
                        } else {
                            $section_text = substr($existing_page_content, $section_start_loc, $section_end_loc - $section_start_loc);
                            $existing_page_content = substr($existing_page_content, $section_end_loc);
                        }
                    }
                    // If input is from the form.
                    if (!$source_is_page && $wgRequest) {
                        $text_per_section = $wgRequest->getArray('_section');
                        $section_text = $text_per_section[trim($section_name)];
                        $wiki_page->addSection($section_name, $page_section_in_form->getSectionLevel(), $section_text);
                    }
                    $section_text = trim($section_text);
                    // Set input name for query string.
                    $input_name = '_section' . '[' . trim($section_name) . ']';
                    $other_args = $page_section_in_form->getSectionArgs();
                    $other_args['isSection'] = true;
                    if ($page_section_in_form->isMandatory()) {
                        $other_args['mandatory'] = true;
                    }
                    if ($page_section_in_form->isHidden()) {
                        $form_section_text = Html::hidden($input_name, $section_text);
                    } else {
                        $form_section_text = SFTextAreaInput::getHTML($section_text, $input_name, false, $form_is_disabled || $page_section_in_form->isRestricted(), $other_args);
                    }
                    $section = substr_replace($section, $form_section_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    // =====================================================
                    // page info processing
                    // =====================================================
                } elseif ($tag_title == 'info') {
                    // TODO: Generate an error message if this is included more than once
                    foreach (array_slice($tag_components, 1) as $component) {
                        $sub_components = array_map('trim', explode('=', $component, 2));
                        // Tag names are case-insensitive
                        $tag = strtolower($sub_components[0]);
                        if ($tag == 'create title' || $tag == 'add title') {
                            // Handle this only if
                            // we're adding a page.
                            if (!$is_query && !$this->mPageTitle->exists()) {
                                $form_page_title = $sub_components[1];
                            }
                        } elseif ($tag == 'edit title') {
                            // Handle this only if
                            // we're editing a page.
                            if (!$is_query && $this->mPageTitle->exists()) {
                                $form_page_title = $sub_components[1];
                            }
                        } elseif ($tag == 'query title') {
                            // Handle this only if
                            // we're in 'RunQuery'.
                            if ($is_query) {
                                $form_page_title = $sub_components[1];
                            }
                        } elseif ($tag == 'partial form') {
                            $form_is_partial = true;
                            // replacement pages may have minimal matches...
                            $source_page_matches_this_form = true;
                        } elseif ($tag == 'includeonly free text' || $tag == 'onlyinclude free text') {
                            $wiki_page->makeFreeTextOnlyInclude();
                        } elseif ($tag == 'query form at top') {
                            // TODO - this should be made a field of
                            // some non-static class that actually
                            // prints the form, instead of requiring
                            // a global variable.
                            global $sfgRunQueryFormAtTop;
                            $sfgRunQueryFormAtTop = true;
                        }
                    }
                    $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    // =====================================================
                    // default outer level processing
                    // =====================================================
                } else {
                    // Tag is not one of the three allowed values -
                    // ignore the tag.
                    $start_position = $brackets_end_loc;
                }
                // end if
            }
            // end while
            if ($tif && (!$tif->allowsMultiple() || $tif->allInstancesPrinted())) {
                $template_text = $wiki_page->createTemplateCallsForTemplateName($tif->getTemplateName());
                // If there is a placeholder in the text, we
                // know that we are doing a replace.
                if ($existing_page_content && strpos($existing_page_content, '{{{insertionpoint}}}', 0) !== false) {
                    $existing_page_content = preg_replace('/\\{\\{\\{insertionpoint\\}\\}\\}(\\r?\\n?)/', preg_replace('/\\}\\}/m', '}�', preg_replace('/\\{\\{/m', '�{', $template_text)) . "\n{{{insertionpoint}}}", $existing_page_content);
                    // Otherwise, if it's a partial form, we have to add the new
                    // text somewhere.
                } elseif ($form_is_partial && $wgRequest->getCheck('partial')) {
                    $existing_page_content = preg_replace('/\\}\\}/m', '}�', preg_replace('/\\{\\{/m', '�{', $template_text)) . "{{{insertionpoint}}}" . $existing_page_content;
                }
            }
            if ($tif && $tif->allowsMultiple()) {
                if ($tif->getInstanceNum() == 0) {
                    $multipleTemplateHTML = $this->multipleTemplateStartHTML($tif);
                } else {
                    $multipleTemplateHTML = '';
                }
                if (!$tif->allInstancesPrinted()) {
                    $multipleTemplateHTML .= $this->multipleTemplateInstanceHTML($tif, $form_is_disabled, $section);
                } else {
                    $multipleTemplateHTML .= $this->multipleTemplateEndHTML($tif, $form_is_disabled, $section);
                }
                $placeholder = $tif->getPlaceholder();
                if ($placeholder != null) {
                    $multipleTemplateHTML .= self::makePlaceholderInFormHTML($placeholder);
                }
                if ($tif->allInstancesPrinted() && $tif->getLabel() != null) {
                    $multipleTemplateHTML .= "</fieldset>\n";
                }
                if ($placeholder == null) {
                    // The normal process.
                    $form_text .= $multipleTemplateHTML;
                } else {
                    // The template text won't be appended
                    // at the end of the template like for
                    // usual multiple template forms.
                    // The HTML text will instead be stored in
                    // the $multipleTemplateHTML variable,
                    // and then added in the right
                    // @insertHTML_".$placeHolderField."@"; position
                    // Optimization: actually, instead of
                    // separating the processes, the usual
                    // multiple template forms could also be
                    // handled this way if a fitting
                    // placeholder tag was added.
                    // We replace the HTML into the current
                    // placeholder tag, but also add another
                    // placeholder tag, to keep track of it.
                    $form_text = str_replace(self::makePlaceholderInFormHTML($placeholder), $multipleTemplateHTML, $form_text);
                }
                if (!$tif->allInstancesPrinted()) {
                    // This will cause the section to be
                    // re-parsed on the next go.
                    $section_num--;
                    $tif->incrementInstanceNum();
                }
            } else {
                $form_text .= $section;
            }
        }
        // end for
        // Cleanup - everything has been browsed.
        // Remove all the remaining placeholder
        // tags in the HTML and wiki-text.
        foreach ($placeholderFields as $stringToReplace) {
            // Remove the @<insertHTML>@ tags from the generated
            // HTML form.
            $form_text = str_replace(self::makePlaceholderInFormHTML($stringToReplace), '', $form_text);
        }
        // If it wasn't included in the form definition, add the
        // 'free text' input as a hidden field at the bottom.
        if (!$free_text_was_included) {
            $form_text .= Html::hidden('sf_free_text', '!free_text!');
        }
        // 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;
            } else {
                $free_text = null;
                $existing_page_content = preg_replace(array('/�\\{/m', '/\\}�/m'), array('{{', '}}'), $existing_page_content);
                $existing_page_content = str_replace('{{{insertionpoint}}}', '', $existing_page_content);
            }
            $form_text .= Html::hidden('partial', 1);
        } 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('sf_free_text')) {
            $free_text = $wgRequest->getVal('sf_free_text');
            if (!$free_text_was_included) {
                $wiki_page->addFreeTextSection();
            }
        } else {
            $free_text = null;
        }
        if ($wiki_page->freeTextOnlyInclude()) {
            $free_text = str_replace("<onlyinclude>", '', $free_text);
            $free_text = str_replace("</onlyinclude>", '', $free_text);
            $free_text = trim($free_text);
        }
        $page_text = '';
        // The first hook here is deprecated. Use the second.
        // Note: Hooks::run can take a third argument which indicates
        // a deprecated hook, but it expects a MediaWiki version, not
        // an extension version.
        Hooks::run('sfModifyFreeTextField', array(&$free_text, $existing_page_content));
        Hooks::run('sfBeforeFreeTextSubstitution', array(&$free_text, $existing_page_content, &$page_text));
        // Now that we have it, add free text to the page, and
        // substitute it into the form.
        if ($form_submitted) {
            $wiki_page->setFreeText($free_text);
            $page_text = $wiki_page->createPageText();
        }
        $escaped_free_text = Sanitizer::safeEncodeAttribute($free_text);
        $form_text = str_replace('!free_text!', $escaped_free_text, $form_text);
        // Add a warning in, if we're editing an existing page and that
        // page appears to not have been created with this form.
        if (!$is_query && is_null($page_name_formula) && $this->mPageTitle->exists() && $existing_page_content !== '' && !$source_page_matches_this_form) {
            $form_text = "\t" . '<div class="warningbox">' . wfMessage('sf_formedit_formwarning', $this->mPageTitle->getFullURL())->text() . "</div>\n<br clear=\"both\" />\n" . $form_text;
        }
        // Add form bottom, if no custom "standard inputs" have been defined.
        if (!$this->standardInputsIncluded) {
            if ($is_query) {
                $form_text .= SFFormUtils::queryFormBottom($form_is_disabled);
            } else {
                $form_text .= SFFormUtils::formBottom($form_submitted, $form_is_disabled);
            }
        }
        if (!$is_query) {
            $form_text .= Html::hidden('wpStarttime', wfTimestampNow());
            $article = new Article($this->mPageTitle, 0);
            $form_text .= Html::hidden('wpEdittime', $article->getTimestamp());
            $form_text .= Html::hidden('wpEditToken', $wgUser->getEditToken());
        }
        $form_text .= "\t</form>\n";
        $wgParser->replaceLinkHolders($form_text);
        Hooks::run('sfRenderingEnd', array(&$form_text));
        // Add general Javascript code.
        $javascript_text = "";
        Hooks::run('sfAddJavascriptToForm', array(&$javascript_text));
        // Send the autocomplete values to the browser, along with the
        // mappings of which values should apply to which fields.
        // If doing a replace, the page text is actually the modified
        // original page.
        if ($wgRequest->getCheck('partial')) {
            $page_text = $existing_page_content;
        }
        if (!$is_embedded) {
            $form_page_title = $wgParser->recursiveTagParse(str_replace("{{!}}", "|", $form_page_title));
        } else {
            $form_page_title = null;
        }
        // If the form has already been submitted, i.e. this is just
        // the redirect page, get rid of all the Javascript, to avoid
        // JS errors.
        if ($form_submitted) {
            $javascript_text = '';
        }
        //		$wgParser = $oldParser;
        return array($form_text, $javascript_text, $page_text, $form_page_title, $generated_page_name);
    }
 protected function appendGeneralInfo($property)
 {
     global $wgContLang, $wgDisableLangConversion, $wgDisableTitleConversion;
     $data = array();
     $mainPage = Title::newMainPage();
     $data['mainpage'] = $mainPage->getPrefixedText();
     $data['base'] = wfExpandUrl($mainPage->getFullURL(), PROTO_CURRENT);
     $data['sitename'] = $GLOBALS['wgSitename'];
     // wgLogo can either be a relative or an absolute path
     // make sure we always return an absolute path
     $data['logo'] = wfExpandUrl($GLOBALS['wgLogo'], PROTO_RELATIVE);
     $data['generator'] = "MediaWiki {$GLOBALS['wgVersion']}";
     $data['phpversion'] = phpversion();
     $data['phpsapi'] = PHP_SAPI;
     $data['dbtype'] = $GLOBALS['wgDBtype'];
     $data['dbversion'] = $this->getDB()->getServerVersion();
     $allowFrom = array('');
     $allowException = true;
     if (!$GLOBALS['wgAllowExternalImages']) {
         if ($GLOBALS['wgEnableImageWhitelist']) {
             $data['imagewhitelistenabled'] = '';
         }
         $allowFrom = $GLOBALS['wgAllowExternalImagesFrom'];
         $allowException = !empty($allowFrom);
     }
     if ($allowException) {
         $data['externalimages'] = (array) $allowFrom;
         $this->getResult()->setIndexedTagName($data['externalimages'], 'prefix');
     }
     if (!$wgDisableLangConversion) {
         $data['langconversion'] = '';
     }
     if (!$wgDisableTitleConversion) {
         $data['titleconversion'] = '';
     }
     if ($wgContLang->linkPrefixExtension()) {
         $linkPrefixCharset = $wgContLang->linkPrefixCharset();
         $data['linkprefixcharset'] = $linkPrefixCharset;
         // For backwards compatability
         $data['linkprefix'] = "/^((?>.*[^{$linkPrefixCharset}]|))(.+)\$/sDu";
     } else {
         $data['linkprefixcharset'] = '';
         $data['linkprefix'] = '';
     }
     $linktrail = $wgContLang->linkTrail();
     if ($linktrail) {
         $data['linktrail'] = $linktrail;
     } else {
         $data['linktrail'] = '';
     }
     $git = SpecialVersion::getGitHeadSha1($GLOBALS['IP']);
     if ($git) {
         $data['git-hash'] = $git;
     } else {
         $svn = SpecialVersion::getSvnRevision($GLOBALS['IP']);
         if ($svn) {
             $data['rev'] = $svn;
         }
     }
     // 'case-insensitive' option is reserved for future
     $data['case'] = $GLOBALS['wgCapitalLinks'] ? 'first-letter' : 'case-sensitive';
     $data['lang'] = $GLOBALS['wgLanguageCode'];
     $fallbacks = array();
     foreach ($wgContLang->getFallbackLanguages() as $code) {
         $fallbacks[] = array('code' => $code);
     }
     $data['fallback'] = $fallbacks;
     $this->getResult()->setIndexedTagName($data['fallback'], 'lang');
     if ($wgContLang->hasVariants()) {
         $variants = array();
         foreach ($wgContLang->getVariants() as $code) {
             $variants[] = array('code' => $code, 'name' => $wgContLang->getVariantname($code));
         }
         $data['variants'] = $variants;
         $this->getResult()->setIndexedTagName($data['variants'], 'lang');
     }
     if ($wgContLang->isRTL()) {
         $data['rtl'] = '';
     }
     $data['fallback8bitEncoding'] = $wgContLang->fallback8bitEncoding();
     if (wfReadOnly()) {
         $data['readonly'] = '';
         $data['readonlyreason'] = wfReadOnlyReason();
     }
     if ($GLOBALS['wgEnableWriteAPI']) {
         $data['writeapi'] = '';
     }
     $tz = $GLOBALS['wgLocaltimezone'];
     $offset = $GLOBALS['wgLocalTZoffset'];
     if (is_null($tz)) {
         $tz = 'UTC';
         $offset = 0;
     } elseif (is_null($offset)) {
         $offset = 0;
     }
     $data['timezone'] = $tz;
     $data['timeoffset'] = intval($offset);
     $data['articlepath'] = $GLOBALS['wgArticlePath'];
     $data['scriptpath'] = $GLOBALS['wgScriptPath'];
     $data['script'] = $GLOBALS['wgScript'];
     $data['variantarticlepath'] = $GLOBALS['wgVariantArticlePath'];
     $data['server'] = $GLOBALS['wgServer'];
     $data['wikiid'] = wfWikiID();
     $data['time'] = wfTimestamp(TS_ISO_8601, time());
     if ($GLOBALS['wgMiserMode']) {
         $data['misermode'] = '';
     }
     $data['maxuploadsize'] = UploadBase::getMaxUploadSize();
     $data['thumblimits'] = $GLOBALS['wgThumbLimits'];
     $this->getResult()->setIndexedTagName($data['thumblimits'], 'limit');
     $data['imagelimits'] = array();
     $this->getResult()->setIndexedTagName($data['imagelimits'], 'limit');
     foreach ($GLOBALS['wgImageLimits'] as $k => $limit) {
         $data['imagelimits'][$k] = array('width' => $limit[0], 'height' => $limit[1]);
     }
     if (!empty($GLOBALS['wgFavicon'])) {
         // wgFavicon can either be a relative or an absolute path
         // make sure we always return an absolute path
         $data['favicon'] = wfExpandUrl($GLOBALS['wgFavicon'], PROTO_RELATIVE);
     }
     wfRunHooks('APIQuerySiteInfoGeneralInfo', array($this, &$data));
     return $this->getResult()->addValue('query', $property, $data);
 }
 private function sendMessage($mSender, $mText, $formData)
 {
     global $wgExternalSharedDB, $wgStatsDB, $wgUser;
     $result = array('msgId' => null, 'errMsg' => null);
     $dbInsertResult = false;
     $mWikiId = null;
     $mLang = $formData['mLang'];
     if (is_array($mLang)) {
         $mLang = implode(',', $mLang);
     }
     $mRecipientId = $formData['sendModeUsers'] != 'USER' ? null : $wgUser->idFromName($formData['userName']);
     $mWikiName = $formData['wikiName'];
     $mRecipientName = $formData['userName'];
     $mGroupName = $formData['groupName'] == '' ? $formData['groupNameS'] : $formData['groupName'];
     $mSendModeWikis = $formData['sendModeWikis'];
     $mSendModeUsers = $formData['sendModeUsers'];
     $mHubId = $formData['hubId'];
     $mClusterId = $formData['clusterId'];
     $mUserNamesArr = array_unique(explode("\n", $formData['listUserNames']));
     $mWikiNamesArr = array_unique(explode("\n", $formData['listWikiNames']));
     //remove unnecessary data
     switch ($mSendModeWikis) {
         case 'ALL':
             $mWikiName = '';
             $mHubId = null;
             $mClusterId = null;
             break;
         case 'HUB':
             $mWikiName = '';
             $mClusterId = null;
             break;
         case 'CLUSTER':
             $mWikiName = '';
             $mHubId = null;
             break;
         case 'WIKI':
             $mHubId = null;
             $mClusterId = null;
             break;
         case 'WIKIS':
             $mWikiName = count($mWikiNamesArr) . ' wikis';
             $mHubId = null;
             $mClusterId = null;
             break;
         case 'CREATED':
             $mWikiName = MSG_WIKI_CREATION_DATE;
             $mHubId = null;
             $mClusterId = null;
             break;
     }
     switch ($mSendModeUsers) {
         case 'ALL':
         case 'ACTIVE':
             $mRecipientName = '';
             $mGroupName = '';
             break;
         case 'GROUP':
             $mRecipientName = '';
             break;
         case 'USER':
             $mGroupName = '';
             $mLang = MSG_LANG_ALL;
             break;
         case 'USERS':
             $mRecipientName = count($mUserNamesArr) . ' users';
             $mGroupName = '';
             $mLang = MSG_LANG_ALL;
             break;
         case 'ANONS':
             $mRecipientName = MSG_RECIPIENT_ANON;
             $mGroupName = '';
             break;
         case 'REGISTRATION':
             $mRecipientName = '';
             $mGroupName = '';
             break;
         case 'EDITCOUNT':
             $mRecipientName = '';
             $mGroupName = '';
             break;
     }
     $sendToAll = $mSendModeWikis == 'ALL' && $mSendModeUsers == 'ALL';
     $tmpWikiName = false;
     if ($mSendModeWikis == 'WIKI' && $mWikiName != '') {
         $tmpWikiName = $mWikiName;
     }
     if ($tmpWikiName) {
         $wikiDomains = array('', '.wikia.com');
         foreach ($wikiDomains as $wikiDomain) {
             if (!is_null($mWikiId = WikiFactory::DomainToID($tmpWikiName . $wikiDomain))) {
                 break;
             }
         }
     }
     $validDateTime = true;
     if ($formData['expireTimeS'] !== '') {
         $timestamp = wfTimestamp(TS_UNIX, $formData['expireTimeS']);
         if (!$timestamp) {
             $validDateTime = false;
         }
         $mExpire = wfTimestamp(TS_DB, $timestamp);
     } else {
         //null => expire never
         $mExpire = $formData['expireTime'] != '0' ? date('Y-m-d H:i:s', strtotime(ctype_digit($formData['expireTime']) ? " +{$formData['expireTime']} day" : ' +' . substr($formData['expireTime'], 0, -1) . ' hour')) : null;
     }
     if ($mSendModeWikis === 'CREATED') {
         $timestamp = wfTimestamp(TS_UNIX, $formData['wikiCreationDateOne']);
         if (!$timestamp) {
             $validDateTime = false;
         }
         $formData['wikiCreationDateOne'] = wfTimestamp(TS_DB, $timestamp);
         if ($formData['wikiCreationDateOption'] === 'between') {
             if ($formData['wikiCreationDateTwo'] !== '') {
                 $timestamp = wfTimestamp(TS_UNIX, $formData['wikiCreationDateTwo']);
                 if (!$timestamp) {
                     $validDateTime = false;
                 }
                 $formData['wikiCreationDateTwo'] = wfTimestamp(TS_DB, $timestamp);
             } else {
                 $validDateTime = false;
             }
         }
     }
     if ($mSendModeUsers === 'REGISTRATION') {
         $timestamp = wfTimestamp(TS_UNIX, $formData['registrationDateOne']);
         if (!$timestamp) {
             $validDateTime = false;
         }
         $formData['registrationDateOne'] = wfTimestamp(TS_MW, $timestamp);
         if ($formData['registrationDateOption'] === 'between') {
             if ($formData['registrationDateTwo'] !== '') {
                 $timestamp = wfTimestamp(TS_UNIX, $formData['registrationDateTwo']);
                 if (!$timestamp) {
                     $validDateTime = false;
                 }
                 $formData['registrationDateTwo'] = wfTimestamp(TS_MW, $timestamp);
             } else {
                 $validDateTime = false;
             }
         }
     }
     if (wfReadOnly()) {
         $reason = wfReadOnlyReason();
         $result['errMsg'] = wfMsg('readonlytext', $reason);
     } elseif ($mText == '') {
         $result['errMsg'] = wfMsg('swm-error-empty-message');
     } elseif (mb_strlen($mText) > 500) {
         $result['errMsg'] = wfMsg('swm-error-long-message');
     } elseif ($mSendModeWikis == 'WIKI' && is_null($mWikiId)) {
         //this wiki doesn't exist
         $result['errMsg'] = wfMsg('swm-error-no-such-wiki');
     } elseif ($mSendModeUsers == 'WIKIS' && empty($formData['listWikiNames'])) {
         $result['errMsg'] = wfMsg('swm-error-no-wiki-list');
     } elseif ($mSendModeUsers == 'USER' && !User::idFromName($mRecipientName)) {
         $result['errMsg'] = wfMsg('swm-error-no-such-user');
     } elseif ($mSendModeUsers == 'USERS' && empty($formData['listUserNames'])) {
         $result['errMsg'] = wfMsg('swm-error-no-user-list');
     } elseif (!$validDateTime) {
         $result['errMsg'] = wfMsg('swm-error-invalid-time');
     } elseif ($mSendModeUsers === 'REGISTRATION' && $formData['registrationDateOption'] === 'between' && $formData['registrationDateTwo'] <= $formData['registrationDateOne']) {
         $result['errMsg'] = wfMsg('swm-error-registered-tobeforefrom');
     } elseif ($mSendModeWikis === 'CREATED' && $formData['wikiCreationDateOption'] === 'between' && $formData['wikiCreationDateTwo'] <= $formData['wikiCreationDateOne']) {
         $result['errMsg'] = wfMsg('swm-error-created-tobeforefrom');
     } elseif ($mSendModeUsers === 'EDITCOUNT' && (!is_numeric($formData['editCountOne']) || $formData['editCountOption'] === 'between' && !is_numeric($formData['editCountTwo']))) {
         $result['errMsg'] = wfMsg('swm-error-editcount-notnumber');
     } elseif ($mSendModeUsers === 'EDITCOUNT' && $formData['editCountOption'] === 'between' && $formData['editCountTwo'] <= $formData['editCountOne']) {
         $result['errMsg'] = wfMsg('swm-error-editcount-tolessthanfrom');
     } else {
         global $wgParser, $wgUser;
         $title = Title::newFromText(uniqid('tmp'));
         $options = ParserOptions::newFromUser($wgUser);
         //Parse some wiki markup [eg. ~~~~]
         $mText = $wgParser->preSaveTransform($mText, $title, $wgUser, $options);
         $DB = wfGetDB(DB_MASTER, array(), $wgExternalSharedDB);
         $dbResult = (bool) $DB->Query('INSERT INTO ' . MSG_TEXT_DB . ' (msg_sender_id, msg_text, msg_mode, msg_expire, msg_recipient_name, msg_group_name, msg_wiki_name, msg_hub_id, msg_lang, msg_cluster_id)' . ' VALUES (' . $DB->AddQuotes($mSender->GetID()) . ', ' . $DB->AddQuotes($mText) . ', ' . ($sendToAll ? MSG_MODE_ALL : MSG_MODE_SELECTED) . ', ' . $DB->AddQuotes($mExpire) . ', ' . $DB->AddQuotes($mRecipientName) . ', ' . $DB->AddQuotes($mGroupName) . ', ' . $DB->AddQuotes($mWikiName) . ', ' . $DB->AddQuotes($mHubId) . ' , ' . $DB->AddQuotes($mLang) . ' , ' . $DB->AddQuotes($mClusterId) . ');', __METHOD__);
         if ($dbResult) {
             $dbInsertResult = true;
             $result['msgId'] = $DB->insertId();
             if (is_null($mWikiId)) {
                 $mWikiId = 0;
             }
             if ($mSendModeUsers == 'USER') {
                 if (!is_null($mRecipientId) && !is_null($result['msgId'])) {
                     $dbResult = (bool) $DB->Query('INSERT INTO ' . MSG_STATUS_DB . ' (msg_wiki_id, msg_recipient_id, msg_id, msg_status)' . ' VALUES (' . $DB->AddQuotes($mWikiId) . ', ' . $DB->AddQuotes($mRecipientId) . ', ' . $DB->AddQuotes($result['msgId']) . ', ' . MSG_STATUS_UNSEEN . ');', __METHOD__);
                     $dbInsertResult &= $dbResult;
                 }
             } elseif ($mSendModeWikis != 'WIKIS' && $mSendModeWikis != 'CREATED' && $mSendModeUsers == 'ANONS') {
                 if (!is_null($result['msgId'])) {
                     $dbResult = (bool) $DB->query('INSERT INTO ' . MSG_STATUS_DB . ' (msg_wiki_id, msg_recipient_id, msg_id, msg_status)' . ' VALUES (' . $DB->addQuotes($mWikiId) . ', 0, ' . $DB->addQuotes($result['msgId']) . ', ' . MSG_STATUS_UNSEEN . ');', __METHOD__);
                     $dbInsertResult &= $dbResult;
                 }
             } elseif ($mSendModeUsers == 'USERS') {
                 $oTask = new SWMSendToGroupTask();
                 $oTask->createTask(array('messageId' => $result['msgId'], 'sendModeWikis' => $mSendModeWikis, 'sendModeUsers' => $mSendModeUsers, 'wikiName' => $mWikiName, 'groupName' => $mGroupName, 'userNames' => $mUserNamesArr, 'senderId' => $mSender->GetID(), 'senderName' => $mSender->GetName(), 'hubId' => $mHubId, 'clusterId' => $mClusterId), TASK_QUEUED, BatchTask::PRIORITY_HIGH);
                 $result['taskId'] = $oTask->getID();
             } else {
                 switch ($mSendModeWikis) {
                     case 'ALL':
                         switch ($mSendModeUsers) {
                             case 'ALL':
                                 break;
                             case 'ACTIVE':
                             case 'GROUP':
                                 //add task to TaskManager
                                 $oTask = new SWMSendToGroupTask();
                                 $oTask->createTask(array('messageId' => $result['msgId'], 'sendModeWikis' => $mSendModeWikis, 'sendModeUsers' => $mSendModeUsers, 'wikiName' => $mWikiName, 'groupName' => $mGroupName, 'senderId' => $mSender->GetID(), 'senderName' => $mSender->GetName(), 'hubId' => $mHubId, 'clusterId' => $mClusterId), TASK_QUEUED, BatchTask::PRIORITY_HIGH);
                                 $result['taskId'] = $oTask->getID();
                                 break;
                             case 'REGISTRATION':
                                 //add task to TaskManager
                                 $oTask = new SWMSendToGroupTask();
                                 $oTask->createTask(array('messageId' => $result['msgId'], 'sendModeWikis' => $mSendModeWikis, 'sendModeUsers' => $mSendModeUsers, 'wikiName' => $mWikiName, 'groupName' => $mGroupName, 'regOption' => $formData['registrationDateOption'], 'regStartDate' => $formData['registrationDateOne'], 'regEndDate' => $formData['registrationDateTwo'], 'senderId' => $mSender->getID(), 'senderName' => $mSender->getName(), 'hubId' => $mHubId, 'clusterId' => $mClusterId), TASK_QUEUED, BatchTask::PRIORITY_HIGH);
                                 $result['taskId'] = $oTask->getID();
                                 break;
                             case 'EDITCOUNT':
                                 //add task to TaskManager
                                 $oTask = new SWMSendToGroupTask();
                                 $oTask->createTask(array('messageId' => $result['msgId'], 'sendModeWikis' => $mSendModeWikis, 'sendModeUsers' => $mSendModeUsers, 'wikiName' => $mWikiName, 'groupName' => $mGroupName, 'editCountOption' => $formData['editCountOption'], 'editCountStart' => $formData['editCountOne'], 'editCountEnd' => $formData['editCountTwo'], 'senderId' => $mSender->getID(), 'senderName' => $mSender->getName(), 'hubId' => $mHubId, 'clusterId' => $mClusterId), TASK_QUEUED, BatchTask::PRIORITY_HIGH);
                                 $result['taskId'] = $oTask->getID();
                                 break;
                         }
                         break;
                     case 'HUB':
                         switch ($mSendModeUsers) {
                             case 'ALL':
                             case 'ACTIVE':
                             case 'GROUP':
                                 //add task to TaskManager
                                 $oTask = new SWMSendToGroupTask();
                                 $oTask->createTask(array('messageId' => $result['msgId'], 'sendModeWikis' => $mSendModeWikis, 'sendModeUsers' => $mSendModeUsers, 'wikiName' => $mWikiName, 'groupName' => $mGroupName, 'senderId' => $mSender->GetID(), 'senderName' => $mSender->GetName(), 'hubId' => $mHubId, 'clusterId' => $mClusterId), TASK_QUEUED, BatchTask::PRIORITY_HIGH);
                                 $result['taskId'] = $oTask->getID();
                                 break;
                         }
                         break;
                     case 'CLUSTER':
                         switch ($mSendModeUsers) {
                             case 'ALL':
                             case 'ACTIVE':
                             case 'GROUP':
                                 //add task to TaskManager
                                 $oTask = new SWMSendToGroupTask();
                                 $oTask->createTask(array('messageId' => $result['msgId'], 'sendModeWikis' => $mSendModeWikis, 'sendModeUsers' => $mSendModeUsers, 'wikiName' => $mWikiName, 'groupName' => $mGroupName, 'senderId' => $mSender->GetID(), 'senderName' => $mSender->GetName(), 'hubId' => $mHubId, 'clusterId' => $mClusterId), TASK_QUEUED, BatchTask::PRIORITY_HIGH);
                                 $result['taskId'] = $oTask->getID();
                                 break;
                         }
                         break;
                     case 'WIKI':
                         switch ($mSendModeUsers) {
                             case 'ALL':
                             case 'ACTIVE':
                                 $dbr = wfGetDB(DB_SLAVE, array(), $wgStatsDB);
                                 $dbResult = $dbr->select(array('`specials`.`events_local_users`'), array('user_id'), array('wiki_id' => $mWikiId), __METHOD__, array('DISTINCT'));
                                 $activeUsers = array();
                                 while ($oMsg = $dbr->FetchObject($dbResult)) {
                                     $activeUsers[] = $oMsg->user_id;
                                 }
                                 if ($dbResult !== false) {
                                     $dbr->FreeResult($dbResult);
                                 }
                                 if (!$DB) {
                                     $DB = wfGetDB(DB_MASTER, array(), $wgExternalSharedDB);
                                 }
                                 $sqlValues = array();
                                 foreach ($activeUsers as $activeUser) {
                                     $sqlValues[] = "({$mWikiId}, {$activeUser}, {$result['msgId']}, " . MSG_STATUS_UNSEEN . ')';
                                 }
                                 if (count($sqlValues)) {
                                     $dbResult = (bool) $DB->Query('INSERT INTO ' . MSG_STATUS_DB . ' (msg_wiki_id, msg_recipient_id, msg_id, msg_status)' . ' VALUES ' . implode(',', $sqlValues) . ';', __METHOD__);
                                     $dbInsertResult &= $dbResult;
                                 }
                                 break;
                             case 'GROUP':
                                 //add task to TaskManager
                                 $oTask = new SWMSendToGroupTask();
                                 $oTask->createTask(array('messageId' => $result['msgId'], 'sendModeWikis' => $mSendModeWikis, 'sendModeUsers' => $mSendModeUsers, 'wikiName' => $mWikiName, 'groupName' => $mGroupName, 'senderId' => $mSender->GetID(), 'senderName' => $mSender->GetName(), 'hubId' => $mHubId, 'clusterId' => $mClusterId), TASK_QUEUED, BatchTask::PRIORITY_HIGH);
                                 $result['taskId'] = $oTask->getID();
                                 break;
                             case 'EDITCOUNT':
                                 //add task to TaskManager
                                 $oTask = new SWMSendToGroupTask();
                                 $oTask->createTask(array('messageId' => $result['msgId'], 'sendModeWikis' => $mSendModeWikis, 'sendModeUsers' => $mSendModeUsers, 'wikiName' => $mWikiName, 'groupName' => $mGroupName, 'editCountOption' => $formData['editCountOption'], 'editCountStart' => $formData['editCountOne'], 'editCountEnd' => $formData['editCountTwo'], 'senderId' => $mSender->getID(), 'senderName' => $mSender->getName(), 'hubId' => $mHubId, 'clusterId' => $mClusterId), TASK_QUEUED, BatchTask::PRIORITY_HIGH);
                                 $result['taskId'] = $oTask->getID();
                                 break;
                         }
                         break;
                     case 'WIKIS':
                         switch ($mSendModeUsers) {
                             case 'ALL':
                             case 'ACTIVE':
                             case 'GROUP':
                             case 'EDITCOUNT':
                             case 'ANONS':
                                 //add task to TaskManager
                                 $oTask = new SWMSendToGroupTask();
                                 $oTask->createTask(array('messageId' => $result['msgId'], 'sendModeWikis' => $mSendModeWikis, 'sendModeUsers' => $mSendModeUsers, 'wikiName' => $mWikiName, 'wikiNames' => $mWikiNamesArr, 'groupName' => $mGroupName, 'editCountOption' => $formData['editCountOption'], 'editCountStart' => $formData['editCountOne'], 'editCountEnd' => $formData['editCountTwo'], 'senderId' => $mSender->GetID(), 'senderName' => $mSender->GetName(), 'hubId' => $mHubId, 'clusterId' => $mClusterId), TASK_QUEUED, BatchTask::PRIORITY_HIGH);
                                 $result['taskId'] = $oTask->getID();
                                 break;
                         }
                         break;
                     case 'CREATED':
                         switch ($mSendModeUsers) {
                             case 'ALL':
                             case 'ACTIVE':
                             case 'GROUP':
                             case 'EDITCOUNT':
                             case 'ANONS':
                                 //add task to TaskManager
                                 $oTask = new SWMSendToGroupTask();
                                 $oTask->createTask(array('messageId' => $result['msgId'], 'sendModeWikis' => $mSendModeWikis, 'sendModeUsers' => $mSendModeUsers, 'wikiName' => $mWikiName, 'wikiNames' => $mWikiNamesArr, 'groupName' => $mGroupName, 'wcOption' => $formData['wikiCreationDateOption'], 'wcStartDate' => $formData['wikiCreationDateOne'], 'wcEndDate' => $formData['wikiCreationDateTwo'], 'editCountOption' => $formData['editCountOption'], 'editCountStart' => $formData['editCountOne'], 'editCountEnd' => $formData['editCountTwo'], 'senderId' => $mSender->GetID(), 'senderName' => $mSender->GetName(), 'hubId' => $mHubId, 'clusterId' => $mClusterId), TASK_QUEUED, BatchTask::PRIORITY_HIGH);
                                 $result['taskId'] = $oTask->getID();
                                 break;
                         }
                         break;
                 }
                 //end: switch ($mSendModeWikis)
             }
             //end: if ($mSendModeUsers == 'USER')
         }
         //end: if ($dbResult) => message sent
     }
     //end: else =? no errors
     wfDebug(basename(__FILE__) . ' || ' . __METHOD__ . " || SenderId=" . $mSender->GetID() . ", RecipientId={$mRecipientId}, Expire={$mExpire}, result=" . ($dbInsertResult ? 'true' : 'false') . "\n");
     return $result;
 }
Example #8
0
 /**
  * Helper function for readonly errors
  */
 public function dieReadOnly()
 {
     $parsed = $this->parseMsg(array('readonlytext'));
     $this->dieUsage($parsed['info'], $parsed['code'], 0, array('readonlyreason' => wfReadOnlyReason()));
 }
 protected function appendGeneralInfo($property)
 {
     global $wgContLang;
     $data = array();
     $mainPage = Title::newMainPage();
     $data['mainpage'] = $mainPage->getPrefixedText();
     $data['base'] = wfExpandUrl($mainPage->getFullUrl(), PROTO_CURRENT);
     $data['sitename'] = $GLOBALS['wgSitename'];
     $data['generator'] = "MediaWiki {$GLOBALS['wgVersion']}";
     $data['phpversion'] = phpversion();
     $data['phpsapi'] = php_sapi_name();
     $data['dbtype'] = $GLOBALS['wgDBtype'];
     $data['dbversion'] = $this->getDB()->getServerVersion();
     $svn = SpecialVersion::getSvnRevision($GLOBALS['IP']);
     if ($svn) {
         $data['rev'] = $svn;
     }
     // 'case-insensitive' option is reserved for future
     $data['case'] = $GLOBALS['wgCapitalLinks'] ? 'first-letter' : 'case-sensitive';
     if (isset($GLOBALS['wgRightsCode'])) {
         $data['rightscode'] = $GLOBALS['wgRightsCode'];
     }
     $data['rights'] = $GLOBALS['wgRightsText'];
     $data['lang'] = $GLOBALS['wgLanguageCode'];
     $fallbacks = array();
     foreach ($wgContLang->getFallbackLanguages() as $code) {
         $fallbacks[] = array('code' => $code);
     }
     $data['fallback'] = $fallbacks;
     $this->getResult()->setIndexedTagName($data['fallback'], 'lang');
     if ($wgContLang->isRTL()) {
         $data['rtl'] = '';
     }
     $data['fallback8bitEncoding'] = $wgContLang->fallback8bitEncoding();
     if (wfReadOnly()) {
         $data['readonly'] = '';
         $data['readonlyreason'] = wfReadOnlyReason();
     }
     if ($GLOBALS['wgEnableWriteAPI']) {
         $data['writeapi'] = '';
     }
     $tz = $GLOBALS['wgLocaltimezone'];
     $offset = $GLOBALS['wgLocalTZoffset'];
     if (is_null($tz)) {
         $tz = 'UTC';
         $offset = 0;
     } elseif (is_null($offset)) {
         $offset = 0;
     }
     $data['timezone'] = $tz;
     $data['timeoffset'] = intval($offset);
     $data['articlepath'] = $GLOBALS['wgArticlePath'];
     $data['scriptpath'] = $GLOBALS['wgScriptPath'];
     $data['script'] = $GLOBALS['wgScript'];
     $data['variantarticlepath'] = $GLOBALS['wgVariantArticlePath'];
     $data['server'] = $GLOBALS['wgServer'];
     $data['wikiid'] = wfWikiID();
     $data['time'] = wfTimestamp(TS_ISO_8601, time());
     if ($GLOBALS['wgMiserMode']) {
         $data['misermode'] = '';
     }
     wfRunHooks('APIQuerySiteInfoGeneralInfo', array($this, &$data));
     return $this->getResult()->addValue('query', $property, $data);
 }
Example #10
0
 /**
  * Update the article's restriction field, and leave a log entry.
  * This works for protection both existing and non-existing pages.
  *
  * @param array $limit Set of restriction keys
  * @param array $expiry Per restriction type expiration
  * @param int &$cascade Set to false if cascading protection isn't allowed.
  * @param string $reason
  * @param User $user The user updating the restrictions
  * @param string|string[] $tags Change tags to add to the pages and protection log entries
  *   ($user should be able to add the specified tags before this is called)
  * @return Status Status object; if action is taken, $status->value is the log_id of the
  *   protection log entry.
  */
 public function doUpdateRestrictions(array $limit, array $expiry, &$cascade, $reason, User $user, $tags = null)
 {
     global $wgCascadingRestrictionLevels, $wgContLang;
     if (wfReadOnly()) {
         return Status::newFatal('readonlytext', wfReadOnlyReason());
     }
     $this->loadPageData('fromdbmaster');
     $restrictionTypes = $this->mTitle->getRestrictionTypes();
     $id = $this->getId();
     if (!$cascade) {
         $cascade = false;
     }
     // Take this opportunity to purge out expired restrictions
     Title::purgeExpiredRestrictions();
     // @todo FIXME: Same limitations as described in ProtectionForm.php (line 37);
     // we expect a single selection, but the schema allows otherwise.
     $isProtected = false;
     $protect = false;
     $changed = false;
     $dbw = wfGetDB(DB_MASTER);
     foreach ($restrictionTypes as $action) {
         if (!isset($expiry[$action]) || $expiry[$action] === $dbw->getInfinity()) {
             $expiry[$action] = 'infinity';
         }
         if (!isset($limit[$action])) {
             $limit[$action] = '';
         } elseif ($limit[$action] != '') {
             $protect = true;
         }
         // Get current restrictions on $action
         $current = implode('', $this->mTitle->getRestrictions($action));
         if ($current != '') {
             $isProtected = true;
         }
         if ($limit[$action] != $current) {
             $changed = true;
         } elseif ($limit[$action] != '') {
             // Only check expiry change if the action is actually being
             // protected, since expiry does nothing on an not-protected
             // action.
             if ($this->mTitle->getRestrictionExpiry($action) != $expiry[$action]) {
                 $changed = true;
             }
         }
     }
     if (!$changed && $protect && $this->mTitle->areRestrictionsCascading() != $cascade) {
         $changed = true;
     }
     // If nothing has changed, do nothing
     if (!$changed) {
         return Status::newGood();
     }
     if (!$protect) {
         // No protection at all means unprotection
         $revCommentMsg = 'unprotectedarticle';
         $logAction = 'unprotect';
     } elseif ($isProtected) {
         $revCommentMsg = 'modifiedarticleprotection';
         $logAction = 'modify';
     } else {
         $revCommentMsg = 'protectedarticle';
         $logAction = 'protect';
     }
     // Truncate for whole multibyte characters
     $reason = $wgContLang->truncate($reason, 255);
     $logRelationsValues = [];
     $logRelationsField = null;
     $logParamsDetails = [];
     // Null revision (used for change tag insertion)
     $nullRevision = null;
     if ($id) {
         // Protection of existing page
         if (!Hooks::run('ArticleProtect', [&$this, &$user, $limit, $reason])) {
             return Status::newGood();
         }
         // Only certain restrictions can cascade...
         $editrestriction = isset($limit['edit']) ? [$limit['edit']] : $this->mTitle->getRestrictions('edit');
         foreach (array_keys($editrestriction, 'sysop') as $key) {
             $editrestriction[$key] = 'editprotected';
             // backwards compatibility
         }
         foreach (array_keys($editrestriction, 'autoconfirmed') as $key) {
             $editrestriction[$key] = 'editsemiprotected';
             // backwards compatibility
         }
         $cascadingRestrictionLevels = $wgCascadingRestrictionLevels;
         foreach (array_keys($cascadingRestrictionLevels, 'sysop') as $key) {
             $cascadingRestrictionLevels[$key] = 'editprotected';
             // backwards compatibility
         }
         foreach (array_keys($cascadingRestrictionLevels, 'autoconfirmed') as $key) {
             $cascadingRestrictionLevels[$key] = 'editsemiprotected';
             // backwards compatibility
         }
         // The schema allows multiple restrictions
         if (!array_intersect($editrestriction, $cascadingRestrictionLevels)) {
             $cascade = false;
         }
         // insert null revision to identify the page protection change as edit summary
         $latest = $this->getLatest();
         $nullRevision = $this->insertProtectNullRevision($revCommentMsg, $limit, $expiry, $cascade, $reason, $user);
         if ($nullRevision === null) {
             return Status::newFatal('no-null-revision', $this->mTitle->getPrefixedText());
         }
         $logRelationsField = 'pr_id';
         // Update restrictions table
         foreach ($limit as $action => $restrictions) {
             $dbw->delete('page_restrictions', ['pr_page' => $id, 'pr_type' => $action], __METHOD__);
             if ($restrictions != '') {
                 $cascadeValue = $cascade && $action == 'edit' ? 1 : 0;
                 $dbw->insert('page_restrictions', ['pr_id' => $dbw->nextSequenceValue('page_restrictions_pr_id_seq'), 'pr_page' => $id, 'pr_type' => $action, 'pr_level' => $restrictions, 'pr_cascade' => $cascadeValue, 'pr_expiry' => $dbw->encodeExpiry($expiry[$action])], __METHOD__);
                 $logRelationsValues[] = $dbw->insertId();
                 $logParamsDetails[] = ['type' => $action, 'level' => $restrictions, 'expiry' => $expiry[$action], 'cascade' => (bool) $cascadeValue];
             }
         }
         // Clear out legacy restriction fields
         $dbw->update('page', ['page_restrictions' => ''], ['page_id' => $id], __METHOD__);
         Hooks::run('NewRevisionFromEditComplete', [$this, $nullRevision, $latest, $user]);
         Hooks::run('ArticleProtectComplete', [&$this, &$user, $limit, $reason]);
     } else {
         // Protection of non-existing page (also known as "title protection")
         // Cascade protection is meaningless in this case
         $cascade = false;
         if ($limit['create'] != '') {
             $dbw->replace('protected_titles', [['pt_namespace', 'pt_title']], ['pt_namespace' => $this->mTitle->getNamespace(), 'pt_title' => $this->mTitle->getDBkey(), 'pt_create_perm' => $limit['create'], 'pt_timestamp' => $dbw->timestamp(), 'pt_expiry' => $dbw->encodeExpiry($expiry['create']), 'pt_user' => $user->getId(), 'pt_reason' => $reason], __METHOD__);
             $logParamsDetails[] = ['type' => 'create', 'level' => $limit['create'], 'expiry' => $expiry['create']];
         } else {
             $dbw->delete('protected_titles', ['pt_namespace' => $this->mTitle->getNamespace(), 'pt_title' => $this->mTitle->getDBkey()], __METHOD__);
         }
     }
     $this->mTitle->flushRestrictions();
     InfoAction::invalidateCache($this->mTitle);
     if ($logAction == 'unprotect') {
         $params = [];
     } else {
         $protectDescriptionLog = $this->protectDescriptionLog($limit, $expiry);
         $params = ['4::description' => $protectDescriptionLog, '5:bool:cascade' => $cascade, 'details' => $logParamsDetails];
     }
     // Update the protection log
     $logEntry = new ManualLogEntry('protect', $logAction);
     $logEntry->setTarget($this->mTitle);
     $logEntry->setComment($reason);
     $logEntry->setPerformer($user);
     $logEntry->setParameters($params);
     if (!is_null($nullRevision)) {
         $logEntry->setAssociatedRevId($nullRevision->getId());
     }
     $logEntry->setTags($tags);
     if ($logRelationsField !== null && count($logRelationsValues)) {
         $logEntry->setRelations([$logRelationsField => $logRelationsValues]);
     }
     $logId = $logEntry->insert();
     $logEntry->publish($logId);
     return Status::newGood($logId);
 }
    /**
     * Replace entire showEditForm, need to add our own textbox and stuff
     */
    function showEditForm($formCallback = null)
    {
        global $wgOut, $wgUser, $wgLang, $wgContLang, $wgMaxArticleSize, $wgTitle, $wgRequest;
        # If $wgTitle is null, that means we're in API mode.
        # Some hook probably called this function  without checking
        # for is_null($wgTitle) first. Bail out right here so we don't
        # do lots of work just to discard it right after.
        if (is_null($wgTitle)) {
            return;
        }
        $fname = 'EditPage::showEditForm';
        wfProfileIn($fname);
        $sk = $wgUser->getSkin();
        wfRunHooks('EditPage::showEditForm:initial', array(&$this));
        #need to parse the preview early so that we know which templates are used,
        #otherwise users with "show preview after edit box" will get a blank list
        #we parse this near the beginning so that setHeaders can do the title
        #setting work instead of leaving it in getPreviewText
        $previewOutput = '';
        if ($this->formtype == 'preview') {
            $previewOutput = $this->getPreviewText();
        }
        $this->setHeaders();
        # Enabled article-related sidebar, toplinks, etc.
        $wgOut->setArticleRelated(true);
        if ($this->isConflict) {
            $wgOut->wrapWikiMsg("<div class='mw-explainconflict'>\n\$1</div>", 'explainconflict');
            $this->textbox2 = $this->textbox1;
            $this->textbox1 = $this->getContent();
            $this->edittime = $this->mArticle->getTimestamp();
            # MeanEditor: too complicated for visual editing
            $this->noVisualEditor = false;
        } else {
            if ($this->section != '' && $this->section != 'new') {
                $matches = array();
                if (!$this->summary && !$this->preview && !$this->diff) {
                    preg_match("/^(=+)(.+)\\1/mi", $this->textbox1, $matches);
                    if (!empty($matches[2])) {
                        global $wgParser;
                        $this->summary = "/* " . $wgParser->stripSectionName(trim($matches[2])) . " */ ";
                    }
                }
            }
            if ($this->missingComment) {
                $wgOut->wrapWikiMsg('<div id="mw-missingcommenttext">$1</div>', 'missingcommenttext');
            }
            if ($this->missingSummary && $this->section != 'new') {
                $wgOut->wrapWikiMsg('<div id="mw-missingsummary">$1</div>', 'missingsummary');
            }
            if ($this->missingSummary && $this->section == 'new') {
                $wgOut->wrapWikiMsg('<div id="mw-missingcommentheader">$1</div>', 'missingcommentheader');
            }
            if ($this->hookError !== '') {
                $wgOut->addWikiText($this->hookError);
            }
            if (!$this->checkUnicodeCompliantBrowser()) {
                $wgOut->addWikiMsg('nonunicodebrowser');
            }
            if (isset($this->mArticle) && isset($this->mArticle->mRevision)) {
                // Let sysop know that this will make private content public if saved
                if (!$this->mArticle->mRevision->userCan(Revision::DELETED_TEXT)) {
                    $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1</div>\n", 'rev-deleted-text-permission');
                } else {
                    if ($this->mArticle->mRevision->isDeleted(Revision::DELETED_TEXT)) {
                        $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1</div>\n", 'rev-deleted-text-view');
                    }
                }
                if (!$this->mArticle->mRevision->isCurrent()) {
                    $this->mArticle->setOldSubtitle($this->mArticle->mRevision->getId());
                    $wgOut->addWikiMsg('editingold');
                }
            }
        }
        if (wfReadOnly()) {
            $wgOut->wrapWikiMsg("<div id=\"mw-read-only-warning\">\n\$1\n</div>", array('readonlywarning', wfReadOnlyReason()));
            # MeanEditor: visual editing makes no sense here
            $this->noVisualEditor = true;
        } elseif ($wgUser->isAnon() && $this->formtype != 'preview') {
            $wgOut->wrapWikiMsg('<div id="mw-anon-edit-warning">$1</div>', 'anoneditwarning');
        } else {
            if ($this->isCssJsSubpage) {
                # Check the skin exists
                if ($this->isValidCssJsSubpage) {
                    if ($this->formtype !== 'preview') {
                        $wgOut->addWikiMsg('usercssjsyoucanpreview');
                    }
                } else {
                    $wgOut->addWikiMsg('userinvalidcssjstitle', $wgTitle->getSkinFromCssJsSubpage());
                }
            }
        }
        $classes = array();
        // Textarea CSS
        if ($this->mTitle->getNamespace() == NS_MEDIAWIKI) {
        } elseif ($this->mTitle->isProtected('edit')) {
            # Is the title semi-protected?
            if ($this->mTitle->isSemiProtected()) {
                $noticeMsg = 'semiprotectedpagewarning';
                $classes[] = 'mw-textarea-sprotected';
            } else {
                # Then it must be protected based on static groups (regular)
                $noticeMsg = 'protectedpagewarning';
                $classes[] = 'mw-textarea-protected';
            }
            $wgOut->addHTML("<div class='mw-warning-with-logexcerpt'>\n");
            $wgOut->addWikiMsg($noticeMsg);
            LogEventsList::showLogExtract($wgOut, 'protect', $this->mTitle->getPrefixedText(), '', 1);
            $wgOut->addHTML("</div>\n");
        }
        if ($this->mTitle->isCascadeProtected()) {
            # Is this page under cascading protection from some source pages?
            list($cascadeSources, ) = $this->mTitle->getCascadeProtectionSources();
            $notice = "<div class='mw-cascadeprotectedwarning'>\$1\n";
            $cascadeSourcesCount = count($cascadeSources);
            if ($cascadeSourcesCount > 0) {
                # Explain, and list the titles responsible
                foreach ($cascadeSources as $page) {
                    $notice .= '* [[:' . $page->getPrefixedText() . "]]\n";
                }
            }
            $notice .= '</div>';
            $wgOut->wrapWikiMsg($notice, array('cascadeprotectedwarning', $cascadeSourcesCount));
        }
        if (!$this->mTitle->exists() && $this->mTitle->getRestrictions('create')) {
            $wgOut->wrapWikiMsg('<div class="mw-titleprotectedwarning">$1</div>', 'titleprotectedwarning');
        }
        if ($this->kblength === false) {
            # MeanEditor: the length will probably be different in HTML
            $this->kblength = (int) (strlen($this->textbox1) / 1024);
        }
        if ($this->tooBig || $this->kblength > $wgMaxArticleSize) {
            $wgOut->addHTML("<div class='error' id='mw-edit-longpageerror'>\n");
            $wgOut->addWikiMsg('longpageerror', $wgLang->formatNum($this->kblength), $wgLang->formatNum($wgMaxArticleSize));
            $wgOut->addHTML("</div>\n");
        } elseif ($this->kblength > 29) {
            $wgOut->addHTML("<div id='mw-edit-longpagewarning'>\n");
            $wgOut->addWikiMsg('longpagewarning', $wgLang->formatNum($this->kblength));
            $wgOut->addHTML("</div>\n");
        }
        $q = 'action=' . $this->action;
        #if ( "no" == $redirect ) { $q .= "&redirect=no"; }
        $action = $wgTitle->escapeLocalURL($q);
        $summary = wfMsg('summary');
        $subject = wfMsg('subject');
        $cancel = $sk->makeKnownLink($wgTitle->getPrefixedText(), wfMsgExt('cancel', array('parseinline')));
        $separator = wfMsgExt('pipe-separator', 'escapenoentities');
        $edithelpurl = Skin::makeInternalOrExternalUrl(wfMsgForContent('edithelppage'));
        $edithelp = '<a target="helpwindow" href="' . $edithelpurl . '">' . htmlspecialchars(wfMsg('edithelp')) . '</a> ' . htmlspecialchars(wfMsg('newwindow'));
        global $wgRightsText;
        if ($wgRightsText) {
            $copywarnMsg = array('copyrightwarning', '[[' . wfMsgForContent('copyrightpage') . ']]', $wgRightsText);
        } else {
            $copywarnMsg = array('copyrightwarning2', '[[' . wfMsgForContent('copyrightpage') . ']]');
        }
        /* MeanEditor: always disable the toolbar */
        if ($wgUser->getOption('showtoolbar') and !$this->isCssJsSubpage) {
            # prepare toolbar for edit buttons
            $toolbar = '';
        } else {
            $toolbar = '';
        }
        // activate checkboxes if user wants them to be always active
        if (!$this->preview && !$this->diff) {
            # Sort out the "watch" checkbox
            if ($wgUser->getOption('watchdefault')) {
                # Watch all edits
                $this->watchthis = true;
            } elseif ($wgUser->getOption('watchcreations') && !$this->mTitle->exists()) {
                # Watch creations
                $this->watchthis = true;
            } elseif ($this->mTitle->userIsWatching()) {
                # Already watched
                $this->watchthis = true;
            }
            # May be overriden by request parameters
            if ($wgRequest->getBool('watchthis')) {
                $this->watchthis = true;
            }
            if ($wgUser->getOption('minordefault')) {
                $this->minoredit = true;
            }
            # MeanEditor: User preference
            if ($wgUser->getOption('prefer_traditional_editor')) {
                $this->userWantsTraditionalEditor = true;
            }
        }
        $wgOut->addHTML($this->editFormPageTop);
        if ($wgUser->getOption('previewontop')) {
            $this->displayPreviewArea($previewOutput, true);
        }
        $wgOut->addHTML($this->editFormTextTop);
        # if this is a comment, show a subject line at the top, which is also the edit summary.
        # Otherwise, show a summary field at the bottom
        $summarytext = $wgContLang->recodeForEdit($this->summary);
        # If a blank edit summary was previously provided, and the appropriate
        # user preference is active, pass a hidden tag as wpIgnoreBlankSummary. This will stop the
        # user being bounced back more than once in the event that a summary
        # is not required.
        #####
        # For a bit more sophisticated detection of blank summaries, hash the
        # automatic one and pass that in the hidden field wpAutoSummary.
        $summaryhiddens = '';
        if ($this->missingSummary) {
            $summaryhiddens .= Xml::hidden('wpIgnoreBlankSummary', true);
        }
        $autosumm = $this->autoSumm ? $this->autoSumm : md5($this->summary);
        $summaryhiddens .= Xml::hidden('wpAutoSummary', $autosumm);
        if ($this->section == 'new') {
            $commentsubject = '';
            if (!$wgRequest->getBool('nosummary')) {
                # Add a class if 'missingsummary' is triggered to allow styling of the summary line
                $summaryClass = $this->missingSummary ? 'mw-summarymissed' : 'mw-summary';
                $commentsubject = Xml::tags('label', array('for' => 'wpSummary'), $subject);
                $commentsubject = Xml::tags('span', array('class' => $summaryClass, 'id' => "wpSummaryLabel"), $commentsubject);
                $commentsubject .= '&nbsp;';
                $commentsubject .= Xml::input('wpSummary', 60, $summarytext, array('id' => 'wpSummary', 'maxlength' => '200', 'tabindex' => '1'));
            }
            $editsummary = "<div class='editOptions'>\n";
            global $wgParser;
            $formattedSummary = wfMsgForContent('newsectionsummary', $wgParser->stripSectionName($this->summary));
            $subjectpreview = $summarytext && $this->preview ? "<div class=\"mw-summary-preview\">" . wfMsg('subject-preview') . $sk->commentBlock($formattedSummary, $this->mTitle, true) . "</div>\n" : '';
            $summarypreview = '';
        } else {
            $commentsubject = '';
            # Add a class if 'missingsummary' is triggered to allow styling of the summary line
            $summaryClass = $this->missingSummary ? 'mw-summarymissed' : 'mw-summary';
            $editsummary = Xml::tags('label', array('for' => 'wpSummary'), $summary);
            $editsummary = Xml::tags('span', array('class' => $summaryClass, 'id' => "wpSummaryLabel"), $editsummary) . ' ';
            $editsummary .= Xml::input('wpSummary', 60, $summarytext, array('id' => 'wpSummary', 'maxlength' => '200', 'tabindex' => '1'));
            // No idea where this is closed.
            $editsummary = Xml::openElement('div', array('class' => 'editOptions')) . $editsummary . '<br/>';
            $summarypreview = '';
            if ($summarytext && $this->preview) {
                $summarypreview = Xml::tags('div', array('class' => 'mw-summary-preview'), wfMsg('summary-preview') . $sk->commentBlock($this->summary, $this->mTitle));
            }
            $subjectpreview = '';
        }
        $commentsubject .= $summaryhiddens;
        # Set focus to the edit box on load, except on preview or diff, where it would interfere with the display
        if (!$this->preview && !$this->diff) {
            $wgOut->setOnloadHandler('document.editform.wpTextbox1.focus()');
        }
        $templates = $this->getTemplates();
        $formattedtemplates = $sk->formatTemplates($templates, $this->preview, $this->section != '');
        $hiddencats = $this->mArticle->getHiddenCategories();
        $formattedhiddencats = $sk->formatHiddenCategories($hiddencats);
        global $wgUseMetadataEdit;
        if ($wgUseMetadataEdit) {
            $metadata = $this->mMetaData;
            $metadata = htmlspecialchars($wgContLang->recodeForEdit($metadata));
            $top = wfMsgWikiHtml('metadata_help');
            /* ToDo: Replace with clean code */
            $ew = $wgUser->getOption('editwidth');
            if ($ew) {
                $ew = " style=\"width:100%\"";
            } else {
                $ew = '';
            }
            $cols = $wgUser->getIntOption('cols');
            /* /ToDo */
            $metadata = $top . "<textarea name='metadata' rows='3' cols='{$cols}'{$ew}>{$metadata}</textarea>";
        } else {
            $metadata = "";
        }
        $recreate = '';
        if ($this->wasDeletedSinceLastEdit()) {
            if ('save' != $this->formtype) {
                $wgOut->wrapWikiMsg("<div class='error mw-deleted-while-editing'>\n\$1</div>", 'deletedwhileediting');
            } else {
                // Hide the toolbar and edit area, user can click preview to get it back
                // Add an confirmation checkbox and explanation.
                $toolbar = '';
                $recreate = '<div class="mw-confirm-recreate">' . $wgOut->parse(wfMsg('confirmrecreate', $this->lastDelete->user_name, $this->lastDelete->log_comment)) . Xml::checkLabel(wfMsg('recreate'), 'wpRecreate', 'wpRecreate', false, array('title' => $sk->titleAttrib('recreate'), 'tabindex' => 1, 'id' => 'wpRecreate')) . '</div>';
            }
        }
        $tabindex = 2;
        $checkboxes = $this->getCheckboxes($tabindex, $sk, array('minor' => $this->minoredit, 'watch' => $this->watchthis, 'want_traditional_editor' => $this->userWantsTraditionalEditor));
        $checkboxhtml = implode($checkboxes, "\n");
        $buttons = $this->getEditButtons($tabindex);
        $buttonshtml = implode($buttons, "\n");
        $safemodehtml = $this->checkUnicodeCompliantBrowser() ? '' : Xml::hidden('safemode', '1');
        $wgOut->addHTML(<<<END
{$toolbar}
<form id="editform" name="editform" method="post" action="{$action}" enctype="multipart/form-data">
END
);
        if (is_callable($formCallback)) {
            call_user_func_array($formCallback, array(&$wgOut));
        }
        wfRunHooks('EditPage::showEditForm:fields', array(&$this, &$wgOut));
        // Put these up at the top to ensure they aren't lost on early form submission
        $this->showFormBeforeText();
        $wgOut->addHTML(<<<END
{$recreate}
{$commentsubject}
{$subjectpreview}
{$this->editFormTextBeforeContent}
END
);
        if ($this->isConflict || $this->diff) {
            # MeanEditor: should be redundant, but let's be sure
            $this->noVisualEditor = true;
        }
        # MeanEditor: also apply htmlspecialchars? See $encodedtext
        $html_text = $this->safeUnicodeOutput($this->textbox1);
        if (!($this->noVisualEditor || $this->userWantsTraditionalEditor)) {
            $this->noVisualEditor = wfRunHooks('EditPage::wiki2html', array($this->mArticle, $wgUser, &$this, &$html_text));
        }
        if (!$this->noVisualEditor && !$this->userWantsTraditionalEditor) {
            $this->noVisualEditor = wfRunHooks('EditPage::showBox', array(&$this, $html_text, $rows, $cols, $ew));
        }
        if (!$this->noVisualEditor && !$this->userWantsTraditionalEditor) {
            $wgOut->addHTML("<input type='hidden' value=\"0\" name=\"wpNoVisualEditor\" />\n");
        } else {
            $wgOut->addHTML("<input type='hidden' value=\"1\" name=\"wpNoVisualEditor\" />\n");
            $this->showTextbox1($classes);
        }
        $wgOut->wrapWikiMsg("<div id=\"editpage-copywarn\">\n\$1\n</div>", $copywarnMsg);
        $wgOut->addHTML(<<<END
{$this->editFormTextAfterWarn}
{$metadata}
{$editsummary}
{$summarypreview}
{$checkboxhtml}
{$safemodehtml}
END
);
        $wgOut->addHTML("<div class='editButtons'>\n{$buttonshtml}\n\t<span class='editHelp'>{$cancel}{$separator}{$edithelp}</span>\n</div><!-- editButtons -->\n</div><!-- editOptions -->");
        /**
         * To make it harder for someone to slip a user a page
         * which submits an edit form to the wiki without their
         * knowledge, a random token is associated with the login
         * session. If it's not passed back with the submission,
         * we won't save the page, or render user JavaScript and
         * CSS previews.
         *
         * For anon editors, who may not have a session, we just
         * include the constant suffix to prevent editing from
         * broken text-mangling proxies.
         */
        $token = htmlspecialchars($wgUser->editToken());
        $wgOut->addHTML("\n<input type='hidden' value=\"{$token}\" name=\"wpEditToken\" />\n");
        $this->showEditTools();
        $wgOut->addHTML(<<<END
{$this->editFormTextAfterTools}
<div class='templatesUsed'>
{$formattedtemplates}
</div>
<div class='hiddencats'>
{$formattedhiddencats}
</div>
END
);
        if ($this->isConflict && wfRunHooks('EditPageBeforeConflictDiff', array(&$this, &$wgOut))) {
            $wgOut->wrapWikiMsg('==$1==', "yourdiff");
            $de = new DifferenceEngine($this->mTitle);
            $de->setText($this->textbox2, $this->textbox1);
            $de->showDiff(wfMsg("yourtext"), wfMsg("storedversion"));
            $wgOut->wrapWikiMsg('==$1==', "yourtext");
            $this->showTextbox2();
        }
        $wgOut->addHTML($this->editFormTextBottom);
        $wgOut->addHTML("</form>\n");
        if (!$wgUser->getOption('previewontop')) {
            $this->displayPreviewArea($previewOutput, false);
        }
        wfProfileOut($fname);
    }
Example #12
0
 protected function showHeader()
 {
     global $wgOut, $wgUser, $wgMaxArticleSize, $wgLang;
     if ($this->mTitle->isTalkPage()) {
         $wgOut->addWikiMsg('talkpagetext');
     }
     # Optional notices on a per-namespace and per-page basis
     $editnotice_ns = 'editnotice-' . $this->mTitle->getNamespace();
     $editnotice_ns_message = wfMessage($editnotice_ns)->inContentLanguage();
     if ($editnotice_ns_message->exists()) {
         $wgOut->addWikiText($editnotice_ns_message->plain());
     }
     if (MWNamespace::hasSubpages($this->mTitle->getNamespace())) {
         $parts = explode('/', $this->mTitle->getDBkey());
         $editnotice_base = $editnotice_ns;
         while (count($parts) > 0) {
             $editnotice_base .= '-' . array_shift($parts);
             $editnotice_base_msg = wfMessage($editnotice_base)->inContentLanguage();
             if ($editnotice_base_msg->exists()) {
                 $wgOut->addWikiText($editnotice_base_msg->plain());
             }
         }
     } else {
         # Even if there are no subpages in namespace, we still don't want / in MW ns.
         $editnoticeText = $editnotice_ns . '-' . str_replace('/', '-', $this->mTitle->getDBkey());
         $editnoticeMsg = wfMessage($editnoticeText)->inContentLanguage();
         if ($editnoticeMsg->exists()) {
             $wgOut->addWikiText($editnoticeMsg->plain());
         }
     }
     if ($this->isConflict) {
         $wgOut->wrapWikiMsg("<div class='mw-explainconflict'>\n\$1\n</div>", 'explainconflict');
         $this->edittime = $this->mArticle->getTimestamp();
     } else {
         if ($this->section != '' && !$this->isSectionEditSupported()) {
             // We use $this->section to much before this and getVal('wgSection') directly in other places
             // at this point we can't reset $this->section to '' to fallback to non-section editing.
             // Someone is welcome to try refactoring though
             $wgOut->showErrorPage('sectioneditnotsupported-title', 'sectioneditnotsupported-text');
             return false;
         }
         if ($this->section != '' && $this->section != 'new') {
             if (!$this->summary && !$this->preview && !$this->diff) {
                 $sectionTitle = self::extractSectionTitle($this->textbox1);
                 if ($sectionTitle !== false) {
                     $this->summary = "/* {$sectionTitle} */ ";
                 }
             }
         }
         if ($this->missingComment) {
             $wgOut->wrapWikiMsg("<div id='mw-missingcommenttext'>\n\$1\n</div>", 'missingcommenttext');
         }
         if ($this->missingSummary && $this->section != 'new') {
             $wgOut->wrapWikiMsg("<div id='mw-missingsummary'>\n\$1\n</div>", 'missingsummary');
         }
         if ($this->missingSummary && $this->section == 'new') {
             $wgOut->wrapWikiMsg("<div id='mw-missingcommentheader'>\n\$1\n</div>", 'missingcommentheader');
         }
         if ($this->hookError !== '') {
             $wgOut->addWikiText($this->hookError);
         }
         if (!$this->checkUnicodeCompliantBrowser()) {
             $wgOut->addWikiMsg('nonunicodebrowser');
         }
         if ($this->section != 'new') {
             $revision = $this->mArticle->getRevisionFetched();
             if ($revision) {
                 // Let sysop know that this will make private content public if saved
                 if (!$revision->userCan(Revision::DELETED_TEXT)) {
                     $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1\n</div>\n", 'rev-deleted-text-permission');
                 } elseif ($revision->isDeleted(Revision::DELETED_TEXT)) {
                     $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1\n</div>\n", 'rev-deleted-text-view');
                 }
                 if (!$revision->isCurrent()) {
                     $this->mArticle->setOldSubtitle($revision->getId());
                     $wgOut->addWikiMsg('editingold');
                 }
             } elseif ($this->mTitle->exists()) {
                 // Something went wrong
                 $wgOut->wrapWikiMsg("<div class='errorbox'>\n\$1\n</div>\n", array('missing-article', $this->mTitle->getPrefixedText(), wfMsgNoTrans('missingarticle-rev', $this->oldid)));
             }
         }
     }
     if (wfReadOnly()) {
         $wgOut->wrapWikiMsg("<div id=\"mw-read-only-warning\">\n\$1\n</div>", array('readonlywarning', wfReadOnlyReason()));
     } elseif ($wgUser->isAnon()) {
         if ($this->formtype != 'preview') {
             $wgOut->wrapWikiMsg("<div id=\"mw-anon-edit-warning\">\n\$1</div>", 'anoneditwarning');
         } else {
             $wgOut->wrapWikiMsg("<div id=\"mw-anon-preview-warning\">\n\$1</div>", 'anonpreviewwarning');
         }
     } else {
         if ($this->isCssJsSubpage) {
             # Check the skin exists
             if ($this->isWrongCaseCssJsPage) {
                 $wgOut->wrapWikiMsg("<div class='error' id='mw-userinvalidcssjstitle'>\n\$1\n</div>", array('userinvalidcssjstitle', $this->mTitle->getSkinFromCssJsSubpage()));
             }
             if ($this->getTitle()->isSubpageOf($wgUser->getUserPage())) {
                 if ($this->formtype !== 'preview') {
                     if ($this->isCssSubpage) {
                         $wgOut->wrapWikiMsg("<div id='mw-usercssyoucanpreview'>\n\$1\n</div>", array('usercssyoucanpreview'));
                     }
                     if ($this->isJsSubpage) {
                         $wgOut->wrapWikiMsg("<div id='mw-userjsyoucanpreview'>\n\$1\n</div>", array('userjsyoucanpreview'));
                     }
                 }
             }
         }
     }
     if ($this->mTitle->getNamespace() != NS_MEDIAWIKI && $this->mTitle->isProtected('edit')) {
         # Is the title semi-protected?
         if ($this->mTitle->isSemiProtected()) {
             $noticeMsg = 'semiprotectedpagewarning';
         } else {
             # Then it must be protected based on static groups (regular)
             $noticeMsg = 'protectedpagewarning';
         }
         LogEventsList::showLogExtract($wgOut, 'protect', $this->mTitle, '', array('lim' => 1, 'msgKey' => array($noticeMsg)));
     }
     if ($this->mTitle->isCascadeProtected()) {
         # Is this page under cascading protection from some source pages?
         list($cascadeSources, ) = $this->mTitle->getCascadeProtectionSources();
         $notice = "<div class='mw-cascadeprotectedwarning'>\n\$1\n";
         $cascadeSourcesCount = count($cascadeSources);
         if ($cascadeSourcesCount > 0) {
             # Explain, and list the titles responsible
             foreach ($cascadeSources as $page) {
                 $notice .= '* [[:' . $page->getPrefixedText() . "]]\n";
             }
         }
         $notice .= '</div>';
         $wgOut->wrapWikiMsg($notice, array('cascadeprotectedwarning', $cascadeSourcesCount));
     }
     if (!$this->mTitle->exists() && $this->mTitle->getRestrictions('create')) {
         LogEventsList::showLogExtract($wgOut, 'protect', $this->mTitle, '', array('lim' => 1, 'showIfEmpty' => false, 'msgKey' => array('titleprotectedwarning'), 'wrap' => "<div class=\"mw-titleprotectedwarning\">\n\$1</div>"));
     }
     if ($this->kblength === false) {
         $this->kblength = (int) (strlen($this->textbox1) / 1024);
     }
     if ($this->tooBig || $this->kblength > $wgMaxArticleSize) {
         $wgOut->wrapWikiMsg("<div class='error' id='mw-edit-longpageerror'>\n\$1\n</div>", array('longpageerror', $wgLang->formatNum($this->kblength), $wgLang->formatNum($wgMaxArticleSize)));
     } else {
         if (!wfMessage('longpage-hint')->isDisabled()) {
             $wgOut->wrapWikiMsg("<div id='mw-edit-longpage-hint'>\n\$1\n</div>", array('longpage-hint', $wgLang->formatSize(strlen($this->textbox1)), strlen($this->textbox1)));
         }
     }
 }
Example #13
0
 /**
  * Translates an EditPage error code into a corresponding message ID
  * @param $error The error code
  * @return String
  */
 public static function processEditErrors($error)
 {
     switch ($error) {
         case EditPage::AS_SUCCESS_NEW_ARTICLE:
         case EditPage::AS_SUCCESS_UPDATE:
             return null;
         case EditPage::AS_SPAM_ERROR:
             return 'spamprotectiontext';
         case EditPage::AS_BLOCKED_PAGE_FOR_USER:
             return 'blockedtitle';
         case EditPage::AS_IMAGE_REDIRECT_ANON:
             return 'uploadnologin';
         case EditPage::AS_READ_ONLY_PAGE_ANON:
             return 'loginreqtitle';
         case EditPage::AS_READ_ONLY_PAGE_LOGGED:
         case EditPage::AS_READ_ONLY_PAGE:
             return array('readonlytext', array(wfReadOnlyReason()));
         case EditPage::AS_RATE_LIMITED:
             return 'actionthrottledtext';
         case EditPage::AS_NO_CREATE_PERMISSION:
             return 'nocreatetext';
         case EditPage::AS_BLANK_ARTICLE:
             return 'autoedit-blankpage';
         case EditPage::AS_IMAGE_REDIRECT_LOGGED:
             return 'badaccess';
         case EditPage::AS_HOOK_ERROR_EXPECTED:
         case EditPage::AS_HOOK_ERROR:
             return 'sf_formedit_hookerror';
         case EditPage::AS_CONFLICT_DETECTED:
             return 'editconflict';
         case EditPage::AS_CONTENT_TOO_BIG:
         case EditPage::AS_ARTICLE_WAS_DELETED:
         case EditPage::AS_SUMMARY_NEEDED:
         case EditPage::AS_TEXTBOX_EMPTY:
         case EditPage::AS_MAX_ARTICLE_SIZE_EXCEEDED:
         case EditPage::AS_END:
         case EditPage::AS_FILTERING:
         default:
             return array('internalerror_text', array($error));
     }
 }
 protected function showHeader()
 {
     global $wgOut, $wgUser, $wgMaxArticleSize, $wgLang;
     if ($this->isConflict) {
         $wgOut->wrapWikiMsg("<div class='mw-explainconflict'>\n\$1\n</div>", 'explainconflict');
         $this->edittime = $this->mArticle->getTimestamp();
     } else {
         if ($this->section != '' && !$this->isSectionEditSupported()) {
             // We use $this->section to much before this and getVal('wgSection') directly in other places
             // at this point we can't reset $this->section to '' to fallback to non-section editing.
             // Someone is welcome to try refactoring though
             $wgOut->showErrorPage('sectioneditnotsupported-title', 'sectioneditnotsupported-text');
             return false;
         }
         if ($this->section != '' && $this->section != 'new') {
             $matches = array();
             if (!$this->summary && !$this->preview && !$this->diff) {
                 preg_match("/^(=+)(.+)\\1/mi", $this->textbox1, $matches);
                 if (!empty($matches[2])) {
                     global $wgParser;
                     $this->summary = "/* " . $wgParser->stripSectionName(trim($matches[2])) . " */ ";
                 }
             }
         }
         if ($this->missingComment) {
             $wgOut->wrapWikiMsg("<div id='mw-missingcommenttext'>\n\$1\n</div>", 'missingcommenttext');
         }
         if ($this->missingSummary && $this->section != 'new') {
             $wgOut->wrapWikiMsg("<div id='mw-missingsummary'>\n\$1\n</div>", 'missingsummary');
         }
         if ($this->missingSummary && $this->section == 'new') {
             $wgOut->wrapWikiMsg("<div id='mw-missingcommentheader'>\n\$1\n</div>", 'missingcommentheader');
         }
         if ($this->hookError !== '') {
             $wgOut->addWikiText($this->hookError);
         }
         if (!$this->checkUnicodeCompliantBrowser()) {
             $wgOut->addWikiMsg('nonunicodebrowser');
         }
         if (isset($this->mArticle) && isset($this->mArticle->mRevision)) {
             // Let sysop know that this will make private content public if saved
             if (!$this->mArticle->mRevision->userCan(Revision::DELETED_TEXT)) {
                 $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1\n</div>\n", 'rev-deleted-text-permission');
             } elseif ($this->mArticle->mRevision->isDeleted(Revision::DELETED_TEXT)) {
                 $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1\n</div>\n", 'rev-deleted-text-view');
             }
             if (!$this->mArticle->mRevision->isCurrent()) {
                 $this->mArticle->setOldSubtitle($this->mArticle->mRevision->getId());
                 $wgOut->addWikiMsg('editingold');
             }
         }
     }
     if (wfReadOnly()) {
         $wgOut->wrapWikiMsg("<div id=\"mw-read-only-warning\">\n\$1\n</div>", array('readonlywarning', wfReadOnlyReason()));
     } elseif ($wgUser->isAnon()) {
         if ($this->formtype != 'preview') {
             $wgOut->wrapWikiMsg("<div id=\"mw-anon-edit-warning\">\n\$1</div>", 'anoneditwarning');
         } else {
             $wgOut->wrapWikiMsg("<div id=\"mw-anon-preview-warning\">\n\$1</div>", 'anonpreviewwarning');
         }
     } else {
         if ($this->isCssJsSubpage) {
             # Check the skin exists
             if ($this->isWrongCaseCssJsPage) {
                 $wgOut->wrapWikiMsg("<div class='error' id='mw-userinvalidcssjstitle'>\n\$1\n</div>", array('userinvalidcssjstitle', $this->getContextTitle()->getSkinFromCssJsSubpage()));
             }
             if ($this->formtype !== 'preview') {
                 if ($this->isCssSubpage) {
                     $wgOut->wrapWikiMsg("<div id='mw-usercssyoucanpreview'>\n\$1\n</div>", array('usercssyoucanpreview'));
                 }
                 if ($this->isJsSubpage) {
                     $wgOut->wrapWikiMsg("<div id='mw-userjsyoucanpreview'>\n\$1\n</div>", array('userjsyoucanpreview'));
                 }
             }
         }
     }
     if ($this->mTitle->getNamespace() != NS_MEDIAWIKI && $this->mTitle->isProtected('edit')) {
         # Is the title semi-protected?
         if ($this->mTitle->isSemiProtected()) {
             $noticeMsg = 'semiprotectedpagewarning';
         } else {
             # Then it must be protected based on static groups (regular)
             $noticeMsg = 'protectedpagewarning';
         }
         LogEventsList::showLogExtract($wgOut, 'protect', $this->mTitle->getPrefixedText(), '', array('lim' => 1, 'msgKey' => array($noticeMsg)));
     }
     if ($this->mTitle->isCascadeProtected()) {
         # Is this page under cascading protection from some source pages?
         list($cascadeSources, ) = $this->mTitle->getCascadeProtectionSources();
         $notice = "<div class='mw-cascadeprotectedwarning'>\n\$1\n";
         $cascadeSourcesCount = count($cascadeSources);
         if ($cascadeSourcesCount > 0) {
             # Explain, and list the titles responsible
             foreach ($cascadeSources as $page) {
                 $notice .= '* [[:' . $page->getPrefixedText() . "]]\n";
             }
         }
         $notice .= '</div>';
         $wgOut->wrapWikiMsg($notice, array('cascadeprotectedwarning', $cascadeSourcesCount));
     }
     if (!$this->mTitle->exists() && $this->mTitle->getRestrictions('create')) {
         LogEventsList::showLogExtract($wgOut, 'protect', $this->mTitle->getPrefixedText(), '', array('lim' => 1, 'showIfEmpty' => false, 'msgKey' => array('titleprotectedwarning'), 'wrap' => "<div class=\"mw-titleprotectedwarning\">\n\$1</div>"));
     }
     if ($this->kblength === false) {
         $this->kblength = (int) (strlen($this->textbox1) / 1024);
     }
     if ($this->tooBig || $this->kblength > $wgMaxArticleSize) {
         $wgOut->wrapWikiMsg("<div class='error' id='mw-edit-longpageerror'>\n\$1\n</div>", array('longpageerror', $wgLang->formatNum($this->kblength), $wgLang->formatNum($wgMaxArticleSize)));
     } else {
         if (!wfMessage('longpage-hint')->isDisabled()) {
             $wgOut->wrapWikiMsg("<div id='mw-edit-longpage-hint'>\n\$1\n</div>", array('longpage-hint', $wgLang->formatSize(strlen($this->textbox1)), strlen($this->textbox1)));
         }
     }
 }
 /**
  * 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);
         }
     }
 }
Example #16
0
 /**
  * Update the article's restriction field, and leave a log entry.
  * This works for protection both existing and non-existing pages.
  *
  * @param array $limit set of restriction keys
  * @param $reason String
  * @param &$cascade Integer. Set to false if cascading protection isn't allowed.
  * @param array $expiry per restriction type expiration
  * @param $user User The user updating the restrictions
  * @return Status
  */
 public function doUpdateRestrictions(array $limit, array $expiry, &$cascade, $reason, User $user)
 {
     global $wgContLang, $wgCascadingRestrictionLevels;
     if (wfReadOnly()) {
         return Status::newFatal('readonlytext', wfReadOnlyReason());
     }
     $restrictionTypes = $this->mTitle->getRestrictionTypes();
     $id = $this->getId();
     if (!$cascade) {
         $cascade = false;
     }
     // Take this opportunity to purge out expired restrictions
     Title::purgeExpiredRestrictions();
     // @todo FIXME: Same limitations as described in ProtectionForm.php (line 37);
     // we expect a single selection, but the schema allows otherwise.
     $isProtected = false;
     $protect = false;
     $changed = false;
     $dbw = wfGetDB(DB_MASTER);
     foreach ($restrictionTypes as $action) {
         if (!isset($expiry[$action])) {
             $expiry[$action] = $dbw->getInfinity();
         }
         if (!isset($limit[$action])) {
             $limit[$action] = '';
         } elseif ($limit[$action] != '') {
             $protect = true;
         }
         // Get current restrictions on $action
         $current = implode('', $this->mTitle->getRestrictions($action));
         if ($current != '') {
             $isProtected = true;
         }
         if ($limit[$action] != $current) {
             $changed = true;
         } elseif ($limit[$action] != '') {
             // Only check expiry change if the action is actually being
             // protected, since expiry does nothing on an not-protected
             // action.
             if ($this->mTitle->getRestrictionExpiry($action) != $expiry[$action]) {
                 $changed = true;
             }
         }
     }
     if (!$changed && $protect && $this->mTitle->areRestrictionsCascading() != $cascade) {
         $changed = true;
     }
     // If nothing has changed, do nothing
     if (!$changed) {
         return Status::newGood();
     }
     if (!$protect) {
         // No protection at all means unprotection
         $revCommentMsg = 'unprotectedarticle';
         $logAction = 'unprotect';
     } elseif ($isProtected) {
         $revCommentMsg = 'modifiedarticleprotection';
         $logAction = 'modify';
     } else {
         $revCommentMsg = 'protectedarticle';
         $logAction = 'protect';
     }
     $encodedExpiry = array();
     $protectDescription = '';
     # Some bots may parse IRC lines, which are generated from log entries which contain plain
     # protect description text. Keep them in old format to avoid breaking compatibility.
     # TODO: Fix protection log to store structured description and format it on-the-fly.
     $protectDescriptionLog = '';
     foreach ($limit as $action => $restrictions) {
         $encodedExpiry[$action] = $dbw->encodeExpiry($expiry[$action]);
         if ($restrictions != '') {
             $protectDescriptionLog .= $wgContLang->getDirMark() . "[{$action}={$restrictions}] (";
             # $action is one of $wgRestrictionTypes = array( 'create', 'edit', 'move', 'upload' ).
             # All possible message keys are listed here for easier grepping:
             # * restriction-create
             # * restriction-edit
             # * restriction-move
             # * restriction-upload
             $actionText = wfMessage('restriction-' . $action)->inContentLanguage()->text();
             # $restrictions is one of $wgRestrictionLevels = array( '', 'autoconfirmed', 'sysop' ),
             # with '' filtered out. All possible message keys are listed below:
             # * protect-level-autoconfirmed
             # * protect-level-sysop
             $restrictionsText = wfMessage('protect-level-' . $restrictions)->inContentLanguage()->text();
             if ($encodedExpiry[$action] != 'infinity') {
                 $expiryText = wfMessage('protect-expiring', $wgContLang->timeanddate($expiry[$action], false, false), $wgContLang->date($expiry[$action], false, false), $wgContLang->time($expiry[$action], false, false))->inContentLanguage()->text();
             } else {
                 $expiryText = wfMessage('protect-expiry-indefinite')->inContentLanguage()->text();
             }
             if ($protectDescription !== '') {
                 $protectDescription .= wfMessage('word-separator')->inContentLanguage()->text();
             }
             $protectDescription .= wfMessage('protect-summary-desc')->params($actionText, $restrictionsText, $expiryText)->inContentLanguage()->text();
             $protectDescriptionLog .= $expiryText . ') ';
         }
     }
     $protectDescriptionLog = trim($protectDescriptionLog);
     if ($id) {
         // Protection of existing page
         if (!wfRunHooks('ArticleProtect', array(&$this, &$user, $limit, $reason))) {
             return Status::newGood();
         }
         // Only certain restrictions can cascade... Otherwise, users who cannot normally protect pages
         // could "protect" them by transcluding them on protected pages they are allowed to edit.
         $editrestriction = isset($limit['edit']) ? array($limit['edit']) : $this->mTitle->getRestrictions('edit');
         $cascadingRestrictionLevels = $wgCascadingRestrictionLevels;
         if (in_array('sysop', $cascadingRestrictionLevels)) {
             $cascadingRestrictionLevels[] = 'protect';
             // backwards compatibility
         }
         // The schema allows multiple restrictions
         if (!array_intersect($editrestriction, $cascadingRestrictionLevels)) {
             $cascade = false;
         }
         // Update restrictions table
         foreach ($limit as $action => $restrictions) {
             if ($restrictions != '') {
                 $dbw->replace('page_restrictions', array(array('pr_page', 'pr_type')), array('pr_page' => $id, 'pr_type' => $action, 'pr_level' => $restrictions, 'pr_cascade' => $cascade && $action == 'edit' ? 1 : 0, 'pr_expiry' => $encodedExpiry[$action]), __METHOD__);
             } else {
                 $dbw->delete('page_restrictions', array('pr_page' => $id, 'pr_type' => $action), __METHOD__);
             }
         }
         // Prepare a null revision to be added to the history
         $editComment = $wgContLang->ucfirst(wfMessage($revCommentMsg, $this->mTitle->getPrefixedText())->inContentLanguage()->text());
         if ($reason) {
             $editComment .= wfMessage('colon-separator')->inContentLanguage()->text() . $reason;
         }
         if ($protectDescription) {
             $editComment .= wfMessage('word-separator')->inContentLanguage()->text();
             $editComment .= wfMessage('parentheses')->params($protectDescription)->inContentLanguage()->text();
         }
         if ($cascade) {
             $editComment .= wfMessage('word-separator')->inContentLanguage()->text();
             $editComment .= wfMessage('brackets')->params(wfMessage('protect-summary-cascade')->inContentLanguage()->text())->inContentLanguage()->text();
         }
         // Insert a null revision
         $nullRevision = Revision::newNullRevision($dbw, $id, $editComment, true);
         $nullRevId = $nullRevision->insertOn($dbw);
         $latest = $this->getLatest();
         // Update page record
         $dbw->update('page', array('page_touched' => $dbw->timestamp(), 'page_restrictions' => '', 'page_latest' => $nullRevId), array('page_id' => $id), __METHOD__);
         wfRunHooks('NewRevisionFromEditComplete', array($this, $nullRevision, $latest, $user));
         wfRunHooks('ArticleProtectComplete', array(&$this, &$user, $limit, $reason));
     } else {
         // Protection of non-existing page (also known as "title protection")
         // Cascade protection is meaningless in this case
         $cascade = false;
         if ($limit['create'] != '') {
             $dbw->replace('protected_titles', array(array('pt_namespace', 'pt_title')), array('pt_namespace' => $this->mTitle->getNamespace(), 'pt_title' => $this->mTitle->getDBkey(), 'pt_create_perm' => $limit['create'], 'pt_timestamp' => $dbw->encodeExpiry(wfTimestampNow()), 'pt_expiry' => $encodedExpiry['create'], 'pt_user' => $user->getId(), 'pt_reason' => $reason), __METHOD__);
         } else {
             $dbw->delete('protected_titles', array('pt_namespace' => $this->mTitle->getNamespace(), 'pt_title' => $this->mTitle->getDBkey()), __METHOD__);
         }
     }
     $this->mTitle->flushRestrictions();
     InfoAction::invalidateCache($this->mTitle);
     if ($logAction == 'unprotect') {
         $logParams = array();
     } else {
         $logParams = array($protectDescriptionLog, $cascade ? 'cascade' : '');
     }
     // Update the protection log
     $log = new LogPage('protect');
     $log->addEntry($logAction, $this->mTitle, trim($reason), $logParams, $user);
     return Status::newGood();
 }
Example #17
0
 /**
  * Auto-create an account, and log into that account
  * @param User $user User to auto-create
  * @param string $source What caused the auto-creation? This must be the ID
  *  of a PrimaryAuthenticationProvider or the constant self::AUTOCREATE_SOURCE_SESSION.
  * @param bool $login Whether to also log the user in
  * @return Status Good if user was created, Ok if user already existed, otherwise Fatal
  */
 public function autoCreateUser(User $user, $source, $login = true)
 {
     if ($source !== self::AUTOCREATE_SOURCE_SESSION && !$this->getAuthenticationProvider($source) instanceof PrimaryAuthenticationProvider) {
         throw new \InvalidArgumentException("Unknown auto-creation source: {$source}");
     }
     $username = $user->getName();
     // Try the local user from the slave DB
     $localId = User::idFromName($username);
     $flags = User::READ_NORMAL;
     // Fetch the user ID from the master, so that we don't try to create the user
     // when they already exist, due to replication lag
     // @codeCoverageIgnoreStart
     if (!$localId && wfGetLB()->getReaderIndex() != 0) {
         $localId = User::idFromName($username, User::READ_LATEST);
         $flags = User::READ_LATEST;
     }
     // @codeCoverageIgnoreEnd
     if ($localId) {
         $this->logger->debug(__METHOD__ . ': {username} already exists locally', ['username' => $username]);
         $user->setId($localId);
         $user->loadFromId($flags);
         if ($login) {
             $this->setSessionDataForUser($user);
         }
         $status = Status::newGood();
         $status->warning('userexists');
         return $status;
     }
     // Wiki is read-only?
     if (wfReadOnly()) {
         $this->logger->debug(__METHOD__ . ': denied by wfReadOnly(): {reason}', ['username' => $username, 'reason' => wfReadOnlyReason()]);
         $user->setId(0);
         $user->loadFromId();
         return Status::newFatal('readonlytext', wfReadOnlyReason());
     }
     // Check the session, if we tried to create this user already there's
     // no point in retrying.
     $session = $this->request->getSession();
     if ($session->get('AuthManager::AutoCreateBlacklist')) {
         $this->logger->debug(__METHOD__ . ': blacklisted in session {sessionid}', ['username' => $username, 'sessionid' => $session->getId()]);
         $user->setId(0);
         $user->loadFromId();
         $reason = $session->get('AuthManager::AutoCreateBlacklist');
         if ($reason instanceof StatusValue) {
             return Status::wrap($reason);
         } else {
             return Status::newFatal($reason);
         }
     }
     // Is the username creatable?
     if (!User::isCreatableName($username)) {
         $this->logger->debug(__METHOD__ . ': name "{username}" is not creatable', ['username' => $username]);
         $session->set('AuthManager::AutoCreateBlacklist', 'noname', 600);
         $user->setId(0);
         $user->loadFromId();
         return Status::newFatal('noname');
     }
     // Is the IP user able to create accounts?
     $anon = new User();
     if (!$anon->isAllowedAny('createaccount', 'autocreateaccount')) {
         $this->logger->debug(__METHOD__ . ': IP lacks the ability to create or autocreate accounts', ['username' => $username, 'ip' => $anon->getName()]);
         $session->set('AuthManager::AutoCreateBlacklist', 'authmanager-autocreate-noperm', 600);
         $session->persist();
         $user->setId(0);
         $user->loadFromId();
         return Status::newFatal('authmanager-autocreate-noperm');
     }
     // Avoid account creation races on double submissions
     $cache = \ObjectCache::getLocalClusterInstance();
     $lock = $cache->getScopedLock($cache->makeGlobalKey('account', md5($username)));
     if (!$lock) {
         $this->logger->debug(__METHOD__ . ': Could not acquire account creation lock', ['user' => $username]);
         $user->setId(0);
         $user->loadFromId();
         return Status::newFatal('usernameinprogress');
     }
     // Denied by providers?
     $providers = $this->getPreAuthenticationProviders() + $this->getPrimaryAuthenticationProviders() + $this->getSecondaryAuthenticationProviders();
     foreach ($providers as $provider) {
         $status = $provider->testUserForCreation($user, $source);
         if (!$status->isGood()) {
             $ret = Status::wrap($status);
             $this->logger->debug(__METHOD__ . ': Provider denied creation of {username}: {reason}', ['username' => $username, 'reason' => $ret->getWikiText(null, null, 'en')]);
             $session->set('AuthManager::AutoCreateBlacklist', $status, 600);
             $user->setId(0);
             $user->loadFromId();
             return $ret;
         }
     }
     // Ignore warnings about master connections/writes...hard to avoid here
     \Profiler::instance()->getTransactionProfiler()->resetExpectations();
     $backoffKey = wfMemcKey('AuthManager', 'autocreate-failed', md5($username));
     if ($cache->get($backoffKey)) {
         $this->logger->debug(__METHOD__ . ': {username} denied by prior creation attempt failures', ['username' => $username]);
         $user->setId(0);
         $user->loadFromId();
         return Status::newFatal('authmanager-autocreate-exception');
     }
     // Checks passed, create the user...
     $from = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : 'CLI';
     $this->logger->info(__METHOD__ . ': creating new user ({username}) - from: {from}', ['username' => $username, 'from' => $from]);
     try {
         $status = $user->addToDatabase();
         if (!$status->isOk()) {
             // double-check for a race condition (T70012)
             $localId = User::idFromName($username, User::READ_LATEST);
             if ($localId) {
                 $this->logger->info(__METHOD__ . ': {username} already exists locally (race)', ['username' => $username]);
                 $user->setId($localId);
                 $user->loadFromId(User::READ_LATEST);
                 if ($login) {
                     $this->setSessionDataForUser($user);
                 }
                 $status = Status::newGood();
                 $status->warning('userexists');
             } else {
                 $this->logger->error(__METHOD__ . ': {username} failed with message {message}', ['username' => $username, 'message' => $status->getWikiText(null, null, 'en')]);
                 $user->setId(0);
                 $user->loadFromId();
             }
             return $status;
         }
     } catch (\Exception $ex) {
         $this->logger->error(__METHOD__ . ': {username} failed with exception {exception}', ['username' => $username, 'exception' => $ex]);
         // Do not keep throwing errors for a while
         $cache->set($backoffKey, 1, 600);
         // Bubble up error; which should normally trigger DB rollbacks
         throw $ex;
     }
     $this->setDefaultUserOptions($user, true);
     // Inform the providers
     $this->callMethodOnProviders(6, 'autoCreatedAccount', [$user, $source]);
     \Hooks::run('AuthPluginAutoCreate', [$user], '1.27');
     \Hooks::run('LocalUserCreated', [$user, true]);
     $user->saveSettings();
     // Update user count
     \DeferredUpdates::addUpdate(new \SiteStatsUpdate(0, 0, 0, 0, 1));
     // Watch user's userpage and talk page
     $user->addWatch($user->getUserPage(), User::IGNORE_USER_RIGHTS);
     // Log the creation
     if ($this->config->get('NewUserLog')) {
         $logEntry = new \ManualLogEntry('newusers', 'autocreate');
         $logEntry->setPerformer($user);
         $logEntry->setTarget($user->getUserPage());
         $logEntry->setComment('');
         $logEntry->setParameters(['4::userid' => $user->getId()]);
         $logid = $logEntry->insert();
     }
     if ($login) {
         $this->setSessionDataForUser($user);
     }
     return Status::newGood();
 }
 /**
  * Render template for <body> tag content
  */
 public function executeEditPage()
 {
     wfProfileIn(__METHOD__);
     $helper = EditPageLayoutHelper::getInstance();
     $editPage = $helper->getEditPage();
     $this->showPreview = true;
     if ($helper->fullScreen) {
         $wgJsMimeType = $this->wg->JsMimeType;
         // add stylesheet
         $this->wg->Out->addStyle(AssetsManager::getInstance()->getSassCommonURL('extensions/wikia/EditPageLayout/css/EditPageLayout.scss'));
         if ($helper->isCodeSyntaxHighlightingEnabled($editPage->getTitle())) {
             $this->wg->Out->addScript("<script type=\"{$wgJsMimeType}\" src=\"/resources/Ace/ace.js\"></script>");
             $srcs = AssetsManager::getInstance()->getGroupCommonURL('ace_editor_js');
             OasisController::addBodyClass('codeeditor');
             $this->showPreview = $helper->isCodePageWithPreview($editPage->getTitle());
         } else {
             $packageName = 'epl';
             if (class_exists('RTE') && RTE::isEnabled() && !$editPage->isReadOnlyPage()) {
                 $packageName = 'eplrte';
             }
             $srcs = AssetsManager::getInstance()->getGroupCommonURL($packageName);
         }
         foreach ($srcs as $src) {
             $this->wg->Out->addScript("<script type=\"{$wgJsMimeType}\" src=\"{$src}\"></script>");
         }
     }
     // render WikiLogo
     $response = $this->app->sendRequest('WikiHeader', 'Wordmark');
     // move wordmark data
     $this->wordmark = $response->getData();
     // render global and user navigation
     $this->header = F::app()->renderView('GlobalNavigation', 'index');
     // Editing [foo]
     $this->title = $editPage->getEditedTitle();
     $section = $this->wg->Request->getVal('section');
     // Is user logged in?
     $this->isLoggedIn = $this->wg->User->isLoggedIn();
     // Can the user minor edit?
     $this->canMinorEdit = $this->title->exists() && $this->isLoggedIn && $this->wg->User->isAllowed('minoredit');
     // Text for Edit summary label
     $wpSummaryLabelText = 'editpagelayout-edit-summary-label';
     // Should show mobile preview icon
     $this->showMobilePreview = $helper->showMobilePreview($editPage->getTitle());
     if ($section == 'new') {
         $msgKey = 'editingcomment';
         // If adding new section to page, change label text (BugId: 7243)
         $wpSummaryLabelText = 'editpagelayout-subject-headline-label';
     } else {
         if (is_numeric($section)) {
             $msgKey = 'editingsection';
         } else {
             $msgKey = 'editing';
         }
     }
     // title
     $this->titleText = $this->title->getPrefixedText();
     if ($this->titleText == '') {
         $this->titleText = ' ';
     }
     // limit title length
     if (mb_strlen($this->titleText) > self::TITLE_MAX_LENGTH) {
         $this->titleShortText = htmlspecialchars(mb_substr($this->titleText, 0, self::TITLE_MAX_LENGTH)) . '&hellip;';
     } else {
         $this->titleShortText = htmlspecialchars($this->titleText);
     }
     $this->editing = wfMessage($msgKey, '')->escaped();
     $this->wpSummaryLabelText = wfMessage($wpSummaryLabelText)->escaped();
     // render help link and point the link to new tab
     $this->helpLink = wfMessage('editpagelayout-helpLink')->parse();
     $this->helpLink = str_replace('<a ', '<a target="_blank" ', $this->helpLink);
     // action for edit form
     $this->editFormAction = $editPage->getFormAction();
     // preloads
     $this->editPagePreloads = $editPage->getEditPagePreloads();
     // minor edit checkbox (BugId:6461)
     $this->minorEditCheckbox = !empty($editPage->minoredit);
     // summary box
     $this->summaryBox = $editPage->renderSummaryBox();
     // extra checkboxes
     $this->customCheckboxes = $editPage->getCustomCheckboxes();
     // dismissable notifications
     $this->notices = $editPage->getNotices();
     $this->noticesHtml = $editPage->getNoticesHtml();
     // notifications link (BugId:7951)
     $this->notificationsLink = count($this->notices) == 0 ? wfMessage('editpagelayout-notificationsLink-none')->escaped() : wfMessage('editpagelayout-notificationsLink', count($this->notices))->parse();
     // check if we're in read only mode
     // disable edit form when in read-only mode
     if (wfReadOnly()) {
         $this->bodytext = '<div id="mw-read-only-warning" class="WikiaArticle">' . wfMessage('oasis-editpage-readonlywarning', wfReadOnlyReason())->escaped() . '</div>';
         wfDebug(__METHOD__ . ": edit form disabled because read-only mode is on\n");
     }
     $this->hideTitle = $editPage->hideTitle;
     wfRunHooks('EditPageLayoutExecute', array($this));
     wfProfileOut(__METHOD__);
 }
Example #19
0
 /**
  * Display a page stating that the Wiki is in read-only mode,
  * and optionally show the source of the page that the user
  * was trying to edit.  Should only be called (for this
  * purpose) after wfReadOnly() has returned true.
  *
  * For historical reasons, this function is _also_ used to
  * show the error message when a user tries to edit a page
  * they are not allowed to edit.  (Unless it's because they're
  * blocked, then we show blockedPage() instead.)  In this
  * case, the second parameter should be set to true and a list
  * of reasons supplied as the third parameter.
  *
  * @todo Needs to be split into multiple functions.
  *
  * @param string $source    Source code to show (or null).
  * @param bool   $protected Is this a permissions error?
  * @param array  $reasons   List of reasons for this error, as returned by Title::getUserPermissionsErrors().
  */
 public function readOnlyPage($source = null, $protected = false, $reasons = array(), $action = null)
 {
     global $wgUser, $wgTitle;
     $skin = $wgUser->getSkin();
     $this->setRobotPolicy('noindex,nofollow');
     $this->setArticleRelated(false);
     // If no reason is given, just supply a default "I can't let you do
     // that, Dave" message.  Should only occur if called by legacy code.
     if ($protected && empty($reasons)) {
         $reasons[] = array('badaccess-group0');
     }
     if (!empty($reasons)) {
         // Permissions error
         if ($source) {
             $this->setPageTitle(wfMsg('viewsource'));
             $this->setSubtitle(wfMsg('viewsourcefor', $skin->makeKnownLinkObj($wgTitle)));
         } else {
             $this->setPageTitle(wfMsg('badaccess'));
         }
         $this->addWikiText($this->formatPermissionsErrorMessage($reasons, $action));
     } else {
         // Wiki is read only
         $this->setPageTitle(wfMsg('readonly'));
         $reason = wfReadOnlyReason();
         $this->wrapWikiMsg('<div class="mw-readonly-error">$1</div>', array('readonlytext', $reason));
     }
     // Show source, if supplied
     if (is_string($source)) {
         $this->addWikiMsg('viewsourcetext');
         $text = Xml::openElement('textarea', array('id' => 'wpTextbox1', 'name' => 'wpTextbox1', 'cols' => $wgUser->getOption('cols'), 'rows' => $wgUser->getOption('rows'), 'readonly' => 'readonly'));
         $text .= htmlspecialchars($source);
         $text .= Xml::closeElement('textarea');
         $this->addHTML($text);
         // Show templates used by this article
         $skin = $wgUser->getSkin();
         $article = new Article($wgTitle);
         $this->addHTML("<div class='templatesUsed'>\n{$skin->formatTemplates($article->getUsedTemplates())}\n</div>\n");
     }
     # If the title doesn't exist, it's fairly pointless to print a return
     # link to it.  After all, you just tried editing it and couldn't, so
     # what's there to do there?
     if ($wgTitle->exists()) {
         $this->returnToMain(null, $wgTitle);
     }
 }
Example #20
0
 /**
  * @return bool
  */
 protected function showHeader()
 {
     global $wgOut, $wgUser, $wgMaxArticleSize, $wgLang;
     global $wgAllowUserCss, $wgAllowUserJs;
     if ($this->mTitle->isTalkPage()) {
         $wgOut->addWikiMsg('talkpagetext');
     }
     // Add edit notices
     $wgOut->addHTML(implode("\n", $this->mTitle->getEditNotices($this->oldid)));
     if ($this->isConflict) {
         $wgOut->wrapWikiMsg("<div class='mw-explainconflict'>\n\$1\n</div>", 'explainconflict');
         $this->edittime = $this->mArticle->getTimestamp();
     } else {
         if ($this->section != '' && !$this->isSectionEditSupported()) {
             // We use $this->section to much before this and getVal('wgSection') directly in other places
             // at this point we can't reset $this->section to '' to fallback to non-section editing.
             // Someone is welcome to try refactoring though
             $wgOut->showErrorPage('sectioneditnotsupported-title', 'sectioneditnotsupported-text');
             return false;
         }
         if ($this->section != '' && $this->section != 'new') {
             if (!$this->summary && !$this->preview && !$this->diff) {
                 $sectionTitle = self::extractSectionTitle($this->textbox1);
                 //FIXME: use Content object
                 if ($sectionTitle !== false) {
                     $this->summary = "/* {$sectionTitle} */ ";
                 }
             }
         }
         if ($this->missingComment) {
             $wgOut->wrapWikiMsg("<div id='mw-missingcommenttext'>\n\$1\n</div>", 'missingcommenttext');
         }
         if ($this->missingSummary && $this->section != 'new') {
             $wgOut->wrapWikiMsg("<div id='mw-missingsummary'>\n\$1\n</div>", 'missingsummary');
         }
         if ($this->missingSummary && $this->section == 'new') {
             $wgOut->wrapWikiMsg("<div id='mw-missingcommentheader'>\n\$1\n</div>", 'missingcommentheader');
         }
         if ($this->blankArticle) {
             $wgOut->wrapWikiMsg("<div id='mw-blankarticle'>\n\$1\n</div>", 'blankarticle');
         }
         if ($this->hookError !== '') {
             $wgOut->addWikiText($this->hookError);
         }
         if (!$this->checkUnicodeCompliantBrowser()) {
             $wgOut->addWikiMsg('nonunicodebrowser');
         }
         if ($this->section != 'new') {
             $revision = $this->mArticle->getRevisionFetched();
             if ($revision) {
                 // Let sysop know that this will make private content public if saved
                 if (!$revision->userCan(Revision::DELETED_TEXT, $wgUser)) {
                     $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1\n</div>\n", 'rev-deleted-text-permission');
                 } elseif ($revision->isDeleted(Revision::DELETED_TEXT)) {
                     $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1\n</div>\n", 'rev-deleted-text-view');
                 }
                 if (!$revision->isCurrent()) {
                     $this->mArticle->setOldSubtitle($revision->getId());
                     $wgOut->addWikiMsg('editingold');
                 }
             } elseif ($this->mTitle->exists()) {
                 // Something went wrong
                 $wgOut->wrapWikiMsg("<div class='errorbox'>\n\$1\n</div>\n", array('missing-revision', $this->oldid));
             }
         }
     }
     if (wfReadOnly()) {
         $wgOut->wrapWikiMsg("<div id=\"mw-read-only-warning\">\n\$1\n</div>", array('readonlywarning', wfReadOnlyReason()));
     } elseif ($wgUser->isAnon()) {
         if ($this->formtype != 'preview') {
             $wgOut->wrapWikiMsg("<div id='mw-anon-edit-warning'>\n\$1\n</div>", array('anoneditwarning', '{{fullurl:Special:UserLogin|returnto={{FULLPAGENAMEE}}}}', '{{fullurl:Special:UserLogin/signup|returnto={{FULLPAGENAMEE}}}}'));
         } else {
             $wgOut->wrapWikiMsg("<div id=\"mw-anon-preview-warning\">\n\$1</div>", 'anonpreviewwarning');
         }
     } else {
         if ($this->isCssJsSubpage) {
             # Check the skin exists
             if ($this->isWrongCaseCssJsPage) {
                 $wgOut->wrapWikiMsg("<div class='error' id='mw-userinvalidcssjstitle'>\n\$1\n</div>", array('userinvalidcssjstitle', $this->mTitle->getSkinFromCssJsSubpage()));
             }
             if ($this->formtype !== 'preview') {
                 if ($this->isCssSubpage && $wgAllowUserCss) {
                     $wgOut->wrapWikiMsg("<div id='mw-usercssyoucanpreview'>\n\$1\n</div>", array('usercssyoucanpreview'));
                 }
                 if ($this->isJsSubpage && $wgAllowUserJs) {
                     $wgOut->wrapWikiMsg("<div id='mw-userjsyoucanpreview'>\n\$1\n</div>", array('userjsyoucanpreview'));
                 }
             }
         }
     }
     if ($this->mTitle->isProtected('edit') && MWNamespace::getRestrictionLevels($this->mTitle->getNamespace()) !== array('')) {
         # Is the title semi-protected?
         if ($this->mTitle->isSemiProtected()) {
             $noticeMsg = 'semiprotectedpagewarning';
         } else {
             # Then it must be protected based on static groups (regular)
             $noticeMsg = 'protectedpagewarning';
         }
         LogEventsList::showLogExtract($wgOut, 'protect', $this->mTitle, '', array('lim' => 1, 'msgKey' => array($noticeMsg)));
     }
     if ($this->mTitle->isCascadeProtected()) {
         # Is this page under cascading protection from some source pages?
         list($cascadeSources, ) = $this->mTitle->getCascadeProtectionSources();
         $notice = "<div class='mw-cascadeprotectedwarning'>\n\$1\n";
         $cascadeSourcesCount = count($cascadeSources);
         if ($cascadeSourcesCount > 0) {
             # Explain, and list the titles responsible
             foreach ($cascadeSources as $page) {
                 $notice .= '* [[:' . $page->getPrefixedText() . "]]\n";
             }
         }
         $notice .= '</div>';
         $wgOut->wrapWikiMsg($notice, array('cascadeprotectedwarning', $cascadeSourcesCount));
     }
     if (!$this->mTitle->exists() && $this->mTitle->getRestrictions('create')) {
         LogEventsList::showLogExtract($wgOut, 'protect', $this->mTitle, '', array('lim' => 1, 'showIfEmpty' => false, 'msgKey' => array('titleprotectedwarning'), 'wrap' => "<div class=\"mw-titleprotectedwarning\">\n\$1</div>"));
     }
     if ($this->kblength === false) {
         $this->kblength = (int) (strlen($this->textbox1) / 1024);
     }
     if ($this->tooBig || $this->kblength > $wgMaxArticleSize) {
         $wgOut->wrapWikiMsg("<div class='error' id='mw-edit-longpageerror'>\n\$1\n</div>", array('longpageerror', $wgLang->formatNum($this->kblength), $wgLang->formatNum($wgMaxArticleSize)));
     } else {
         if (!wfMessage('longpage-hint')->isDisabled()) {
             $wgOut->wrapWikiMsg("<div id='mw-edit-longpage-hint'>\n\$1\n</div>", array('longpage-hint', $wgLang->formatSize(strlen($this->textbox1)), strlen($this->textbox1)));
         }
     }
     # Add header copyright warning
     $this->showHeaderCopyrightWarning();
     return true;
 }
Example #21
0
 /**
  * Update the article's restriction field, and leave a log entry.
  * This works for protection both existing and non-existing pages.
  *
  * @param $limit Array: set of restriction keys
  * @param $reason String
  * @param &$cascade Integer. Set to false if cascading protection isn't allowed.
  * @param $expiry Array: per restriction type expiration
  * @param $user User The user updating the restrictions
  * @return Status
  */
 public function doUpdateRestrictions(array $limit, array $expiry, &$cascade, $reason, User $user)
 {
     global $wgContLang;
     if (wfReadOnly()) {
         return Status::newFatal('readonlytext', wfReadOnlyReason());
     }
     $restrictionTypes = $this->mTitle->getRestrictionTypes();
     $id = $this->mTitle->getArticleID();
     if (!$cascade) {
         $cascade = false;
     }
     // Take this opportunity to purge out expired restrictions
     Title::purgeExpiredRestrictions();
     # @todo FIXME: Same limitations as described in ProtectionForm.php (line 37);
     # we expect a single selection, but the schema allows otherwise.
     $isProtected = false;
     $protect = false;
     $changed = false;
     $dbw = wfGetDB(DB_MASTER);
     foreach ($restrictionTypes as $action) {
         if (!isset($expiry[$action])) {
             $expiry[$action] = $dbw->getInfinity();
         }
         if (!isset($limit[$action])) {
             $limit[$action] = '';
         } elseif ($limit[$action] != '') {
             $protect = true;
         }
         # Get current restrictions on $action
         $current = implode('', $this->mTitle->getRestrictions($action));
         if ($current != '') {
             $isProtected = true;
         }
         if ($limit[$action] != $current) {
             $changed = true;
         } elseif ($limit[$action] != '') {
             # Only check expiry change if the action is actually being
             # protected, since expiry does nothing on an not-protected
             # action.
             if ($this->mTitle->getRestrictionExpiry($action) != $expiry[$action]) {
                 $changed = true;
             }
         }
     }
     if (!$changed && $protect && $this->mTitle->areRestrictionsCascading() != $cascade) {
         $changed = true;
     }
     # If nothing's changed, do nothing
     if (!$changed) {
         return Status::newGood();
     }
     if (!$protect) {
         # No protection at all means unprotection
         $revCommentMsg = 'unprotectedarticle';
         $logAction = 'unprotect';
     } elseif ($isProtected) {
         $revCommentMsg = 'modifiedarticleprotection';
         $logAction = 'modify';
     } else {
         $revCommentMsg = 'protectedarticle';
         $logAction = 'protect';
     }
     $encodedExpiry = array();
     $protectDescription = '';
     foreach ($limit as $action => $restrictions) {
         $encodedExpiry[$action] = $dbw->encodeExpiry($expiry[$action]);
         if ($restrictions != '') {
             $protectDescription .= $wgContLang->getDirMark() . "[{$action}={$restrictions}] (";
             if ($encodedExpiry[$action] != 'infinity') {
                 $protectDescription .= wfMessage('protect-expiring', $wgContLang->timeanddate($expiry[$action], false, false), $wgContLang->date($expiry[$action], false, false), $wgContLang->time($expiry[$action], false, false))->inContentLanguage()->text();
             } else {
                 $protectDescription .= wfMessage('protect-expiry-indefinite')->inContentLanguage()->text();
             }
             $protectDescription .= ') ';
         }
     }
     $protectDescription = trim($protectDescription);
     if ($id) {
         # Protection of existing page
         if (!wfRunHooks('ArticleProtect', array(&$this, &$user, $limit, $reason))) {
             return Status::newGood();
         }
         # Only restrictions with the 'protect' right can cascade...
         # Otherwise, people who cannot normally protect can "protect" pages via transclusion
         $editrestriction = isset($limit['edit']) ? array($limit['edit']) : $this->mTitle->getRestrictions('edit');
         # The schema allows multiple restrictions
         if (!in_array('protect', $editrestriction) && !in_array('sysop', $editrestriction)) {
             $cascade = false;
         }
         # Update restrictions table
         foreach ($limit as $action => $restrictions) {
             if ($restrictions != '') {
                 $dbw->replace('page_restrictions', array(array('pr_page', 'pr_type')), array('pr_page' => $id, 'pr_type' => $action, 'pr_level' => $restrictions, 'pr_cascade' => $cascade && $action == 'edit' ? 1 : 0, 'pr_expiry' => $encodedExpiry[$action]), __METHOD__);
             } else {
                 $dbw->delete('page_restrictions', array('pr_page' => $id, 'pr_type' => $action), __METHOD__);
             }
         }
         # Prepare a null revision to be added to the history
         $editComment = $wgContLang->ucfirst(wfMessage($revCommentMsg, $this->mTitle->getPrefixedText())->inContentLanguage()->text());
         if ($reason) {
             $editComment .= ": {$reason}";
         }
         if ($protectDescription) {
             $editComment .= " ({$protectDescription})";
         }
         if ($cascade) {
             // FIXME: Should use 'brackets' message.
             $editComment .= ' [' . wfMessage('protect-summary-cascade')->inContentLanguage()->text() . ']';
         }
         # Insert a null revision
         $nullRevision = Revision::newNullRevision($dbw, $id, $editComment, true);
         $nullRevId = $nullRevision->insertOn($dbw);
         $latest = $this->getLatest();
         # Update page record
         $dbw->update('page', array('page_touched' => $dbw->timestamp(), 'page_restrictions' => '', 'page_latest' => $nullRevId), array('page_id' => $id), __METHOD__);
         wfRunHooks('NewRevisionFromEditComplete', array($this, $nullRevision, $latest, $user));
         wfRunHooks('ArticleProtectComplete', array(&$this, &$user, $limit, $reason));
     } else {
         # Protection of non-existing page (also known as "title protection")
         # Cascade protection is meaningless in this case
         $cascade = false;
         if ($limit['create'] != '') {
             $dbw->replace('protected_titles', array(array('pt_namespace', 'pt_title')), array('pt_namespace' => $this->mTitle->getNamespace(), 'pt_title' => $this->mTitle->getDBkey(), 'pt_create_perm' => $limit['create'], 'pt_timestamp' => $dbw->encodeExpiry(wfTimestampNow()), 'pt_expiry' => $encodedExpiry['create'], 'pt_user' => $user->getId(), 'pt_reason' => $reason), __METHOD__);
         } else {
             $dbw->delete('protected_titles', array('pt_namespace' => $this->mTitle->getNamespace(), 'pt_title' => $this->mTitle->getDBkey()), __METHOD__);
         }
     }
     $this->mTitle->flushRestrictions();
     if ($logAction == 'unprotect') {
         $logParams = array();
     } else {
         $logParams = array($protectDescription, $cascade ? 'cascade' : '');
     }
     # Update the protection log
     $log = new LogPage('protect');
     $log->addEntry($logAction, $this->mTitle, trim($reason), $logParams, $user);
     return Status::newGood();
 }
Example #22
0
 /**
  *	This method will try to store the data in mOptions.
  *
  * It will return true on success or an error message on failure.
  * The used form and target page will be available in mOptions after
  * execution of the method.
  *
  * This method also sets HTTP response headers according to the result.
  *
  * @param bool $prefillFromExisting If this is set, existing values in the page will be used to prefill the form.
  * @return true or an error message
  */
 public function storeSemanticData($prefillFromExisting = true)
 {
     global $wgOut, $wgRequest;
     // If the wiki is read-only we might as well stop right away
     if (wfReadOnly()) {
         return $this->reportError(wfMsg('sf_autoedit_readonly', wfReadOnlyReason()));
     }
     // ensure 'form' key exists
     if (!array_key_exists('form', $this->mOptions)) {
         $this->mOptions['form'] = null;
     }
     // ensure 'target' key exists
     if (!array_key_exists('target', $this->mOptions)) {
         $this->mOptions['target'] = null;
     }
     // If we have no target article and no form we might as well stop right away
     if (!$this->mOptions['target'] && !$this->mOptions['form']) {
         return $this->reportError(wfMsg('sf_autoedit_notargetspecified'));
     }
     // check if form was specified
     if (!$this->mOptions['form']) {
         // If no form was specified, find the default one for
         // this page.
         $title = Title::newFromText($this->mOptions['target']);
         $form_names = SFFormLinker::getDefaultFormsForPage($title);
         // if no form can be found, return
         if (count($form_names) == 0) {
             return $this->reportError(wfMsg('sf_autoedit_noformfound'));
         }
         // if more than one form found, return
         if (count($form_names) > 1) {
             return $this->reportError(wfMsg('sf_autoedit_toomanyformsfound'));
         }
         // There should now be exactly one form.
         $this->mOptions['form'] = $form_names[0];
     }
     // we only care for the form's body
     $wgOut->setArticleBodyOnly(true);
     $formedit = new SFFormEdit();
     $data = array();
     $oldRequest = $wgRequest;
     // Get the form definition and target page (if there is one),
     // as specified in the options string, then create the actual
     // HTML form from them, and call that form to modify or create
     // the page.
     if ($prefillFromExisting) {
         $wgRequest = new FauxRequest($this->mOptions, true);
         // get the Semantic Form
         if ($this->mOptions['target']) {
             $formedit->execute($this->mOptions['form'] . '/' . $this->mOptions['target']);
         } else {
             $formedit->execute($this->mOptions['form']);
         }
         // extract its data
         $form = $this->parseDataFromHTMLFrag($data, trim($wgOut->getHTML()), 'sfForm');
         if (!$form) {
             // something went wrong
             $wgRequest = $oldRequest;
             return $this->reportError(wfMsg('sf_autoedit_nosemanticform', array($this->mOptions['target'], $this->mOptions['form'])));
         }
     } else {
         self::addToArray($data, "wpSave", "Save");
     }
     // and modify as specified
     $data = SFUtils::array_merge_recursive_distinct($data, $this->mOptions);
     ////////////////////////////////////////////////////////////////////////
     // Store the modified form
     // $wgOut->clearHTML();
     $wgRequest = new FauxRequest($data, true);
     // get the MW form
     if ($this->mOptions['target']) {
         $formedit->execute($this->mOptions['form'] . '/' . $this->mOptions['target'], false);
     } else {
         $formedit->execute($this->mOptions['form'], false);
     }
     $this->mOptions['form'] = $formedit->mForm;
     $this->mOptions['target'] = $formedit->mTarget;
     $wgRequest = $oldRequest;
     if ($formedit->mError) {
         return $this->reportError($formedit->mError);
     } else {
         if (!headers_sent()) {
             header("X-Location: " . $wgOut->getRedirect());
             header("X-Form: " . $formedit->mForm);
             header("X-Target: " . $formedit->mTarget);
         }
         if ($this->isApiQuery()) {
             $this->getResult()->addValue(null, 'result', array('code' => '200', 'location' => $wgOut->getRedirect(), 'form' => $formedit->mForm, 'target' => $formedit->mTarget));
         }
     }
     return true;
 }
Example #23
0
/**
 * Check whether the wiki is in read-only mode.
 *
 * @return bool
 */
function wfReadOnly()
{
    return wfReadOnlyReason() !== false;
}
Example #24
0
 /**
  * @param $url string
  * @return Mixed|String
  */
 function fetchScaryTemplateMaybeFromCache($url)
 {
     global $wgTranscludeCacheExpiry;
     $dbr = wfGetDB(DB_SLAVE);
     $tsCond = $dbr->timestamp(time() - $wgTranscludeCacheExpiry);
     $obj = $dbr->selectRow('transcache', array('tc_time', 'tc_contents'), array('tc_url' => $url, "tc_time >= " . $dbr->addQuotes($tsCond)));
     if ($obj) {
         return $obj->tc_contents;
     }
     $text = Http::get($url);
     if (!$text) {
         # wikia start
         Wikia::log(__METHOD__, false, "Scary transclusion failed for <{$url}>");
         # wikia end
         return wfMsgForContent('scarytranscludefailed', $url);
     }
     # wikia start
     if (wfReadOnly()) {
         return wfReadOnlyReason();
     }
     # wikia end
     $dbw = wfGetDB(DB_MASTER);
     $dbw->replace('transcache', array('tc_url'), array('tc_url' => $url, 'tc_time' => $dbw->timestamp(time()), 'tc_contents' => $text));
     return $text;
 }
Example #25
0
    /**
     * This function is the real heart of the entire Semantic Forms
     * extension. It handles two main actions: (1) displaying a form on the
     * screen, given a form definition and possibly page contents (if an
     * existing page is being edited); and (2) creating actual page
     * contents, if the form was already submitted by the user.
     *
     * It also does some related tasks, like figuring out the page name (if
     * only a page formula exists).
     */
    function formHTML($form_def, $form_submitted, $source_is_page, $form_id = null, $existing_page_content = null, $page_name = null, $page_name_formula = null, $is_query = false, $is_embedded = false)
    {
        global $wgRequest, $wgUser, $wgParser;
        global $sfgTabIndex;
        // used to represent the current tab index in the form
        global $sfgFieldNum;
        // used for setting various HTML IDs
        wfProfileIn(__METHOD__);
        // initialize some variables
        $sfgTabIndex = 1;
        $sfgFieldNum = 1;
        $source_page_matches_this_form = false;
        $form_page_title = null;
        $generated_page_name = $page_name_formula;
        // $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 = "";
        // flag for placing "<onlyinclude>" tags in form output
        $onlyinclude_free_text = false;
        // 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 a hidden text field.
        if (!$wgRequest->getCheck('partial')) {
            $original_page_content = $existing_page_content;
        } else {
            $original_page_content = null;
            if ($wgRequest->getCheck('sf_free_text')) {
                $existing_page_content = $wgRequest->getVal('sf_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 ($is_embedded) {
            // If this is an embedded form (probably a 'RunQuery'),
            // just use the name of the actual page we're on.
            global $wgTitle;
            $this->mPageTitle = $wgTitle;
        } elseif ($is_query) {
            $this->mPageTitle = Title::newFromText('RunQuery dummy title');
        } elseif ($page_name === '' || $page_name === null) {
            $this->mPageTitle = Title::newFromText($wgRequest->getVal('namespace') . ":Semantic Forms permissions test");
        } else {
            $this->mPageTitle = Title::newFromText($page_name);
        }
        global $wgOut;
        // show previous set of deletions for this page, if it's been deleted before
        if (!$form_submitted && ($this->mPageTitle && !$this->mPageTitle->exists())) {
            $this->showDeletionLog($wgOut);
        }
        // Unfortunately, we can't just call userCan() here because,
        // since MW 1.16, it has a bug in which it ignores a setting of
        // "$wgEmailConfirmToEdit = true;". Instead, we'll just get the
        // permission errors from the start, and use those to determine whether
        // the page is editable.
        if (!$is_query) {
            // $userCanEditPage = ( $wgUser->isAllowed( 'edit' ) && $this->mPageTitle->userCan( 'edit' ) );
            $permissionErrors = $this->mPageTitle->getUserPermissionsErrors('edit', $wgUser);
            // The handling of $wgReadOnly and $wgReadOnlyFile
            // has to be done separately.
            if (wfReadOnly()) {
                global $wgReadOnly;
                $permissionErrors = array(array('readonlytext', array(wfReadOnlyReason())));
            }
            $userCanEditPage = count($permissionErrors) == 0;
            wfRunHooks('sfUserCanEditPage', array($this->mPageTitle, &$userCanEditPage));
        }
        $form_text = "";
        if ($is_query || $userCanEditPage) {
            $form_is_disabled = false;
            // Show "Your IP address will be recorded" warning if
            // user is anonymous, and it's not a query -
            // wiki-text for bolding has to be replaced with HTML.
            if ($wgUser->isAnon() && !$is_query) {
                $anon_edit_warning = preg_replace("/'''(.*)'''/", "<strong>\$1</strong>", wfMsg('anoneditwarning'));
                $form_text .= "<p>{$anon_edit_warning}</p>\n";
            }
        } else {
            $form_is_disabled = true;
            $wgOut->setPageTitle(wfMsg('badaccess'));
            $wgOut->addWikiText($wgOut->formatPermissionsErrorMessage($permissionErrors, 'edit'));
            $wgOut->addHTML("\n<hr />\n");
        }
        //		$oldParser = $wgParser;
        //		$wgParser = unserialize( serialize( $oldParser ) ); // deep clone of parser
        if (!$wgParser->Options()) {
            $wgParser->Options(ParserOptions::newFromUser($wgUser));
        }
        $wgParser->Title($this->mPageTitle);
        //		$wgParser->clearState();
        $form_def = SFFormUtils::getFormDefinition($wgParser, $form_def, $form_id);
        // 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;
        $free_text_components = array();
        $all_values_for_template = array();
        // Unencode any 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 was 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 = SFUtils::getFormTagComponents($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 the 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;
        // Placeholder name in the form
        $curPlaceholder = null;
        // Used to store the HTML code of the multiple template, to reinsert it into the right spot
        // This array will keep track of all the replaced @<name>@ strings
        $placeholderFields = array();
        for ($section_num = 0; $section_num < count($form_def_sections); $section_num++) {
            $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];
            $multipleTemplateString = "";
            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 = SFUtils::getFormTagComponents($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 = SFTemplateInForm::create($template_name);
                    $query_template_name = str_replace(' ', '_', $template_name);
                    $add_button_text = wfMsg('sf_formedit_addanother');
                    // Also replace periods with underlines, since that's what
                    // POST does to strings anyway.
                    $query_template_name = str_replace('.', '_', $query_template_name);
                    // ...and escape apostrophes.
                    $query_template_name = str_replace("'", "\\'", $query_template_name);
                    // 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 = array_map('trim', explode('=', $component, 2));
                        if (count($sub_components) == 2) {
                            if ($sub_components[0] == 'label') {
                                $template_label = $sub_components[1];
                            } elseif ($sub_components[0] == 'add button text') {
                                $add_button_text = $sub_components[1];
                            } elseif ($sub_components[0] == 'embed in field') {
                                // Placeholder on form template level. Assume that the template form def
                                // will have a multiple+placeholder parameters, and get the placeholder value.
                                // We expect something like TemplateName[fieldName], and convert it to the
                                // TemplateName___fieldName form used internally.
                                preg_match('/\\s*(.*)\\[(.*)\\]\\s*/', $sub_components[1], $matches);
                                $curPlaceholder = count($matches) > 2 ? self::placeholderFormat($matches[1], $matches[2]) : null;
                                unset($matches);
                            }
                        }
                    }
                    // If this is the first instance, add
                    // the label into the form, if there is
                    // one, and add the appropriate wrapper
                    // div, if this is a multiple-instance
                    // template.
                    if ($old_template_name != $template_name) {
                        if (isset($template_label)) {
                            $multipleTemplateString .= "<fieldset>\n";
                            $multipleTemplateString .= Html::element('legend', null, $template_label) . "\n";
                        }
                        // If $curPlaceholder is set, it means we want to insert a
                        // multiple template form's HTML into the main form's HTML.
                        // So, the HTML will be stored in $multipleTemplateString.
                        if ($allow_multiple) {
                            $multipleTemplateString .= "\t" . '<div class="multipleTemplateWrapper">' . "\n";
                            $multipleTemplateString .= "\t" . '<div class="multipleTemplateList">' . "\n";
                        }
                    }
                    if ($curPlaceholder == null) {
                        $form_text .= $multipleTemplateString;
                    }
                    $template_text .= "{{" . $template_name;
                    $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;
                    if ($source_is_page || $form_is_partial) {
                        // Replace underlines with spaces in template name, to allow for
                        // searching on either.
                        $search_template_str = str_replace('_', ' ', $template_name);
                        $preg_match_template_str = str_replace(array('/', '(', ')'), array('\\/', '\\(', '\\)'), $search_template_str);
                        $found_instance = preg_match('/{{' . $preg_match_template_str . '\\s*[\\|}]/i', str_replace('_', ' ', $existing_page_content));
                        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 ($found_instance) {
                                $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 ($found_instance) {
                            $matches = array();
                            $search_pattern = '/{{' . $preg_match_template_str . '\\s*[\\|}]/i';
                            $content_str = str_replace('_', ' ', $existing_page_content);
                            preg_match($search_pattern, $content_str, $matches, PREG_OFFSET_CAPTURE);
                            // is this check necessary?
                            if (array_key_exists(0, $matches) && array_key_exists(1, $matches[0])) {
                                $start_char = $matches[0][1];
                                $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++;
                                }
                                // If the next character is a pipe, skip that too.
                                if ($existing_page_content[$fields_start_char] == '|') {
                                    $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 && $uncompleted_curly_brackets <= 2;
                                    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;
                                    }
                                }
                                // If there are uncompleted opening brackets, the whole form will get messed up -
                                // display a warning.
                                // (If there are too many *closing* brackets, some template stuff will end up in
                                // the "free text" field - which is bad, but it's harder for the code to detect
                                // the problem - though hopefully, easier for users.)
                                if ($uncompleted_curly_brackets > 0 || $uncompleted_square_brackets > 0) {
                                    $form_text .= "\t" . '<div class="warningbox">' . wfMsg('sf_formedit_mismatchedbrackets', $this->mPageTitle->getFullURL(array('action' => 'edit'))) . "</div>\n<br clear=\"both\" />\n";
                                }
                                $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 = $this->strReplaceFirst($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)
                                // - on second thought, allow even the presence of multiple-
                                // instance templates to validate that this is the correct
                                // form: the problem is that some forms contain *only* mutliple-
                                // instance templates.
                                // 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
                            // TODO: this code is probably no longer necessary
                            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]);
                            }
                        }
                    }
                    // =====================================================
                    // end template processing
                    // =====================================================
                } elseif ($tag_title == 'end template') {
                    if ($source_is_page) {
                        // Add any unhandled template fields in the page as hidden variables.
                        if (isset($template_contents)) {
                            $form_text .= SFFormUtils::unhandledFieldsHTML($template_name, $template_contents);
                            $template_contents = null;
                        }
                    }
                    // 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) && $curPlaceholder == null) {
                        $form_text .= "</fieldset>\n";
                        unset($template_label);
                    }
                    $allow_multiple = false;
                    $all_instances_printed = false;
                    $instance_num = 0;
                    // =====================================================
                    // field processing
                    // =====================================================
                } elseif ($tag_title == 'field') {
                    $field_name = trim($tag_components[1]);
                    $fullFieldName = $template_name . '[' . $field_name . ']';
                    // 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();
                    $show_on_select = array();
                    $default_value = null;
                    $values = null;
                    $possible_values = null;
                    $semantic_property = null;
                    $preload_page = null;
                    $holds_template = false;
                    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 = !$wgUser || !$wgUser->isAllowed('editrestrictedfields');
                        } elseif ($component == 'list') {
                            $is_list = true;
                        } elseif ($component == 'edittools') {
                            // free text only
                            $free_text_components[] = 'edittools';
                        }
                        $sub_components = array_map('trim', explode('=', $component, 2));
                        if (count($sub_components) == 1) {
                            // add handling for single-value params, for custom input types
                            $field_args[$sub_components[0]] = true;
                            if ($component == 'holds template') {
                                $is_hidden = true;
                                $holds_template = true;
                                $placeholderFields[] = self::placeholderFormat($template_name, $field_name);
                            }
                        } elseif (count($sub_components) == 2) {
                            // First, set each value as its own entry in $field_args.
                            $field_args[$sub_components[0]] = $sub_components[1];
                            // Then, do all special handling.
                            if ($sub_components[0] == 'input type') {
                                $input_type = $sub_components[1];
                            } elseif ($sub_components[0] == 'default') {
                                $default_value = $wgParser->recursiveTagParse($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 {
                                    $preload_page = $sub_components[1];
                                }
                            } elseif ($sub_components[0] == 'show on select') {
                                // html_entity_decode() is needed to turn '&gt;' to '>'
                                $vals = explode(';', html_entity_decode($sub_components[1]));
                                foreach ($vals as $val) {
                                    $val = trim($val);
                                    if (empty($val)) {
                                        continue;
                                    }
                                    $option_div_pair = explode('=>', $val, 2);
                                    if (count($option_div_pair) > 1) {
                                        $option = $option_div_pair[0];
                                        $div_id = $option_div_pair[1];
                                        if (array_key_exists($div_id, $show_on_select)) {
                                            $show_on_select[$div_id][] = $option;
                                        } else {
                                            $show_on_select[$div_id] = array($option);
                                        }
                                    } else {
                                        $show_on_select[$val] = array();
                                    }
                                }
                            } elseif ($sub_components[0] == 'autocomplete on property') {
                                $property_name = $sub_components[1];
                                $propValue = SMWPropertyValue::makeUserProperty($property_name);
                                if ($propValue->getPropertyTypeID() == '_wpg') {
                                    $field_args['autocomplete field type'] = 'relation';
                                } else {
                                    $field_args['autocomplete field type'] = 'attribute';
                                }
                                $field_args['autocompletion source'] = $sub_components[1];
                            } elseif ($sub_components[0] == 'autocomplete on category') {
                                $field_args['autocomplete field type'] = 'category';
                                $field_args['autocompletion source'] = $sub_components[1];
                            } elseif ($sub_components[0] == 'autocomplete on concept') {
                                $field_args['autocomplete field type'] = 'concept';
                                $field_args['autocompletion source'] = $sub_components[1];
                            } elseif ($sub_components[0] == 'autocomplete on namespace') {
                                $field_args['autocomplete field type'] = 'namespace';
                                $autocompletion_source = $sub_components[1];
                                // special handling for "main" (blank) namespace
                                if ($autocompletion_source == "") {
                                    $autocompletion_source = "main";
                                }
                                $field_args['autocompletion source'] = $autocompletion_source;
                            } elseif ($sub_components[0] == 'autocomplete from url') {
                                $field_args['autocomplete field type'] = 'external_url';
                                $field_args['autocompletion source'] = $sub_components[1];
                                // 'external' autocompletion is always done remotely, i.e. via API
                                $field_args['remote autocompletion'] = true;
                            } elseif ($sub_components[0] == 'values') {
                                // Handle this one only after 'delimiter' has
                                // also been set.
                                $values = $sub_components[1];
                            } elseif ($sub_components[0] == 'values from property') {
                                $propertyName = $sub_components[1];
                                $possible_values = SFUtils::getAllValuesForProperty($propertyName);
                            } elseif ($sub_components[0] == 'values from category') {
                                $category_name = ucfirst($sub_components[1]);
                                $possible_values = SFUtils::getAllPagesForCategory($category_name, 10);
                            } elseif ($sub_components[0] == 'values from concept') {
                                $possible_values = SFUtils::getAllPagesForConcept($sub_components[1]);
                            } elseif ($sub_components[0] == 'values from namespace') {
                                $possible_values = SFUtils::getAllPagesForNamespace($sub_components[1]);
                            } elseif ($sub_components[0] == 'values dependent on') {
                                global $sfgDependentFields;
                                $sfgDependentFields[] = array($sub_components[1], $fullFieldName);
                            } elseif ($sub_components[0] == 'property') {
                                $semantic_property = $sub_components[1];
                            } elseif ($sub_components[0] == 'default filename') {
                                $default_filename = str_replace('&lt;page name&gt;', $page_name, $sub_components[1]);
                                // Parse value, so default filename can include parser functions.
                                $default_filename = $wgParser->recursiveTagParse($default_filename);
                                $field_args['default filename'] = $default_filename;
                            } elseif ($sub_components[0] == 'restricted') {
                                $is_restricted = !array_intersect($wgUser->getEffectiveGroups(), array_map('trim', explode(',', $sub_components[1])));
                            }
                        }
                    }
                    // end for
                    // Backwards compatibility
                    if ($input_type == 'datetime with timezone') {
                        $input_type = 'datetime';
                        $field_args['include timezone'] = true;
                    } elseif ($input_type == 'text' || $input_type == 'textarea') {
                        // Also for backwards compatibility,
                        // in that once b/c goes away,
                        // this will no longer be
                        // necessary.
                        $field_args['no autocomplete'] = true;
                    }
                    if ($allow_multiple) {
                        $field_args['part_of_multiple'] = $allow_multiple;
                    }
                    if (count($show_on_select) > 0) {
                        $field_args['show on select'] = $show_on_select;
                    }
                    // Get the value from the request, if
                    // it's there, and if it's not an array.
                    $cur_value = null;
                    $escaped_field_name = str_replace("'", "\\'", $field_name);
                    if (isset($template_instance_query_values) && $template_instance_query_values != null && is_array($template_instance_query_values)) {
                        // If the field name contains an
                        // apostrophe, the array sometimes
                        // has the apostrophe escaped, and
                        // sometimes not. For now, just check
                        // for both versions.
                        // @TODO - figure this out.
                        $field_query_val = null;
                        if (array_key_exists($escaped_field_name, $template_instance_query_values)) {
                            $field_query_val = $template_instance_query_values[$escaped_field_name];
                        } elseif (array_key_exists($field_name, $template_instance_query_values)) {
                            $field_query_val = $template_instance_query_values[$field_name];
                        }
                        if ($form_submitted || $field_query_val != '' && !is_array($field_query_val)) {
                            $cur_value = $field_query_val;
                        }
                    }
                    if (empty($cur_value) && !$form_submitted) {
                        if (!is_null($default_value)) {
                            // Set to the default value specified in the form, if it's there.
                            $cur_value = $default_value;
                        } elseif ($preload_page) {
                            $cur_value = SFFormUtils::getPreloadedText($preload_page);
                        }
                    }
                    // If the user is editing a page, and that page contains a call to
                    // the template being processed, get the current field's value
                    // from the template call
                    if ($source_is_page && !empty($existing_template_text)) {
                        if (isset($template_contents[$field_name])) {
                            $cur_value = $template_contents[$field_name];
                            // If the field is a placeholder, the contents of this template
                            // parameter should be treated as elements parsed by an another
                            // multiple template form.
                            // By putting that at the very end of the parsed string, we'll
                            // have it processed as a regular multiple template form.
                            if ($holds_template) {
                                $existing_page_content = $existing_page_content . $cur_value;
                            }
                            // Now remove this value
                            // from $template_contents,
                            // so that at the end we
                            // can have a list of all
                            // the fields that weren't
                            // handled by the form.
                            unset($template_contents[$field_name]);
                        } else {
                            $cur_value = '';
                        }
                    }
                    // Handle the free text field.
                    if ($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 = Html::hidden('sf_free_text', '!free_text!');
                        } else {
                            $sfgTabIndex++;
                            $sfgFieldNum++;
                            if ($cur_value === '' || is_null($cur_value)) {
                                $default_value = '!free_text!';
                            } else {
                                $default_value = $cur_value;
                                // If the FCKeditor extension is installed and
                                // active, the default value needs to be parsed
                                // for use in the editor.
                                global $wgFCKEditorDir;
                                if ($wgFCKEditorDir && strpos($existing_page_content, '__NORICHEDITOR__') === false) {
                                    $showFCKEditor = SFFormUtils::getShowFCKEditor();
                                    if (!$form_submitted && $showFCKEditor & RTE_VISIBLE) {
                                        $default_value = SFFormUtils::prepareTextForFCK($cur_value);
                                    }
                                }
                            }
                            $new_text = SFTextAreaInput::getHTML($default_value, 'sf_free_text', false, $form_is_disabled || $is_restricted, $field_args);
                            if (in_array('edittools', $free_text_components)) {
                                // borrowed from EditPage::showEditTools()
                                $options[] = 'parse';
                                $edittools_text = $wgParser->recursiveTagParse(wfMsg('edittools', array('content')));
                                $new_text .= <<<END
\t\t<div class="mw-editTools">
\t\t{$edittools_text}
\t\t</div>

END;
                            }
                        }
                        $free_text_was_included = true;
                        // add a similar placeholder to the data text
                        $data_text .= "!free_text!\n";
                    }
                    if ($template_name === '' || $field_name == '<freetext>') {
                        $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) {
                                    $cur_value_in_template = SFUtils::getWordForYesOrNo(false);
                                } elseif (count($cur_value) == 2) {
                                    $cur_value_in_template = SFUtils::getWordForYesOrNo(true);
                                    // 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'];
                                    $hour = $minute = $second = $ampm24h = $timezone = null;
                                    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 (!is_null($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 (!is_null($second)) {
                                            $cur_value_in_template .= ":" . str_pad(intval(substr($second, 0, 2)), 2, '0', STR_PAD_LEFT);
                                        }
                                        if (!is_null($ampm24h)) {
                                            $cur_value_in_template .= " {$ampm24h}";
                                        }
                                        if (!is_null($timezone)) {
                                            $cur_value_in_template .= " {$timezone}";
                                        }
                                    } else {
                                        $cur_value_in_template = "";
                                    }
                                }
                            }
                        } else {
                            // value is not an array
                            $cur_value_in_template = $cur_value;
                        }
                        if ($template_name == null || $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 = $template_name . '[num][' . $field_name . ']';
                            $field_args['origName'] = $template_name . '[' . $field_name . ']';
                        } else {
                            $input_name = $template_name . '[' . $field_name . ']';
                        }
                        // If the 'values' parameter was set, separate it based on the
                        // 'delimiter' parameter, if any.
                        if (!empty($values)) {
                            if (array_key_exists('delimiter', $field_args)) {
                                $delimiter = $field_args['delimiter'];
                            } else {
                                $delimiter = ",";
                            }
                            // Remove whitespaces, and un-escape characters
                            $possible_values = array_map('trim', explode($delimiter, $values));
                            $possible_values = array_map('htmlspecialchars_decode', $possible_values);
                        }
                        // if we're creating the page name from a formula based on
                        // form values, see if the current input is part of that formula,
                        // and if so, substitute in the actual value
                        if ($form_submitted && $generated_page_name !== '') {
                            // this line appears to be unnecessary
                            // $generated_page_name = str_replace('.', '_', $generated_page_name);
                            $generated_page_name = str_replace(' ', '_', $generated_page_name);
                            $escaped_input_name = str_replace(' ', '_', $input_name);
                            $generated_page_name = str_ireplace("<{$escaped_input_name}>", $cur_value_in_template, $generated_page_name);
                            // once the substitution is done, replace underlines back
                            // with spaces
                            $generated_page_name = str_replace('_', ' ', $generated_page_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;
                        // Create an SFFormField instance based on all the parameters
                        // in the form definition, and any information from the template
                        // definition (contained in the $all_fields parameter).
                        $form_field = SFFormField::createFromDefinition($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 a property was set in the form definition, overwrite whatever
                        // is set in the template field - this is somewhat of a hack, since
                        // parameters set in the form definition are meant to go into the
                        // SFFormField object, not the SFTemplateField object it contains;
                        // it seemed like too much work, though, to create an
                        // SFFormField::setSemanticProperty() function just for this call
                        if ($semantic_property != null) {
                            $form_field->template_field->setSemanticProperty($semantic_property);
                        }
                        $semantic_property = $form_field->template_field->getSemanticProperty();
                        if (!is_null($semantic_property)) {
                            global $sfgFieldProperties;
                            $sfgFieldProperties[$fullFieldName] = $semantic_property;
                        }
                        // call hooks - unfortunately this has to be split into two
                        // separate calls, because of the different variable names in
                        // each case
                        if ($form_submitted) {
                            wfRunHooks('sfCreateFormField', array(&$form_field, &$cur_value_in_template, true));
                        } else {
                            wfRunHooks('sfCreateFormField', array(&$form_field, &$cur_value, false));
                        }
                        // if this is not part of a 'multiple' template, increment the
                        // global tab index (used for correct tabbing)
                        if (!array_key_exists('part_of_multiple', $field_args)) {
                            $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 == 'year' || $input_type === '' && $form_field->getTemplateField()->getPropertyType() == '_dat') {
                                // Get current time, for the time zone specified in the wiki.
                                global $wgLocaltimezone;
                                if (isset($wgLocaltimezone)) {
                                    $serverTimezone = date_default_timezone_get();
                                    date_default_timezone_set($wgLocaltimezone);
                                }
                                $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 (isset($wgLocaltimezone)) {
                                    date_default_timezone_set($serverTimezone);
                                }
                                if ($input_type == 'datetime') {
                                    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 (array_key_exists('include timezone', $field_args)) {
                                    $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')) {
                            $cur_value_in_template = $wgUser->getName();
                            $cur_value = $cur_value_in_template;
                        }
                        // Generate a hidden field with a placeholder value that will be replaced
                        // by the multiple-instances template output at form submission.
                        //// <input type="hidden" value="@replace_Town___mayors@" name="Town[town_mayors]" />
                        if ($holds_template) {
                            $cur_value = self::makePlaceholderInWikiText(self::placeholderFormat($template_name, $field_name));
                        }
                        $new_text = $this->formFieldHTML($form_field, $cur_value);
                        // Add a field just after the hidden field, within the HTML, to locate
                        // where the multiple-templates HTML, stored in $multipleTemplateString,
                        // should be inserted.
                        if ($holds_template) {
                            $new_text .= self::makePlaceholderInFormHTML(self::placeholderFormat($template_name, $field_name));
                        }
                        // If this field is disabled, add a hidden field holding
                        // the value of this field, because disabled inputs for some
                        // reason don't submit their value.
                        if ($form_field->isDisabled()) {
                            if ($field_name == 'free text' || $field_name == '<freetext>') {
                                $new_text .= Html::hidden('sf_free_text', '!free_text!');
                            } else {
                                $new_text .= Html::hidden($input_name, $cur_value);
                            }
                        }
                        if ($new_text) {
                            // Include the field name only for non-numeric field names.
                            if (is_numeric($field_name)) {
                                $template_text .= "|{$cur_value_in_template}";
                            } else {
                                // If the value is null, don't include it at all.
                                if ($cur_value_in_template !== '') {
                                    $template_text .= "\n|{$field_name}={$cur_value_in_template}";
                                }
                            }
                            $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                        } else {
                            $start_position = $brackets_end_loc;
                        }
                    }
                    // =====================================================
                    // standard input processing
                    // =====================================================
                } elseif ($tag_title == 'standard input') {
                    // handle all the possible values
                    $input_name = $tag_components[1];
                    $input_label = null;
                    $attr = array();
                    // if it's a query, ignore all standard inputs except run query
                    if ($is_query && $input_name != 'run query' || !$is_query && $input_name == 'run query') {
                        $new_text = "";
                        $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                        continue;
                    }
                    // set a flag so that the standard 'form bottom' won't get displayed
                    $this->standardInputsIncluded = true;
                    // cycle through the other components
                    for ($i = 2; $i < count($tag_components); $i++) {
                        $component = $tag_components[$i];
                        $sub_components = array_map('trim', explode('=', $component));
                        if (count($sub_components) == 1) {
                            if ($sub_components[0] == 'edittools') {
                                $free_text_components[] = 'edittools';
                            }
                        } elseif (count($sub_components) == 2) {
                            switch ($sub_components[0]) {
                                case 'label':
                                    $input_label = $sub_components[1];
                                    break;
                                case 'class':
                                case 'style':
                                    $attr[$sub_components[0]] = $sub_components[1];
                                    break;
                            }
                            // free text input needs more handling than the rest
                            if ($input_name == 'free text' || $input_name == '<freetext>') {
                                if ($sub_components[0] == 'preload') {
                                    $free_text_preload_page = $sub_components[1];
                                }
                            }
                        }
                    }
                    if ($input_name == 'summary') {
                        $new_text = SFFormUtils::summaryInputHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'minor edit') {
                        $new_text = SFFormUtils::minorEditInputHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'watch') {
                        $new_text = SFFormUtils::watchInputHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'save') {
                        $new_text = SFFormUtils::saveButtonHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'save and continue') {
                        $new_text = SFFormUtils::saveAndContinueButtonHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'preview') {
                        $new_text = SFFormUtils::showPreviewButtonHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'changes') {
                        $new_text = SFFormUtils::showChangesButtonHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'cancel') {
                        $new_text = SFFormUtils::cancelLinkHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'run query') {
                        $new_text = SFFormUtils::runQueryButtonHTML($form_is_disabled, $input_label, $attr);
                    }
                    $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    // =====================================================
                    // page info processing
                    // =====================================================
                } elseif ($tag_title == 'info') {
                    // TODO: Generate an error message if this is included more than once
                    foreach (array_slice($tag_components, 1) as $component) {
                        $sub_components = array_map('trim', explode('=', $component, 2));
                        // Tag names are case-insensitive
                        $tag = strtolower($sub_components[0]);
                        if ($tag == 'create title' || $tag == 'add title') {
                            // Handle this only if
                            // we're adding a page.
                            if (!$is_query && !$this->mPageTitle->exists()) {
                                $form_page_title = $sub_components[1];
                            }
                        } elseif ($tag == 'edit title') {
                            // Handle this only if
                            // we're editing a page.
                            if (!$is_query && $this->mPageTitle->exists()) {
                                $form_page_title = $sub_components[1];
                            }
                        } elseif ($tag == 'query title') {
                            // Handle this only if
                            // we're in 'RunQuery'.
                            if ($is_query) {
                                $form_page_title = $sub_components[1];
                            }
                        } elseif ($tag == 'partial form') {
                            $form_is_partial = true;
                            // replacement pages may have minimal matches...
                            $source_page_matches_this_form = true;
                        } elseif ($tag == 'includeonly free text' || $tag == 'onlyinclude free text') {
                            $onlyinclude_free_text = true;
                        } elseif ($tag == 'query form at top') {
                            // TODO - this should be made a field of
                            // some non-static class that actually
                            // prints the form, instead of requiring
                            // a global variable.
                            global $sfgRunQueryFormAtTop;
                            $sfgRunQueryFormAtTop = true;
                        }
                    }
                    $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    // =====================================================
                    // default outer level processing
                    // =====================================================
                } else {
                    // Tag is not one of the three allowed values -
                    // ignore the tag.
                    $start_position = $brackets_end_loc;
                }
                // end if
            }
            // end while
            if (!$all_instances_printed) {
                if ($template_text !== '') {
                    // For mostly aesthetic purposes, if the template call ends with
                    // a bunch of pipes (i.e., it's an indexed template with unused
                    // parameters at the end), remove the pipes.
                    $template_text = preg_replace('/\\|*$/', '', $template_text);
                    // add another newline before the final bracket, if this template
                    // call is already more than one line
                    if (strpos($template_text, "\n")) {
                        $template_text .= "\n";
                    }
                    // If we're editing an existing page, and there were fields in
                    // the template call not handled by this form, preserve those.
                    if (!$allow_multiple) {
                        $template_text .= SFFormUtils::addUnhandledFields($template_name);
                    }
                    $template_text .= "}}";
                    // The base $template_text will contain strings like "@replace_xxx@"
                    // in the hidden fields when the form is submitted.
                    // On the following loops, the text for the multiple-instance templates
                    // is progressively reinserted in the main data, always keeping a
                    // trailing @replace_xxx@ for a given field
                    // The trailing @replace_xxx@ is then deleted at the end.
                    // Note: this cleanup step could also be done with a regexp, instead of
                    // keeping a track array (e.g., /@replace_(.*)@/)
                    $reptmp = self::makePlaceholderInWikiText($curPlaceholder);
                    if ($curPlaceholder != null && $data_text && strpos($data_text, $reptmp, 0) !== false) {
                        $data_text = preg_replace('/' . $reptmp . '/', $template_text . $reptmp, $data_text);
                    } else {
                        $data_text .= $template_text . "\n";
                    }
                    // If there is a placeholder in the
                    // text, we know that we are
                    // doing a replace.
                    if ($existing_page_content && strpos($existing_page_content, '{{{insertionpoint}}}', 0) !== false) {
                        $existing_page_content = preg_replace('/\\{\\{\\{insertionpoint\\}\\}\\}(\\r?\\n?)/', preg_replace('/\\}\\}/m', '}�', preg_replace('/\\{\\{/m', '�{', $template_text)) . "\n{{{insertionpoint}}}", $existing_page_content);
                        // otherwise, if it's a partial form, we have to add the new
                        // text somewhere
                    } elseif ($form_is_partial && $wgRequest->getCheck('partial')) {
                        $existing_page_content = preg_replace('/\\}\\}/m', '}�', preg_replace('/\\{\\{/m', '�{', $template_text)) . "\n{{{insertionpoint}}}\n" . $existing_page_content;
                    }
                }
            }
            if ($allow_multiple) {
                if ($curPlaceholder == null) {
                    // The normal process.
                    $form_text .= $this->multipleTemplateInstanceHTML($form_is_disabled, $all_instances_printed, $section, $instance_num, $add_button_text);
                } else {
                    // if ( $curPlaceholder != null ){
                    // The template text won't be appended at the end of the template like for usual multiple template forms.
                    // The HTML text will then be stored in the $multipleTemplateString variable,
                    // and then added in the right @insertHTML_".$placeHolderField."@"; position
                    // Optimization: actually, instead of separating the processes, the usual multiple
                    // template forms could also be handled this way if a fitting placeholder tag was added.
                    $multipleTemplateString .= $this->multipleTemplateInstanceHTML($form_is_disabled, $all_instances_printed, $section, $instance_num, $add_button_text);
                    // We replace the $multipleTemplateString HTML into the
                    // current placeholder tag, but also add another
                    // placeholder tag, to keep track of it.
                    $multipleTemplateString .= self::makePlaceholderInFormHTML($curPlaceholder);
                    if (isset($template_label)) {
                        $multipleTemplateString .= "</fieldset>\n";
                        unset($template_label);
                    }
                    $form_text = preg_replace('/' . self::makePlaceholderInFormHTML($curPlaceholder) . '/', $multipleTemplateString, $form_text);
                }
                if (!$all_instances_printed) {
                    // This will cause the section to be
                    // re-parsed on the next go.
                    $section_num--;
                }
            } else {
                // if ( $allow_multiple ) {
                $form_text .= $section;
            }
            $curPlaceholder = null;
            //		var_dump($wgParser->getOutput()->getModules());
        }
        // end for
        // Cleanup - everything has been browsed.
        // Remove all the remaining placeholder
        // tags in the HTML and wiki-text.
        foreach ($placeholderFields as $stringToReplace) {
            // remove the @<replacename>@ tags from the data that is submitted
            $data_text = preg_replace('/' . self::makePlaceholderInWikiText($stringToReplace) . '/', '', $data_text);
            // remove the @<insertHTML>@ tags from the generated HTML form
            $form_text = preg_replace('/' . self::makePlaceholderInFormHTML($stringToReplace) . '/', '', $form_text);
        }
        // if it wasn't included in the form definition, add the
        // 'free text' input as a hidden field at the bottom
        if (!$free_text_was_included) {
            $form_text .= Html::hidden('sf_free_text', '!free_text!');
        }
        // 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 .= Html::hidden('partial', 1);
            } else {
                $free_text = null;
                $existing_page_content = preg_replace(array('/�\\{/m', '/\\}�/m'), array('{{', '}}'), $existing_page_content);
                $existing_page_content = preg_replace('/\\{\\{\\{insertionpoint\\}\\}\\}/', '', $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('sf_free_text')) {
            $free_text = $wgRequest->getVal('sf_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;
        }
        if ($onlyinclude_free_text) {
            // modify free text and data text to insert <onlyinclude> tags
            $free_text = str_replace("<onlyinclude>", '', $free_text);
            $free_text = str_replace("</onlyinclude>", '', $free_text);
            $free_text = trim($free_text);
            $data_text = str_replace('!free_text!', '<onlyinclude>!free_text!</onlyinclude>', $data_text);
        }
        wfRunHooks('sfModifyFreeTextField', array(&$free_text, $existing_page_content));
        // if the FCKeditor extension is installed, use that for the free text input
        global $wgFCKEditorDir;
        if ($wgFCKEditorDir && strpos($existing_page_content, '__NORICHEDITOR__') === false) {
            $showFCKEditor = SFFormUtils::getShowFCKEditor();
            if (!$form_submitted && $showFCKEditor & RTE_VISIBLE) {
                $free_text = SFFormUtils::prepareTextForFCK($free_text);
            }
        } else {
            $showFCKEditor = 0;
        }
        // now that we have it, substitute free text into the form and page
        $escaped_free_text = Sanitizer::safeEncodeAttribute($free_text);
        $form_text = str_replace('!free_text!', $escaped_free_text, $form_text);
        $data_text = str_replace('!free_text!', $free_text, $data_text);
        // Add a warning in, if we're editing an existing page and that
        // page appears to not have been created with this form.
        if (!$is_query && $this->mPageTitle->exists() && $existing_page_content !== '' && !$source_page_matches_this_form) {
            $form_text = "\t" . '<div class="warningbox">' . wfMsg('sf_formedit_formwarning', $this->mPageTitle->getFullURL()) . "</div>\n<br clear=\"both\" />\n" . $form_text;
        }
        // add form bottom, if no custom "standard inputs" have been defined
        if (!$this->standardInputsIncluded) {
            if ($is_query) {
                $form_text .= SFFormUtils::queryFormBottom($form_is_disabled);
            } else {
                $form_text .= SFFormUtils::formBottom($form_is_disabled);
            }
        }
        if (!$is_query) {
            $form_text .= Html::hidden('wpStarttime', wfTimestampNow());
            $article = new Article($this->mPageTitle, 0);
            $form_text .= Html::hidden('wpEdittime', $article->getTimestamp());
        }
        $form_text .= "\t</form>\n";
        // Add general Javascript code.
        wfRunHooks('sfAddJavascriptToForm', array(&$javascript_text));
        // @TODO The FCKeditor Javascript should be handled within
        // the FCKeditor extension itself, using the hook.
        $javascript_text = "";
        if ($free_text_was_included && $showFCKEditor > 0) {
            $javascript_text .= SFFormUtils::mainFCKJavascript($showFCKEditor, $field_args);
            if ($showFCKEditor & (RTE_TOGGLE_LINK | RTE_POPUP)) {
                $javascript_text .= SFFormUTils::FCKToggleJavascript();
            }
            if ($showFCKEditor & RTE_POPUP) {
                $javascript_text .= SFFormUTils::FCKPopupJavascript();
            }
        }
        // Send the autocomplete values to the browser, along with the
        // mappings of which values should apply to which fields.
        // If doing a replace, the data text is actually the modified original page
        if ($wgRequest->getCheck('partial')) {
            $data_text = $existing_page_content;
        }
        if (!$is_embedded) {
            $form_page_title = $wgParser->recursiveTagParse(str_replace("{{!}}", "|", $form_page_title));
        } else {
            $form_page_title = null;
        }
        // If the form has already been submitted, i.e. this is just
        // the redirect page, get rid of all the Javascript, to avoid
        // JS errors.
        if ($form_submitted) {
            $javascript_text = '';
        }
        $parserOutput = $wgParser->getOutput();
        $wgOut->addParserOutputNoText($parserOutput);
        //		$wgParser = $oldParser;
        wfProfileOut(__METHOD__);
        return array($form_text, $javascript_text, $data_text, $form_page_title, $generated_page_name);
    }
Example #26
0
 protected function appendGeneralInfo($property)
 {
     global $wgContLang;
     $config = $this->getConfig();
     $data = array();
     $mainPage = Title::newMainPage();
     $data['mainpage'] = $mainPage->getPrefixedText();
     $data['base'] = wfExpandUrl($mainPage->getFullURL(), PROTO_CURRENT);
     $data['sitename'] = $config->get('Sitename');
     // wgLogo can either be a relative or an absolute path
     // make sure we always return an absolute path
     $data['logo'] = wfExpandUrl($config->get('Logo'), PROTO_RELATIVE);
     $data['generator'] = "MediaWiki {$config->get('Version')}";
     $data['phpversion'] = PHP_VERSION;
     $data['phpsapi'] = PHP_SAPI;
     if (defined('HHVM_VERSION')) {
         $data['hhvmversion'] = HHVM_VERSION;
     }
     $data['dbtype'] = $config->get('DBtype');
     $data['dbversion'] = $this->getDB()->getServerVersion();
     $allowFrom = array('');
     $allowException = true;
     if (!$config->get('AllowExternalImages')) {
         $data['imagewhitelistenabled'] = (bool) $config->get('EnableImageWhitelist');
         $allowFrom = $config->get('AllowExternalImagesFrom');
         $allowException = !empty($allowFrom);
     }
     if ($allowException) {
         $data['externalimages'] = (array) $allowFrom;
         ApiResult::setIndexedTagName($data['externalimages'], 'prefix');
     }
     $data['langconversion'] = !$config->get('DisableLangConversion');
     $data['titleconversion'] = !$config->get('DisableTitleConversion');
     if ($wgContLang->linkPrefixExtension()) {
         $linkPrefixCharset = $wgContLang->linkPrefixCharset();
         $data['linkprefixcharset'] = $linkPrefixCharset;
         // For backwards compatibility
         $data['linkprefix'] = "/^((?>.*[^{$linkPrefixCharset}]|))(.+)\$/sDu";
     } else {
         $data['linkprefixcharset'] = '';
         $data['linkprefix'] = '';
     }
     $linktrail = $wgContLang->linkTrail();
     $data['linktrail'] = $linktrail ?: '';
     $data['legaltitlechars'] = Title::legalChars();
     global $IP;
     $git = SpecialVersion::getGitHeadSha1($IP);
     if ($git) {
         $data['git-hash'] = $git;
         $data['git-branch'] = SpecialVersion::getGitCurrentBranch($GLOBALS['IP']);
     } else {
         $svn = SpecialVersion::getSvnRevision($IP);
         if ($svn) {
             $data['rev'] = $svn;
         }
     }
     // 'case-insensitive' option is reserved for future
     $data['case'] = $config->get('CapitalLinks') ? 'first-letter' : 'case-sensitive';
     $data['lang'] = $config->get('LanguageCode');
     $fallbacks = array();
     foreach ($wgContLang->getFallbackLanguages() as $code) {
         $fallbacks[] = array('code' => $code);
     }
     $data['fallback'] = $fallbacks;
     ApiResult::setIndexedTagName($data['fallback'], 'lang');
     if ($wgContLang->hasVariants()) {
         $variants = array();
         foreach ($wgContLang->getVariants() as $code) {
             $variants[] = array('code' => $code, 'name' => $wgContLang->getVariantname($code));
         }
         $data['variants'] = $variants;
         ApiResult::setIndexedTagName($data['variants'], 'lang');
     }
     $data['rtl'] = $wgContLang->isRTL();
     $data['fallback8bitEncoding'] = $wgContLang->fallback8bitEncoding();
     $data['readonly'] = wfReadOnly();
     if ($data['readonly']) {
         $data['readonlyreason'] = wfReadOnlyReason();
     }
     $data['writeapi'] = (bool) $config->get('EnableWriteAPI');
     $tz = $config->get('Localtimezone');
     $offset = $config->get('LocalTZoffset');
     if (is_null($tz)) {
         $tz = 'UTC';
         $offset = 0;
     } elseif (is_null($offset)) {
         $offset = 0;
     }
     $data['timezone'] = $tz;
     $data['timeoffset'] = intval($offset);
     $data['articlepath'] = $config->get('ArticlePath');
     $data['scriptpath'] = $config->get('ScriptPath');
     $data['script'] = $config->get('Script');
     $data['variantarticlepath'] = $config->get('VariantArticlePath');
     $data[ApiResult::META_BC_BOOLS][] = 'variantarticlepath';
     $data['server'] = $config->get('Server');
     $data['servername'] = $config->get('ServerName');
     $data['wikiid'] = wfWikiID();
     $data['time'] = wfTimestamp(TS_ISO_8601, time());
     $data['misermode'] = (bool) $config->get('MiserMode');
     $data['maxuploadsize'] = UploadBase::getMaxUploadSize();
     $data['minuploadchunksize'] = (int) $this->getConfig()->get('MinUploadChunkSize');
     $data['thumblimits'] = $config->get('ThumbLimits');
     ApiResult::setArrayType($data['thumblimits'], 'BCassoc');
     ApiResult::setIndexedTagName($data['thumblimits'], 'limit');
     $data['imagelimits'] = array();
     ApiResult::setArrayType($data['imagelimits'], 'BCassoc');
     ApiResult::setIndexedTagName($data['imagelimits'], 'limit');
     foreach ($config->get('ImageLimits') as $k => $limit) {
         $data['imagelimits'][$k] = array('width' => $limit[0], 'height' => $limit[1]);
     }
     $favicon = $config->get('Favicon');
     if (!empty($favicon)) {
         // wgFavicon can either be a relative or an absolute path
         // make sure we always return an absolute path
         $data['favicon'] = wfExpandUrl($favicon, PROTO_RELATIVE);
     }
     Hooks::run('APIQuerySiteInfoGeneralInfo', array($this, &$data));
     return $this->getResult()->addValue('query', $property, $data);
 }
Example #27
0
 public function __construct()
 {
     parent::__construct('readonly', 'readonlytext', wfReadOnlyReason());
 }
 function execute($subpage)
 {
     global $wgUser;
     $this->setHeaders();
     if (!$this->userCanExecute($wgUser)) {
         $this->getOutput()->addWikiMsg('centralauth-merge-denied');
         $this->getOutput()->addWikiMsg('centralauth-readmore-text');
         return;
     }
     if (!$this->getUser()->isLoggedIn()) {
         $loginpage = SpecialPage::getTitleFor('Userlogin');
         $loginurl = $loginpage->getFullUrl(array('returnto' => $this->getTitle()->getPrefixedText()));
         $this->getOutput()->addWikiMsg('centralauth-merge-notlogged', $loginurl);
         $this->getOutput()->addWikiMsg('centralauth-readmore-text');
         return;
     }
     if (wfReadOnly()) {
         $this->getOutput()->setPagetitle(wfMsg('readonly'));
         $this->getOutput()->addWikiMsg('readonlytext', wfReadOnlyReason());
         return;
     }
     $this->mUserName = $this->getUser()->getName();
     $this->mAttemptMerge = $this->getRequest()->wasPosted();
     $this->mMergeAction = $this->getRequest()->getVal('wpMergeAction');
     $this->mPassword = $this->getRequest()->getVal('wpPassword');
     $this->mWikiIDs = $this->getRequest()->getArray('wpWikis');
     $this->mSessionToken = $this->getRequest()->getVal('wpMergeSessionToken');
     $this->mSessionKey = pack("H*", $this->getRequest()->getVal('wpMergeSessionKey'));
     // Possible demo states
     // success, all accounts merged
     // successful login, some accounts merged, others left
     // successful login, others left
     // not account owner, others left
     // is owner / is not owner
     // did / did not merge some accounts
     // do / don't have more accounts to merge
     if ($this->mAttemptMerge) {
         switch ($this->mMergeAction) {
             case "dryrun":
                 $this->doDryRunMerge();
             case "initial":
                 $this->doInitialMerge();
             case "cleanup":
                 $this->doCleanupMerge();
             case "attach":
                 $this->doAttachMerge();
             case "remove":
                 $this->doUnattach();
             default:
                 $this->invalidAction();
         }
         return;
     }
     $globalUser = new CentralAuthUser($this->mUserName);
     if ($globalUser->exists()) {
         if ($globalUser->isAttached()) {
             $this->showCleanupForm();
         } else {
             $this->showAttachForm();
         }
     } else {
         $this->showWelcomeForm();
     }
 }
Example #29
0
	/**
	 * Update the article's restriction field, and leave a log entry.
	 * This works for protection both existing and non-existing pages.
	 *
	 * @param array $limit set of restriction keys
	 * @param array $expiry per restriction type expiration
	 * @param int &$cascade Set to false if cascading protection isn't allowed.
	 * @param string $reason
	 * @param User $user The user updating the restrictions
	 * @return Status
	 */
	public function doUpdateRestrictions( array $limit, array $expiry, &$cascade, $reason, User $user ) {
		global $wgCascadingRestrictionLevels;

		if ( wfReadOnly() ) {
			return Status::newFatal( 'readonlytext', wfReadOnlyReason() );
		}

		$restrictionTypes = $this->mTitle->getRestrictionTypes();

		$id = $this->getId();

		if ( !$cascade ) {
			$cascade = false;
		}

		// Take this opportunity to purge out expired restrictions
		Title::purgeExpiredRestrictions();

		// @todo FIXME: Same limitations as described in ProtectionForm.php (line 37);
		// we expect a single selection, but the schema allows otherwise.
		$isProtected = false;
		$protect = false;
		$changed = false;

		$dbw = wfGetDB( DB_MASTER );

		foreach ( $restrictionTypes as $action ) {
			if ( !isset( $expiry[$action] ) ) {
				$expiry[$action] = $dbw->getInfinity();
			}
			if ( !isset( $limit[$action] ) ) {
				$limit[$action] = '';
			} elseif ( $limit[$action] != '' ) {
				$protect = true;
			}

			// Get current restrictions on $action
			$current = implode( '', $this->mTitle->getRestrictions( $action ) );
			if ( $current != '' ) {
				$isProtected = true;
			}

			if ( $limit[$action] != $current ) {
				$changed = true;
			} elseif ( $limit[$action] != '' ) {
				// Only check expiry change if the action is actually being
				// protected, since expiry does nothing on an not-protected
				// action.
				if ( $this->mTitle->getRestrictionExpiry( $action ) != $expiry[$action] ) {
					$changed = true;
				}
			}
		}

		if ( !$changed && $protect && $this->mTitle->areRestrictionsCascading() != $cascade ) {
			$changed = true;
		}

		// If nothing has changed, do nothing
		if ( !$changed ) {
			return Status::newGood();
		}

		if ( !$protect ) { // No protection at all means unprotection
			$revCommentMsg = 'unprotectedarticle';
			$logAction = 'unprotect';
		} elseif ( $isProtected ) {
			$revCommentMsg = 'modifiedarticleprotection';
			$logAction = 'modify';
		} else {
			$revCommentMsg = 'protectedarticle';
			$logAction = 'protect';
		}

		if ( $id ) { // Protection of existing page
			if ( !wfRunHooks( 'ArticleProtect', array( &$this, &$user, $limit, $reason ) ) ) {
				return Status::newGood();
			}

			// Only certain restrictions can cascade...
			$editrestriction = isset( $limit['edit'] ) ? array( $limit['edit'] ) : $this->mTitle->getRestrictions( 'edit' );
			foreach ( array_keys( $editrestriction, 'sysop' ) as $key ) {
				$editrestriction[$key] = 'editprotected'; // backwards compatibility
			}
			foreach ( array_keys( $editrestriction, 'autoconfirmed' ) as $key ) {
				$editrestriction[$key] = 'editsemiprotected'; // backwards compatibility
			}

			$cascadingRestrictionLevels = $wgCascadingRestrictionLevels;
			foreach ( array_keys( $cascadingRestrictionLevels, 'sysop' ) as $key ) {
				$cascadingRestrictionLevels[$key] = 'editprotected'; // backwards compatibility
			}
			foreach ( array_keys( $cascadingRestrictionLevels, 'autoconfirmed' ) as $key ) {
				$cascadingRestrictionLevels[$key] = 'editsemiprotected'; // backwards compatibility
			}

			// The schema allows multiple restrictions
			if ( !array_intersect( $editrestriction, $cascadingRestrictionLevels ) ) {
				$cascade = false;
			}

			// insert null revision to identify the page protection change as edit summary
			$latest = $this->getLatest();
			$nullRevision = $this->insertProtectNullRevision( $revCommentMsg, $limit, $expiry, $cascade, $reason );
			if ( $nullRevision === null ) {
				return Status::newFatal( 'no-null-revision', $this->mTitle->getPrefixedText() );
			}

			// Update restrictions table
			foreach ( $limit as $action => $restrictions ) {
				if ( $restrictions != '' ) {
					$dbw->replace( 'page_restrictions', array( array( 'pr_page', 'pr_type' ) ),
						array( 'pr_page' => $id,
							'pr_type' => $action,
							'pr_level' => $restrictions,
							'pr_cascade' => ( $cascade && $action == 'edit' ) ? 1 : 0,
							'pr_expiry' => $dbw->encodeExpiry( $expiry[$action] )
						),
						__METHOD__
					);
				} else {
					$dbw->delete( 'page_restrictions', array( 'pr_page' => $id,
						'pr_type' => $action ), __METHOD__ );
				}
			}

			// Clear out legacy restriction fields
			$dbw->update(
				'page',
				array( 'page_restrictions' => '' ),
				array( 'page_id' => $id ),
				__METHOD__
			);

			wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $nullRevision, $latest, $user ) );
			wfRunHooks( 'ArticleProtectComplete', array( &$this, &$user, $limit, $reason ) );
		} else { // Protection of non-existing page (also known as "title protection")
			// Cascade protection is meaningless in this case
			$cascade = false;

			if ( $limit['create'] != '' ) {
				$dbw->replace( 'protected_titles',
					array( array( 'pt_namespace', 'pt_title' ) ),
					array(
						'pt_namespace' => $this->mTitle->getNamespace(),
						'pt_title' => $this->mTitle->getDBkey(),
						'pt_create_perm' => $limit['create'],
						'pt_timestamp' => $dbw->encodeExpiry( wfTimestampNow() ),
						'pt_expiry' => $dbw->encodeExpiry( $expiry['create'] ),
						'pt_user' => $user->getId(),
						'pt_reason' => $reason,
					), __METHOD__
				);
			} else {
				$dbw->delete( 'protected_titles',
					array(
						'pt_namespace' => $this->mTitle->getNamespace(),
						'pt_title' => $this->mTitle->getDBkey()
					), __METHOD__
				);
			}
		}

		$this->mTitle->flushRestrictions();
		InfoAction::invalidateCache( $this->mTitle );

		if ( $logAction == 'unprotect' ) {
			$params = array();
		} else {
			$protectDescriptionLog = $this->protectDescriptionLog( $limit, $expiry );
			$params = array( $protectDescriptionLog, $cascade ? 'cascade' : '' );
		}

		// Update the protection log
		$log = new LogPage( 'protect' );
		$log->addEntry( $logAction, $this->mTitle, trim( $reason ), $params, $user );

		return Status::newGood();
	}
echo $ajaxLoginComponent;
?>
    </div>
	<?php 
if ($wgUser->isAllowed('createaccount')) {
    ?>
<div id="AjaxLoginRegisterForm" <?php 
    echo $showRegister ? '' : 'style="display:none"';
    ?>
 title="<?php 
    print wfMsg('login');
    ?>
">
				<?php 
    if (!$isReadOnly) {
        echo $registerAjax;
    } else {
        // RT #85688
        ?>
					<div id="AjaxLoginReadOnlyMessage"><?php 
        echo wfMsg('comboajaxlogin-readonlytext', wfReadOnlyReason());
        ?>
</div>
				<?php 
    }
    ?>
			</div><?php 
}
?>
</div>