/** * 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; }
/** * The function called if we're in index.php (as opposed to one of the * special pages) */ static function displayForm($action, $article) { // @todo: This looks like bad code. If we can't find a form, we // should be showing an informative error page rather than // making it look like an edit form page does not exist. $title = $article->getTitle(); $form_names = SFFormLinker::getDefaultFormsForPage($title); if (count($form_names) == 0) { return true; } $output = $action->getOutput(); if (count($form_names) > 1) { $warning_text = "\t" . '<div class="warningbox">' . wfMessage('sf_formedit_morethanoneform')->text() . "</div>\n"; $output->addWikiText($warning_text); } $form_name = $form_names[0]; $page_name = SFUtils::titleString($title); SFFormEdit::printForm($form_name, $page_name); return false; }
/** * The function called if we're in index.php (as opposed to one of the * special pages) */ static function displayForm($action, $article) { global $wgOut, $sfgUseFormEditPage; // return "true" if the call failed (meaning, pass on handling // of the hook to others), and "false" otherwise if ($action != 'formedit') { return true; } // @todo: This looks like bad code. If we can't find a form, we // should be showing an informative error page rather than // making it look like an edit form page does not exist. $title = $article->getTitle(); $form_names = SFFormLinker::getDefaultFormsForPage($title); if (count($form_names) == 0) { return true; } if (count($form_names) > 1) { $warning_text = "\t" . '<div class="warningMessage">' . wfMsg('sf_formedit_morethanoneform') . "</div>\n"; $wgOut->addHTML($warning_text); } $form_name = $form_names[0]; if ($sfgUseFormEditPage) { # Experimental new feature extending from the internal # EditPage class $editor = new SFFormEditPage($article, $form_name); $editor->edit(); return false; } $page_name = SFUtils::titleString($title); $msg = SFFormEdit::printForm($form_name, $page_name); if ($msg) { // Some error occurred - display it. $msgdata = null; if (is_array($msg)) { if (count($msg) > 1) { $msgdata = $msg[1]; } $msg = $msg[0]; } $wgOut->addHTML(Html::element('p', array('class' => 'error'), wfMsg($msg, $msgdata))); } return false; }
/** * The function called if we're in index.php (as opposed to one of the * special pages) */ static function displayForm($action, $article) { $output = $action->getOutput(); $title = $article->getTitle(); $form_names = SFFormLinker::getDefaultFormsForPage($title); if (count($form_names) == 0) { // If no form is set, display an interface to let the // user choose out of all the forms defined on this wiki // (or none at all). self::displayFormChooser($output, $title); return true; } if (count($form_names) > 1) { $warning_text = "\t" . '<div class="warningbox">' . wfMessage('sf_formedit_morethanoneform')->text() . "</div>\n"; $output->addWikiText($warning_text); } $form_name = $form_names[0]; $page_name = SFUtils::titleString($title); $sfFormEdit = new SFFormEdit(); $sfFormEdit->printForm($form_name, $page_name); return false; }
function doRedirect($form_name, $page_name, $params) { global $wgOut; $page_title = Title::newFromText($page_name); if ($page_title->exists()) { // It exists - see if page is a redirect; if // it is, edit the target page instead. $article = new Article($page_title, 0); $article->loadContent(); $redirect_title = Title::newFromRedirect($article->fetchContent()); if ($redirect_title != null) { $page_title = $redirect_title; $page_name = SFUtils::titleURLString($redirect_title); } // HACK - if this is the default form for // this page, send to the regular 'formedit' // tab page; otherwise, send to the 'Special:FormEdit' // page, with the form name hardcoded. // Is this logic necessary? Or should we just // out-guess the user and always send to the // standard form-edit page, with the 'correct' form? $default_forms = SFFormLinker::getDefaultFormsForPage($page_title); if (count($default_forms) > 0) { $default_form_name = $default_forms[0]; } else { $default_form_name = null; } if ($form_name == $default_form_name) { $redirect_url = $page_title->getLocalURL('action=formedit'); } else { $redirect_url = self::getFormEditURL($form_name, $page_name); } } else { $redirect_url = self::getFormEditURL($form_name, $page_name); // Of all the request values, send on to 'FormEdit' // only 'preload' and specific form fields - we can // identify the latter because they show up as arrays. foreach ($_REQUEST as $key => $val) { if (is_array($val)) { $template_name = urlencode($key); foreach ($val as $field_name => $value) { $field_name = urlencode($field_name); $value = urlencode($value); $redirect_url .= strpos($redirect_url, '?') > -1 ? '&' : '?'; $redirect_url .= $template_name . '[' . $field_name . ']=' . $value; } } elseif ($key == 'preload') { $redirect_url .= strpos($redirect_url, '?') > -1 ? '&' : '?'; $redirect_url .= "{$key}={$val}"; } } } if (!is_null($params) && $params !== '') { $redirect_url .= strpos($redirect_url, '?') > -1 ? '&' : '?'; $redirect_url .= $params; } $wgOut->setArticleBodyOnly(true); // Show "loading" animated image while people wait for the // redirect. global $sfgScriptPath; $text = "<p style=\"position: absolute; left: 45%; top: 45%;\"><img src=\"{$sfgScriptPath}/skins/loading.gif\" /></p>\n"; $text .= <<<END \t\t<script type="text/javascript"> \t\twindow.onload = function() { \t\t\twindow.location="{$redirect_url}"; \t\t} \t\t</script> END; $wgOut->addHTML($text); return; }
/** * Get the Title object of a form suitable for editing the target page. * * @return Title * @throws MWException */ protected function getFormTitle() { // if no form was explicitly specified, try for explicitly set alternate forms if ($this->mOptions['form'] === '') { $this->logMessage('No form specified. Will try to find the default form for the target page.', self::DEBUG); $formNames = array(); // try explicitly set alternative forms if (array_key_exists('alt_form', $this->mOptions)) { $formNames = (array) $this->mOptions['alt_form']; // cast to array to make sure we get an array, even if only a string was sent } // if no alternate forms were explicitly set, try finding a default form for the target page if (count($formNames) === 0) { // if no form and and no alt forms and no target page was specified, give up if ($this->mOptions['target'] === '') { throw new MWException(wfMessage('sf_autoedit_notargetspecified')->parse()); } $targetTitle = Title::newFromText($this->mOptions['target']); // if the specified target title is invalid, give up if (!$targetTitle instanceof Title) { throw new MWException(wfMessage('sf_autoedit_invalidtargetspecified', $this->mOptions['target'])->parse()); } $formNames = SFFormLinker::getDefaultFormsForPage($targetTitle); // if no default form can be found, try alternate forms if (count($formNames) === 0) { $formNames = SFFormLinker::getFormsThatPagePointsTo($targetTitle->getText(), $targetTitle->getNamespace(), SFFormLinker::ALTERNATE_FORM); // if still no form can be found, give up if (count($formNames) === 0) { throw new MWException(wfMessage('sf_autoedit_noformfound')->parse()); } } } // if more than one form was found, issue a notice and give up // this happens if no default form but several alternate forms are defined if (count($formNames) > 1) { throw new MWException(wfMessage('sf_autoedit_toomanyformsfound')->parse(), self::DEBUG); } $this->mOptions['form'] = $formNames[0]; $this->logMessage('Using ' . $this->mOptions['form'] . ' as default form.', self::DEBUG); } $formTitle = Title::makeTitleSafe(SF_NS_FORM, $this->mOptions['form']); // if the given form is not a valid title, give up if (!$formTitle instanceof Title) { throw new MWException(wfMessage('sf_autoedit_invalidform', $this->mOptions['form'])->parse()); } // if the form page is a redirect, follow the redirect if ($formTitle->isRedirect()) { $this->logMessage('Form ' . $this->mOptions['form'] . ' is a redirect. Finding target.', self::DEBUG); $formWikiPage = WikiPage::factory($formTitle); if (method_exists($formWikiPage, 'getContent')) { // MW 1.21+ $formTitle = $formWikiPage->getContent(Revision::RAW)->getUltimateRedirectTarget(); } else { $formTitle = Title::newFromRedirectRecurse($formWikiPage->getRawText()); } // if we exeeded $wgMaxRedirects or encountered an invalid redirect target, give up if ($formTitle->isRedirect()) { $newTitle = WikiPage::factory($formTitle)->getRedirectTarget(); if ($newTitle instanceof Title && $newTitle->isValidRedirectTarget()) { throw new MWException(wfMessage('sf_autoedit_redirectlimitexeeded', $this->mOptions['form'])->parse()); } else { throw new MWException(wfMessage('sf_autoedit_invalidredirecttarget', $newTitle->getFullText(), $this->mOptions['form'])->parse()); } } } // if specified or found form does not exist (e.g. is a red link), give up // FIXME: Throw specialized error message, so a list of alternative forms can be shown if (!$formTitle->exists()) { throw new MWException(wfMessage('sf_autoedit_invalidform', $this->mOptions['form'])->parse()); } return $formTitle; }
function doRedirect($form_name, $page_name, $params) { global $wgOut; $page_title = Title::newFromText($page_name); if ($page_title->exists()) { // It exists - see if page is a redirect; if // it is, edit the target page instead. $article = new Article($page_title, 0); $article->loadContent(); $redirect_title = Title::newFromRedirect($article->fetchContent()); if ($redirect_title != null) { $page_title = $redirect_title; $page_name = SFUtils::titleURLString($redirect_title); } // HACK - if this is the default form for // this page, send to the regular 'formedit' // tab page; otherwise, send to the 'Special:FormEdit' // page, with the form name hardcoded. // Is this logic necessary? Or should we just // out-guess the user and always send to the // standard form-edit page, with the 'correct' form? $default_forms = SFFormLinker::getDefaultFormsForPage($page_title); if (count($default_forms) > 0) { $default_form_name = $default_forms[0]; } else { $default_form_name = null; } if ($form_name == $default_form_name) { $redirect_url = $page_title->getLocalURL('action=formedit'); } else { $redirect_url = self::getFormEditURL($form_name, $page_name); } } else { $redirect_url = self::getFormEditURL($form_name, $page_name); // Of all the request values, send on to 'FormEdit' // only 'preload' and specific form fields - we can // identify the latter because they show up as arrays. foreach ($_REQUEST as $key => $val) { if (is_array($val)) { $redirect_url .= strpos($redirect_url, '?') > -1 ? '&' : '?'; // Re-add the key (i.e. the template // name), so we can make a nice query // string snippet out of the whole // thing. $wrapperArray = array($key => $val); $redirect_url .= urldecode(http_build_query($wrapperArray)); } elseif ($key == 'preload') { $redirect_url .= strpos($redirect_url, '?') > -1 ? '&' : '?'; $redirect_url .= "{$key}={$val}"; } } } if (!is_null($params) && $params !== '') { $redirect_url .= strpos($redirect_url, '?') > -1 ? '&' : '?'; $redirect_url .= $params; } $wgOut->setArticleBodyOnly(true); // Show "loading" animated image while people wait for the // redirect. global $sfgScriptPath; $text = <<<END \t<p style="position: absolute; left: 45%; top: 45%;"> \t<img src="{$sfgScriptPath}/skins/loading.gif" /> \t</p> \t<meta http-equiv="refresh" content="0; url={$redirect_url}" /> END; $wgOut->addHTML($text); return; }
/** * The function called if we're in index.php (as opposed to one of the * special pages) */ static function displayForm($action, $article) { // TODO: This function will be called as a hook handler and $action will // be a string before MW 1.18. From 1.18 onwards this function will // only be called for formedit actions, i.e. the if statement can be // removed then. // return "true" if the call failed (meaning, pass on handling // of the hook to others), and "false" otherwise if (is_string($action) && $action !== 'formedit') { return true; } // @todo: This looks like bad code. If we can't find a form, we // should be showing an informative error page rather than // making it look like an edit form page does not exist. $title = $article->getTitle(); $form_names = SFFormLinker::getDefaultFormsForPage($title); if (count($form_names) == 0) { return true; } // For backward-compatibility if (is_string($action)) { global $wgOut; $output = $wgOut; } else { $output = $action->getOutput(); } if (count($form_names) > 1) { $warning_text = "\t" . '<div class="warningbox">' . wfMessage('sf_formedit_morethanoneform')->text() . "</div>\n"; $output->addWikiText($warning_text); } $form_name = $form_names[0]; $page_name = SFUtils::titleString($title); SFFormEdit::printForm($form_name, $page_name); return false; }
/** * The function called if we're in index.php (as opposed to one of the * special pages) */ static function displayForm($action, $article) { global $sfgUseFormEditPage; // TODO: This function will be called as a hook handler and $action will // be a string before MW 1.18. From 1.18 onwards this function will# // only be called for formedit actions, i.e. the if statement can be // removed then. // return "true" if the call failed (meaning, pass on handling // of the hook to others), and "false" otherwise if (is_string($action) && $action !== 'formedit') { return true; } // @todo: This looks like bad code. If we can't find a form, we // should be showing an informative error page rather than // making it look like an edit form page does not exist. $title = $article->getTitle(); $form_names = SFFormLinker::getDefaultFormsForPage($title); if (count($form_names) == 0) { return true; } // For backward-compatibility if (is_string($action)) { global $wgOut; $output = $wgOut; } else { $output = $action->getOutput(); } if (count($form_names) > 1) { $warning_text = "\t" . '<div class="warningbox">' . wfMsg('sf_formedit_morethanoneform') . "</div>\n"; $output->addWikiText($warning_text); } $form_name = $form_names[0]; if ($sfgUseFormEditPage) { # Experimental new feature extending from the internal # EditPage class $editor = new SFFormEditPage($article, $form_name); $editor->edit(); return false; } $page_name = SFUtils::titleString($title); $msg = SFFormEdit::printForm($form_name, $page_name); if ($msg) { // Some error occurred - display it. $msgdata = null; if (is_array($msg)) { if (count($msg) > 1) { $msgdata = $msg[1]; } $msg = $msg[0]; } $output->addHTML(Html::element('p', array('class' => 'error'), wfMsg($msg, $msgdata))); } return false; }
/** * Get the Title object of a form suitable for editing the target page. * * @return Title * @throws MWException */ protected function getFormTitle() { // if no form was specified, try finding the default form for the target page. if ($this->mOptions['form'] === '') { $this->logMessage('No form specified. Will try to find the default form for the target page.', self::DEBUG); // if no form and no target page was specified, give up if ($this->mOptions['target'] === '') { throw new MWException(wfMessage('sf_autoedit_notargetspecified')->parse()); } $targetTitle = Title::newFromText($this->mOptions['target']); // if the specified target title is invalid, give up if (!$targetTitle instanceof Title) { throw new MWException(wfMessage('sf_autoedit_invalidtargetspecified', $this->mOptions['target'])->parse()); } $formNames = SFFormLinker::getDefaultFormsForPage($targetTitle); // if no form can be found, give up if (count($formNames) === 0) { throw new MWException(wfMessage('sf_autoedit_noformfound')->parse()); } // if more than one form was found, issue a warning and use the first form // FIXME: If we have more than one form, should we stop? if (count($formNames) > 1) { $this->logMessage(wfMessage('sf_autoedit_toomanyformsfound')->parse(), self::WARNING); } $this->mOptions['form'] = $formNames[0]; $this->logMessage('Using ' . $this->mOptions['form'] . ' as default form.', self::DEBUG); } $formTitle = Title::makeTitleSafe(SF_NS_FORM, $this->mOptions['form']); // if the given form is not a valid title, give up if (!$formTitle instanceof Title) { throw new MWException(wfMessage('sf_autoedit_invalidform', $this->mOptions['form'])->parse()); } // if the form page is a redirect, follow the redirect if ($formTitle->isRedirect()) { $this->logMessage('Form ' . $this->mOptions['form'] . ' is a redirect. Finding target.', self::DEBUG); // FIXME: Title::newFromRedirectRecurse is deprecated as of MW 1.21 $formTitle = Title::newFromRedirectRecurse(WikiPage::factory($formTitle)->getRawText()); // if we exeeded $wgMaxRedirects or encountered an invalid redirect target, give up if ($formTitle->isRedirect()) { $newTitle = WikiPage::factory($formTitle)->getRedirectTarget(); if ($newTitle instanceof Title && $newTitle->isValidRedirectTarget()) { throw new MWException(wfMessage('sf_autoedit_redirectlimitexeeded', $this->mOptions['form'])->parse()); } else { throw new MWException(wfMessage('sf_autoedit_invalidredirecttarget', $newTitle->getFullText(), $this->mOptions['form'])->parse()); } } } // if specified or found form does not exist (e.g. is a red link), give up // FIXME: Throw specialized error message, so a list of alternative forms can be shown if (!$formTitle->exists()) { throw new MWException(wfMessage('sf_autoedit_invalidform', $this->mOptions['form'])->parse()); } return $formTitle; }