Example #1
0
 /**
  * Insert the captcha prompt into an edit form.
  * @param EditPage $editPage
  */
 function editShowCaptcha($editPage)
 {
     $context = $editPage->getArticle()->getContext();
     $page = $editPage->getArticle()->getPage();
     $out = $context->getOutput();
     if (isset($page->ConfirmEdit_ActivateCaptcha) || $this->showEditCaptcha || $this->shouldCheck($page, '', '', false)) {
         $out->addWikiText($this->getMessage($this->action));
         $out->addHTML($this->getForm());
     }
     unset($page->ConfirmEdit_ActivateCaptcha);
 }
 /**
  * Monitors edit page usage
  */
 public static function onEditForm(EditPage $editPage)
 {
     global $wgUser, $wgEditPageTrackingRegistrationCutoff, $wgMemc;
     // Anonymous users
     if ($wgUser->isAnon()) {
         return true;
     }
     if ($wgEditPageTrackingRegistrationCutoff && $wgUser->getRegistration() < $wgEditPageTrackingRegistrationCutoff) {
         // User registered before the cutoff
         return true;
     }
     if (EditPageTracking::getFirstEditPage($wgUser)) {
         // Already stored.
         return true;
     }
     // Record it
     $dbw = wfGetDB(DB_MASTER);
     $title = $editPage->getArticle()->getTitle();
     $timestamp = wfTimestampNow();
     $row = array('ept_user' => $wgUser->getId(), 'ept_namespace' => $title->getNamespace(), 'ept_title' => $title->getDBkey(), 'ept_timestamp' => $dbw->timestamp($timestamp));
     $dbw->insert('edit_page_tracking', $row, __METHOD__);
     $wgUser->mFirstEditPage = $timestamp;
     $cacheKey = wfMemcKey('first-edit-page', $wgUser->getId());
     $wgMemc->set($cacheKey, $timestamp, 86400);
     return true;
 }
 /**
  * @desc Redirects to Special:CSS if this is a try of edition of Wikia.css
  *
  * @param EditPage $editPage
  * @return bool
  */
 public static function onAlternateEdit(EditPage $editPage)
 {
     wfProfileIn(__METHOD__);
     $app = F::app();
     $model = new SpecialCssModel();
     if (static::shouldRedirect($app, $model, $editPage->getArticle()->getTitle())) {
         $oldid = $app->wg->Request->getIntOrNull('oldid');
         $app->wg->Out->redirect($model->getSpecialCssUrl(false, $oldid ? array('oldid' => $oldid) : null));
     }
     wfProfileOut(__METHOD__);
     return true;
 }
 /**
  * Guess the rev ID the text of this form is based off
  * Note: baseRevId trusted for Reviewers - check text for others.
  * @return int
  */
 protected static function getBaseRevId(EditPage $editPage, WebRequest $request)
 {
     if (!isset($editPage->fr_baseRevId)) {
         $article = $editPage->getArticle();
         // convenience
         $latestId = $article->getLatest();
         // current rev
         $undo = $request->getIntOrNull('undo');
         # Undoing consecutive top edits...
         if ($undo && $undo === $latestId) {
             # Treat this like a revert to a base revision.
             # We are undoing all edits *after* some rev ID (undoafter).
             # If undoafter is not given, then it is the previous rev ID.
             $revId = $request->getInt('undoafter', $article->getTitle()->getPreviousRevisionID($latestId, Title::GAID_FOR_UPDATE));
             # Undoing other edits...
         } elseif ($undo) {
             $revId = $latestId;
             // current rev is the base rev
             # Other edits...
         } else {
             # If we are editing via oldid=X, then use that rev ID.
             # Otherwise, check if the client specified the ID (bug 23098).
             $revId = $article->getOldID() ? $article->getOldID() : $request->getInt('baseRevId');
             // e.g. "show changes"/"preview"
         }
         # Zero oldid => draft revision
         if (!$revId) {
             $revId = $latestId;
         }
         $editPage->fr_baseRevId = $revId;
     }
     return $editPage->fr_baseRevId;
 }
Example #5
0
 /**
  * Appends a preview of the actual form, when a page in the "Form"
  * namespace is previewed.
  *
  * @author Solitarius
  * @since 2.4
  *
  * @param EditPage $editpage
  * @param WebRequest $request
  *
  * @return true
  */
 public static function showFormPreview(EditPage $editpage, WebRequest $request)
 {
     global $wgOut, $sfgFormPrinter;
     wfDebug(__METHOD__ . ": enter.\n");
     wfProfileIn(__METHOD__);
     // Exit if we're not in preview mode.
     if (!$editpage->preview) {
         wfProfileOut(__METHOD__);
         return true;
     }
     // Exit if we aren't in the "Form" namespace.
     if ($editpage->getArticle()->getTitle()->getNamespace() != SF_NS_FORM) {
         wfProfileOut(__METHOD__);
         return true;
     }
     $editpage->previewTextAfterContent .= Html::element('h2', null, wfMessage('sf-preview-header')->text()) . "\n" . '<div class="previewnote" style="font-weight: bold">' . $wgOut->parse(wfMessage('sf-preview-note')->text()) . "</div>\n<hr />\n";
     $form_definition = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $editpage->textbox1);
     list($form_text, $javascript_text, $data_text, $form_page_title, $generated_page_name) = $sfgFormPrinter->formHTML($form_definition, null, false, null, null, "Semantic Forms form preview dummy title", null);
     SFUtils::addJavascriptAndCSS();
     $editpage->previewTextAfterContent .= '<div style="margin-top: 15px">' . $form_text . "</div>";
     wfProfileOut(__METHOD__);
     return true;
 }
 /**
  * This is attached to the MediaWiki 'EditPage::attemptSave:after' hook.
  *
  * @param EditPage $editPage
  * @param Status $status
  * @return boolean
  */
 public static function editPageAttemptSaveAfter(EditPage $editPage, Status $status)
 {
     $article = $editPage->getArticle();
     $request = $article->getContext()->getRequest();
     if ($request->getVal('editingStatsId')) {
         $data = array();
         $data['editingSessionId'] = $request->getVal('editingStatsId');
         if ($status->isOK()) {
             $action = 'saveSuccess';
         } else {
             $action = 'saveFailure';
             $errors = $status->getErrorsArray();
             if (isset($errors[0][0])) {
                 $data['action.saveFailure.message'] = $errors[0][0];
             }
             if ($status->value === EditPage::AS_CONFLICT_DETECTED) {
                 $data['action.saveFailure.type'] = 'editConflict';
             } elseif ($status->value === EditPage::AS_ARTICLE_WAS_DELETED) {
                 $data['action.saveFailure.type'] = 'editPageDeleted';
             } elseif (isset($errors[0][0]) && $errors[0][0] === 'abusefilter-disallowed') {
                 $data['action.saveFailure.type'] = 'extensionAbuseFilter';
             } elseif (isset($editPage->getArticle()->getPage()->ConfirmEdit_ActivateCaptcha)) {
                 // TODO: :(
                 $data['action.saveFailure.type'] = 'extensionCaptcha';
             } elseif (isset($errors[0][0]) && $errors[0][0] === 'spamprotectiontext') {
                 $data['action.saveFailure.type'] = 'extensionSpamBlacklist';
             } else {
                 // Catch everything else... We don't seem to get userBadToken or
                 // userNewUser through this hook.
                 $data['action.saveFailure.type'] = 'responseUnknown';
             }
         }
         self::doEventLogging($action, $article, $data);
     }
     return true;
 }
 /**
  * @param EditPage $editpage
  * @return string
  */
 private static function editBoxes(EditPage $editpage)
 {
     $context = $editpage->getArticle()->getContext();
     $request = $context->getRequest();
     $groupId = $request->getText('loadgroup', '');
     $th = new TranslationHelpers($editpage->getTitle(), $groupId);
     if ($editpage->firsttime && !$request->getCheck('oldid') && !$request->getCheck('undo')) {
         $editpage->textbox1 = (string) $th->getTranslation();
     } else {
         $th->setTranslation($editpage->textbox1);
     }
     TranslationHelpers::addModules($context->getOutput());
     return $th->getBoxes();
 }
 protected function doStore(EditPage $editor)
 {
     $title = $editor->getTitle();
     // If they used redlink=1 and the page exists, redirect to the main article and send notice
     if ($this->getRequest()->getBool('redlink') && $title->exists()) {
         $this->logMessage(wfMessage('sf_autoedit_redlinkexists')->parse(), self::WARNING);
     }
     $permErrors = $title->getUserPermissionsErrors('edit', $this->getUser());
     // if this title needs to be created, user needs create rights
     if (!$title->exists()) {
         $permErrors = array_merge($permErrors, wfArrayDiff2($title->getUserPermissionsErrors('create', $this->getUser()), $permErrors));
     }
     if ($permErrors) {
         // Auto-block user's IP if the account was "hard" blocked
         $this->getUser()->spreadAnyEditBlock();
         foreach ($permErrors as $error) {
             $this->logMessage(call_user_func_array('wfMessage', $error)->parse());
         }
         return;
     }
     $resultDetails = false;
     # Allow bots to exempt some edits from bot flagging
     $bot = $this->getUser()->isAllowed('bot') && $editor->bot;
     $request = $editor->sfFauxRequest;
     if ($editor->tokenOk($request)) {
         $ctx = RequestContext::getMain();
         $tempTitle = $ctx->getTitle();
         $ctx->setTitle($title);
         $status = $editor->internalAttemptSave($resultDetails, $bot);
         $ctx->setTitle($tempTitle);
     } else {
         throw new MWException(wfMessage('session_fail_preview')->parse());
     }
     switch ($status->value) {
         case EditPage::AS_HOOK_ERROR_EXPECTED:
             // A hook function returned an error
             // show normal Edit page
             // remove Preview and Diff standard buttons from editor page
             Hooks::register('EditPageBeforeEditButtons', function (&$editor, &$buttons, &$tabindex) {
                 foreach (array_keys($buttons) as $key) {
                     if ($key !== 'save') {
                         unset($buttons[$key]);
                     }
                 }
             });
             // Context title needed for correct Cancel link
             $editor->setContextTitle($title);
             $editor->showEditForm();
             return false;
             // success
         // success
         case EditPage::AS_CONTENT_TOO_BIG:
             // Content too big (> $wgMaxArticleSize)
         // Content too big (> $wgMaxArticleSize)
         case EditPage::AS_ARTICLE_WAS_DELETED:
             // article was deleted while editting and param wpRecreate == false or form was not posted
         // article was deleted while editting and param wpRecreate == false or form was not posted
         case EditPage::AS_CONFLICT_DETECTED:
             // (non-resolvable) edit conflict
         // (non-resolvable) edit conflict
         case EditPage::AS_SUMMARY_NEEDED:
             // no edit summary given and the user has forceeditsummary set and the user is not editting in his own userspace or talkspace and wpIgnoreBlankSummary == false
         // no edit summary given and the user has forceeditsummary set and the user is not editting in his own userspace or talkspace and wpIgnoreBlankSummary == false
         case EditPage::AS_TEXTBOX_EMPTY:
             // user tried to create a new section without content
         // user tried to create a new section without content
         case EditPage::AS_MAX_ARTICLE_SIZE_EXCEEDED:
             // article is too big (> $wgMaxArticleSize), after merging in the new section
         // article is too big (> $wgMaxArticleSize), after merging in the new section
         case EditPage::AS_END:
             // WikiPage::doEdit() was unsuccessfull
             throw new MWException(wfMessage('sf_autoedit_fail', $this->mOptions['target'])->parse());
         case EditPage::AS_HOOK_ERROR:
             // Article update aborted by a hook function
             $this->logMessage('Article update aborted by a hook function', self::DEBUG);
             return false;
             // success
             // TODO: This error code only exists from 1.21 onwards. It is
             // suitably handled by the default branch, but really should get its
             // own branch. Uncomment once compatibility to pre1.21 is dropped.
             //			case EditPage::AS_PARSE_ERROR: // can't parse content
             //
             //				throw new MWException( $status->getHTML() );
             //				return true; // fail
         // success
         // TODO: This error code only exists from 1.21 onwards. It is
         // suitably handled by the default branch, but really should get its
         // own branch. Uncomment once compatibility to pre1.21 is dropped.
         //			case EditPage::AS_PARSE_ERROR: // can't parse content
         //
         //				throw new MWException( $status->getHTML() );
         //				return true; // fail
         case EditPage::AS_SUCCESS_NEW_ARTICLE:
             // Article successfully created
             $query = $resultDetails['redirect'] ? 'redirect=no' : '';
             $anchor = isset($resultDetails['sectionanchor']) ? $resultDetails['sectionanchor'] : '';
             $this->getOutput()->redirect($title->getFullURL($query) . $anchor);
             $this->getResult()->addValue(NULL, 'redirect', $title->getFullURL($query) . $anchor);
             return false;
             // success
         // success
         case EditPage::AS_SUCCESS_UPDATE:
             // Article successfully updated
             $extraQuery = '';
             $sectionanchor = $resultDetails['sectionanchor'];
             // Give extensions a chance to modify URL query on update
             Hooks::run('ArticleUpdateBeforeRedirect', array($editor->getArticle(), &$sectionanchor, &$extraQuery));
             if ($resultDetails['redirect']) {
                 if ($extraQuery == '') {
                     $extraQuery = 'redirect=no';
                 } else {
                     $extraQuery = 'redirect=no&' . $extraQuery;
                 }
             }
             $this->getOutput()->redirect($title->getFullURL($extraQuery) . $sectionanchor);
             $this->getResult()->addValue(NULL, 'redirect', $title->getFullURL($extraQuery) . $sectionanchor);
             return false;
             // success
         // success
         case EditPage::AS_BLANK_ARTICLE:
             // user tried to create a blank page
             $this->logMessage('User tried to create a blank page', self::DEBUG);
             $this->getOutput()->redirect($editor->getContextTitle()->getFullURL());
             $this->getResult()->addValue(NULL, 'redirect', $editor->getContextTitle()->getFullURL());
             return false;
             // success
         // success
         case EditPage::AS_SPAM_ERROR:
             // summary contained spam according to one of the regexes in $wgSummarySpamRegex
             $match = $resultDetails['spam'];
             if (is_array($match)) {
                 $match = $this->getLanguage()->listToText($match);
             }
             throw new MWException(wfMessage('spamprotectionmatch', wfEscapeWikiText($match))->parse());
             // FIXME: Include better error message
         // FIXME: Include better error message
         case EditPage::AS_BLOCKED_PAGE_FOR_USER:
             // User is blocked from editting editor page
             throw new UserBlockedError($this->getUser()->getBlock());
         case EditPage::AS_IMAGE_REDIRECT_ANON:
             // anonymous user is not allowed to upload (User::isAllowed('upload') == false)
         // anonymous user is not allowed to upload (User::isAllowed('upload') == false)
         case EditPage::AS_IMAGE_REDIRECT_LOGGED:
             // logged in user is not allowed to upload (User::isAllowed('upload') == false)
             throw new PermissionsError('upload');
         case EditPage::AS_READ_ONLY_PAGE_ANON:
             // editor anonymous user is not allowed to edit editor page
         // editor anonymous user is not allowed to edit editor page
         case EditPage::AS_READ_ONLY_PAGE_LOGGED:
             // editor logged in user is not allowed to edit editor page
             throw new PermissionsError('edit');
         case EditPage::AS_READ_ONLY_PAGE:
             // wiki is in readonly mode (wfReadOnly() == true)
             throw new ReadOnlyError();
         case EditPage::AS_RATE_LIMITED:
             // rate limiter for action 'edit' was tripped
             throw new ThrottledError();
         case EditPage::AS_NO_CREATE_PERMISSION:
             // user tried to create editor page, but is not allowed to do that ( Title->usercan('create') == false )
             $permission = $title->isTalkPage() ? 'createtalk' : 'createpage';
             throw new PermissionsError($permission);
         default:
             // We don't recognize $status->value. The only way that can happen
             // is if an extension hook aborted from inside ArticleSave.
             // Render the status object into $editor->hookError
             $editor->hookError = '<div class="error">' . $status->getWikitext() . '</div>';
             throw new MWException($status->getHTML());
     }
 }
 /**
  * Guess the alternative rev ID the text of this form is based off.
  * When undoing the top X edits, the base can be though of as either
  * the current or the edit X edits prior to the latest.
  * Note: baseRevId trusted for Reviewers - check text for others.
  * @param EditPage $editPage
  * @param WebRequest $request
  * @return int
  */
 protected static function getAltBaseRevId(EditPage $editPage, WebRequest $request)
 {
     if ($editPage->isConflict) {
         return 0;
         // throw away these values (bug 33481)
     }
     if (!isset($editPage->fr_altBaseRevId)) {
         $article = $editPage->getArticle();
         // convenience
         $latestId = $article->getLatest();
         // current rev
         $undo = $request->getIntOrNull('undo');
         # Undoing consecutive top edits...
         if ($undo && $undo === $latestId) {
             # Treat this like a revert to a base revision.
             # We are undoing all edits *after* some rev ID (undoafter).
             # If undoafter is not given, then it is the previous rev ID.
             $revId = $request->getInt('undoafter', $article->getTitle()->getPreviousRevisionID($latestId, Title::GAID_FOR_UPDATE));
         } else {
             $revId = $request->getInt('altBaseRevId');
         }
         $editPage->fr_altBaseRevId = $revId;
     }
     return $editPage->fr_altBaseRevId;
 }
Example #10
0
/**
 * This function is called when an article is modified via the Mediawiki API.
 * The article's name is stored for later update with the IAI bot 
 * (see iaifArticleSaveComplete).
 *
 * @param EditPage $editPage
 * @param string $text
 * @param array $resultArr
 * @return bool true
 */
function iaifAPIEditBeforeSave(&$editPage, $text, &$resultArr)
{
    iaifStartLog("iaifAPIEditBeforeSave");
    global $iaigIP;
    global $iaigUpdateWithBot;
    $t = $editPage->getArticle()->getTitle()->getFullText();
    $iaigUpdateWithBot[] = $t;
    global $iaigLog, $iaigStartTime;
    fprintf($iaigLog, "iaifAPIEditBeforeSave: %f (ms)\n", (microtime(true) - $iaigStartTime) / 1000);
    iaifEndLog("iaifAPIEditBeforeSave");
    return true;
}
Example #11
0
 /**
  * Display header on 'Task:' pages (dummy hook for edit pages)
  * @param EditPage $editPage
  */
 public static function onEditPageShowEditFormInitial(&$editPage)
 {
     # Checked for HTML and MySQL insertion attacks
     return self::onArticleViewHeader($editPage->getArticle());
 }
Example #12
0
 /**
  * EditPageBeforeEditButtons hook
  * Add draft saving controls
  */
 public static function onEditPageBeforeEditButtons(EditPage $editpage, $buttons, &$tabindex)
 {
     global $egDraftsAutoSaveWait, $egDraftsAutoSaveTimeout, $egDraftsAutoSaveInputBased;
     $context = $editpage->getArticle()->getContext();
     $user = $context->getUser();
     if (!$user->getOption('extensionDrafts_enable', 'true')) {
         return true;
     }
     // Check permissions
     if ($user->isAllowed('edit') && $user->isLoggedIn()) {
         $request = $context->getRequest();
         // Build XML
         $buttons['savedraft'] = Xml::openElement('script', array('type' => 'text/javascript', 'language' => 'javascript'));
         $buttonAttribs = array('id' => 'wpDraftSave', 'name' => 'wpDraftSave', 'class' => 'button secondary disabled', 'tabindex' => ++$tabindex, 'value' => $context->msg('drafts-save-save')->text());
         $attribs = Linker::tooltipAndAccesskeyAttribs('drafts-save');
         if (isset($attribs['accesskey'])) {
             $buttonAttribs['accesskey'] = $attribs['accesskey'];
         }
         if (isset($attribs['tooltip'])) {
             $buttonAttribs['title'] = $attribs['title'];
         }
         $ajaxButton = Xml::escapeJsString(Xml::element('input', array('type' => 'submit') + $buttonAttribs + ($request->getText('action') !== 'submit' ? array('disabled' => 'disabled') : array())));
         $buttons['savedraft'] .= "document.write( '{$ajaxButton}' );";
         $buttons['savedraft'] .= Xml::closeElement('script');
         $buttons['savedraft'] .= Xml::openElement('noscript');
         $buttons['savedraft'] .= Xml::element('input', array('type' => 'submit') + $buttonAttribs);
         $buttons['savedraft'] .= Xml::closeElement('noscript');
         $buttons['savedraft'] .= Xml::element('input', array('type' => 'hidden', 'name' => 'wpDraftToken', 'value' => MWCryptRand::generateHex(32)));
         $buttons['savedraft'] .= Xml::element('input', array('type' => 'hidden', 'name' => 'wpDraftID', 'value' => $request->getInt('draft', '')));
         $buttons['savedraft'] .= Xml::element('input', array('type' => 'hidden', 'name' => 'wpDraftTitle', 'value' => $context->getTitle()->getPrefixedText()));
     }
     // Continue
     return true;
 }