/**
  * Executes special page rendering and data processing
  *
  * @param $sub Mixed: MediaWiki supplied sub-page path
  * @throws PermissionsError
  */
 public function execute($sub)
 {
     $out = $this->getOutput();
     $user = $this->getUser();
     $request = $this->getRequest();
     // Begin output
     $this->setHeaders();
     // Make sure the user is logged in
     if (!$user->isLoggedIn()) {
         throw new PermissionsError('read');
     }
     // Handle discarding
     $draft = Draft::newFromID($request->getIntOrNull('discard'));
     if ($draft->exists()) {
         // Discard draft
         $draft->discard();
         // Redirect to the article editor or view if returnto was set
         $section = $request->getIntOrNull('section');
         $urlSection = $section !== null ? "&section={$section}" : '';
         switch ($request->getText('returnto')) {
             case 'edit':
                 $title = Title::newFromDBKey($draft->getTitle());
                 $out->redirect(wfExpandURL($title->getEditURL() . $urlSection));
                 break;
             case 'view':
                 $title = Title::newFromDBKey($draft->getTitle());
                 $out->redirect(wfExpandURL($title->getFullURL() . $urlSection));
                 break;
         }
     }
     // Show list of drafts, or a message that there are none
     if (Drafts::display() == 0) {
         $out->addWikiMsg('drafts-view-nonesaved');
     }
 }
 public function execute()
 {
     if ($this->getUser()->isAnon()) {
         $this->dieUsage('You must be logged in to save drafts.', 'notloggedin');
     }
     $params = $this->extractRequestParams();
     $draft = Draft::newFromID($params['id']);
     $draft->setToken($params['drafttoken']);
     $draft->setTitle(Title::newFromText($params['title']));
     $draft->setSection($params['section'] == '' ? null : $params['section']);
     $draft->setStartTime($params['starttime']);
     $draft->setEditTime($params['edittime']);
     $draft->setSaveTime(wfTimestampNow());
     $draft->setScrollTop($params['scrolltop']);
     $draft->setText($params['text']);
     $draft->setSummary($params['summary']);
     $draft->setMinorEdit($params['minoredit']);
     $draft->save();
     $this->getResult()->addValue(null, $this->getModuleName(), array('id' => $draft->getID()));
 }
Beispiel #3
0
 /**
  * Executes special page rendering and data processing
  *
  * @param $sub Mixed: MediaWiki supplied sub-page path
  */
 public function execute($sub)
 {
     global $wgRequest, $wgOut, $wgUser;
     // Begin output
     $this->setHeaders();
     // Make sure the user is logged in
     if (!$wgUser->isLoggedIn()) {
         // If not, let them know they need to
         $wgOut->loginToUse();
         // Continue
         return true;
     }
     // Handle discarding
     $draft = Draft::newFromID($wgRequest->getIntOrNull('discard'));
     if ($draft->exists()) {
         // Discard draft
         $draft->discard();
         // Redirect to the article editor or view if returnto was set
         $section = $wgRequest->getIntOrNull('section');
         $urlSection = $section !== null ? "&section={$section}" : '';
         switch ($wgRequest->getText('returnto')) {
             case 'edit':
                 $title = Title::newFromDBKey($draft->getTitle());
                 $wgOut->redirect(wfExpandURL($title->getEditURL() . $urlSection));
                 break;
             case 'view':
                 $title = Title::newFromDBKey($draft->getTitle());
                 $wgOut->redirect(wfExpandURL($title->getFullURL() . $urlSection));
                 break;
         }
     }
     // Show list of drafts, or a message that there are none
     if (Drafts::display() == 0) {
         $wgOut->addHTML(wfMsgHTML('drafts-view-nonesaved'));
     }
 }
Beispiel #4
0
 public static function listDrafts(&$title = null, $user = null)
 {
     global $wgOut, $wgRequest, $wgUser, $wgLang;
     //added twice?
     $wgOut->addScript('<style type="text/css" media="all">/*<![CDATA[*/ @import "' . wfGetPad('/extensions/min/f/extensions/Drafts/Drafts.css?rev=') . WH_SITEREV . '"; /*]]>*/</style>');
     // Get draftID
     $currentDraft = Draft::newFromID($wgRequest->getIntOrNull('draft'));
     //based on user preference
     $adv = $wgUser->getOption('defaulteditor', '') == 'advanced' ? '&advanced=true' : '';
     // Output HTML for list of drafts
     $drafts = Draft::getDrafts($title, $user);
     if (count($drafts) > 0) {
         global $egDraftsLifeSpan;
         // Internationalization
         wfLoadExtensionMessages('Drafts');
         // Add a summary, on Special:Drafts only
         if (!$title || $title->getNamespace() == NS_SPECIAL) {
             $wgOut->wrapWikiMsg('<div class="mw-drafts-summary">$1</div>', array('drafts-view-summary', $wgLang->formatNum($egDraftsLifeSpan)));
         }
         // Build XML
         $wgOut->addHTML(Xml::openElement('table', array('cellpadding' => 5, 'cellspacing' => 0, 'border' => 0, 'id' => 'drafts-list-table', 'class' => 'section_text', 'style' => 'margin-top:15px')));
         $wgOut->addHTML(Xml::openElement('tr'));
         $wgOut->addHTML(Xml::element('th', array('align' => 'left', 'nowrap' => 'nowrap', 'style' => 'text-align:center;'), wfMsg('drafts-view-article')));
         $wgOut->addHTML(Xml::element('th', array('align' => 'left', 'nowrap' => 'nowrap', 'style' => 'text-align:center;'), wfMsg('drafts-view-saved')));
         $wgOut->addHTML(Xml::element('th', array(), wfMsg('edit')));
         $wgOut->addHTML(Xml::element('th', array(), wfMsg('discard')));
         $wgOut->addHTML(Xml::closeElement('tr'));
         // Add existing drafts for this page and user
         $index = 0;
         foreach ($drafts as $draft) {
             // Get article title text
             $htmlTitle = $draft->getTitle()->getEscapedText();
             // Build Article Load link
             if ($draft->getHTML5()) {
                 $params = 'h5e=true&draft=' . urlencode($draft->getID());
                 if ($draft->getTitle()->getArticleID() == 0) {
                     $params .= "&create-new-article=true";
                 }
                 $urlLoad = $draft->getTitle()->getFullUrl($params);
             } else {
                 $urlLoad = $draft->getTitle()->getFullUrl('action=edit' . $adv . '&draft=' . urlencode($draft->getID()));
             }
             // Build discard link
             $urlDiscard = sprintf('%s?discard=%s&token=%s', SpecialPage::getTitleFor('Drafts')->getFullUrl(), urlencode($draft->getID()), urlencode($wgUser->editToken()));
             // If in edit mode, return to editor
             if ($wgRequest->getText('action') == 'edit' || $wgRequest->getText('action') == 'submit') {
                 $urlDiscard .= '&returnto=' . urlencode('edit');
             }
             // Append section to titles and links
             if ($draft->getSection() !== null) {
                 // Detect section name
                 $lines = explode("\n", $draft->getText());
                 // If there is any content in the section
                 if (count($lines) > 0) {
                     $htmlTitle .= '#' . htmlspecialchars(trim(trim(substr($lines[0], 0, 255), '=')));
                 }
                 // Modify article link and title
                 $urlLoad .= '&section=' . urlencode($draft->getSection());
                 $urlDiscard .= '&section=' . urlencode($draft->getSection());
             }
             // Build XML
             if ($index % 2 == 1) {
                 $wgOut->addHTML(Xml::openElement('tr', array('style' => 'background: #eee;')));
             } else {
                 $wgOut->addHTML(Xml::openElement('tr', array('style' => '')));
             }
             $wgOut->addHTML(Xml::openElement('td', array('align' => 'left', 'class' => 'draftpage')));
             $wgOut->addHTML(Xml::element('a', array('href' => $urlLoad, 'style' => 'font-weight:' . ($currentDraft->getID() == $draft->getID() ? 'bold' : 'normal')), $htmlTitle));
             $wgOut->addHTML(Xml::closeElement('td'));
             $wgOut->addHTML(Xml::element('td', array('align' => 'left', 'nowrap' => 'nowrap', 'class' => 'draftsaved'), $wgLang->timeanddate($draft->getSaveTime(), true)));
             // edit link
             $wgOut->addHTML(Xml::openElement('td', array('align' => 'left', 'nowrap' => 'nowrap', 'class' => 'draftedit')));
             $wgOut->addHTML(Xml::element('a', array('href' => $urlLoad), wfMsg('edit')));
             $wgOut->addHTML(Xml::closeElement('td'));
             $wgOut->addHTML(Xml::openElement('td', array('align' => 'left', 'nowrap' => 'nowrap', 'class' => 'draftdiscard')));
             $wgOut->addHTML(Xml::element('a', array('href' => $urlDiscard, 'onclick' => "if( true || !wgAjaxSaveDraft.insync ) return confirm('" . Xml::escapeJsString(wfMsgHTML('drafts-discard-warn', $draft->getTitle()->getText())) . "')"), wfMsg('drafts-view-discard')));
             $wgOut->addHTML(Xml::closeElement('td'));
             $wgOut->addHTML(Xml::closeElement('tr'));
             $index++;
         }
         $wgOut->addHTML(Xml::closeElement('table'));
         // Return number of drafts
         return count($drafts);
     }
     return 0;
 }
 function execute($par)
 {
     global $wgOut, $wgRequest, $wgParser, $wgUser, $wgFilterCallback, $wgCookiePath, $wgCookieDomain, $wgCookieSecure;
     $wgOut->disable();
     // build the article which we are about to save
     $t = Title::newFromUrl($wgRequest->getVal('target'));
     $a = new Article($t);
     $action = $wgRequest->getVal('eaction');
     wfDebug("Html5Editor::execute called with {$action}\n");
     // process the edit update
     if ($action == 'get-vars') {
         $wgOut->disable();
         $response = array('edittoken' => $wgUser->editToken(), 'edittime' => $a->getTimestamp(true), 'drafttoken' => wfGenerateToken(), 'olddraftid' => 0);
         // do they already have a draft saved?
         $drafts = Draft::getDrafts($t, $wgUser->getID());
         if ($drafts) {
             // do we only select an html5 draft? probably not.
             // for loop here in  case we want to display multiple drafts of same article
             $response['olddraftid'] = $drafts[0]->getID();
         }
         print json_encode($response);
         return;
     } else {
         if ($action == 'load-draft') {
             $draftid = $wgRequest->getVal('draftid');
             $draft = new Draft($draftid);
             if (!$draft->exists()) {
                 wfLoadExtensionMessages("Html5editor");
                 $response = array('error' => wfMsg('h5e-draft-does-not-exist', $draftid), 'html' => '');
                 wfDebug("DRAFT: {$draftid} does not exist \n");
             } else {
                 $text = $draft->getText();
                 $html = $this->parse($t, $a, $text);
                 $response = array(error => '', 'html' => $html);
             }
             print json_encode($response);
             return;
         } else {
             if ($action == 'save-draft') {
                 $token = $wgRequest->getVal('edittoken');
                 if ($wgUser->matchEditToken($token)) {
                     wfDebug("Html5Editor::execute save-draft edit token ok!\n");
                     $oldtext = $a->getContent();
                     $html = $wgRequest->getVal('html');
                     $newtext = $this->convertHTML2Wikitext($html, $oldtext);
                     $draftid = $wgRequest->getVal('draftid', null);
                     $draft = null;
                     // 'null' apparently is what javascript is giving us. doh.
                     if (!$draftid || preg_match("@[^0-9]@", $draftid)) {
                         wfDebug("Html5Editor::execute getting draft id from title \n");
                         $draftid = self::getDraftIDFromTitle($t);
                     }
                     if (!$draftid || $draftid == 'null') {
                         $draft = new Draft();
                     } else {
                         $draft = Draft::newFromID($draftid);
                     }
                     wfDebug("Html5Editor::execute got draft id {$draftid} \n");
                     $draft->setTitle($t);
                     //$draft->setStartTime( $wgRequest->getText( 'wpStarttime' ) );
                     $draft->setEditTime($wgRequest->getText('edittime'));
                     $draft->setSaveTime(wfTimestampNow());
                     $draft->setText($newtext);
                     $draft->setSummary($wgRequest->getText('editsummary'));
                     $draft->setHtml5(true);
                     //$draft->setMinorEdit( $wgRequest->getInt( 'wpMinoredit', 0 ) );
                     // Save draft
                     $draft->save();
                     wfDebug("Html5Editor::execute saved draft with id {$draft->getID()} and text {$newtext} \n");
                     $response = array('draftid' => $draft->getID());
                     print json_encode($response);
                     return;
                 } else {
                     wfDebug("Html5Editor::execute save-draft edit token BAD {$token} \n");
                     $response = array('error' => 'edit token bad');
                     print json_encode($response);
                     return;
                 }
                 return;
             } else {
                 if ($action == 'save-summary') {
                     // this implementation could have a few problems
                     // 1. if a user is editing the article in separate windows, it will
                     //		only update the last edit
                     // 2. Could be easy to fake an edit summary save, but is limited to
                     // edits made by the user
                     /// 3. There's no real 'paper' trail of the saved summary
                     // grab the cookie with the rev_id
                     global $wgCookiePrefix;
                     if (isset($_COOKIE["{$wgCookiePrefix}RevId" . $t->getArticleID()])) {
                         $revid = $_COOKIE["{$wgCookiePrefix}RevId" . $t->getArticleID()];
                         wfDebug("AXX: updating revcomment {$revid} \n");
                         $dbw = wfGetDB(DB_MASTER);
                         $summary = "updating from html5 editor, " . $wgRequest->getVal('summary');
                         $dbw->update('revision', array('rev_comment' => $summary), array('rev_id' => $revid, 'rev_user_text' => $wgUser->getName()), "Html5Editor::saveComment", array("LIMIT" => 1));
                         $dbw->update('recentchanges', array('rc_comment' => $summary), array('rc_this_oldid' => $revid, 'rc_user_text' => $wgUser->getName()), "Html5Editor::saveComment", array("LIMIT" => 1));
                     } else {
                         wfDebug("AXX: NOT updating revcomment, why\n");
                     }
                     return;
                 } else {
                     if ($action == 'publish-html') {
                         // check the edit token
                         $token = $wgRequest->getVal('edittoken');
                         if (!$wgUser->matchEditToken($token)) {
                             $response = array('error' => wfMsg('sessionfailure'));
                             print json_encode($response);
                             return;
                         }
                         // check the edit time and check for a conflict
                         $edittime = $wgRequest->getVal('edittime');
                         if (!preg_match('/^\\d{14}$/', $edittime)) {
                             $edittime = null;
                         }
                         if (!$edittime) {
                             $response = array('error' => 'missing or invalid edit time');
                             print json_encode($response);
                             return;
                         }
                         if ($response = $this->getPermissionErrors($t)) {
                             print json_encode($response);
                             return;
                         }
                         $newArticle = !$t->exists();
                         $a = new Article($t);
                         // check for edit conflict
                         //	if( $this->mArticle->getTimestamp() != $this->edittime ) {
                         //   $this->isConflict = true;
                         //	}
                         // now ... let's convert the HTML back into wikitext... holy crap, we are nuts
                         $oldtext = $a->getContent();
                         $html = $wgRequest->getVal('html');
                         $newtext = $this->convertHTML2Wikitext($html, $oldtext);
                         // filter callback?
                         if ($wgFilterCallback && $wgFilterCallback($t, $newtext, null)) {
                             # Error messages or other handling should be performed by the filter function
                             $response = array('error' => self::$spam_message, 'html' => $html);
                             print json_encode($response);
                             return;
                         }
                         // do the save
                         // TODO: check for conflicts (obviously)
                         if ($a->doEdit($newtext, $wgRequest->getVal('summary') . " (HTML5) ")) {
                             //$alerts = new MailAddress("*****@*****.**");
                             //UserMailer::send($alerts, $alerts, "HTML5 Ouput for {$t->getText()}", "{$t->getFullURL()}?action=history \n HTML: " . trim($html) . "\n\nwikitext:\n $newtext\n\n\nUser: "******"\n\n\n\nPOST: " . print_r($_POST, true) );
                             $r = Revision::newFromTitle($t);
                             $this->setRevCookie($t, $r);
                             #$html = WikihowArticleHTML::postProcess($wgOut->parse($newtext));
                             $html = $this->parse($t, $a, $newtext);
                             // Create an anon attribution cookie
                             if ($newArticle && $wgUser->getId() == 0) {
                                 setcookie('aen_anon_newarticleid', $a->getId(), time() + 3600, $wgCookiePath, $wgCookieDomain, $wgCookieSecure);
                             }
                             $response = array(error => '', 'html' => $html);
                             print json_encode($response);
                             return;
                         } else {
                             $response = array(error => 'Error saving', 'html' => '');
                             print json_encode($response);
                             return;
                         }
                     }
                 }
             }
         }
     }
     return;
 }
Beispiel #6
0
 /**
  * Outputs a table of existing drafts
  *
  * @param $title Object: [optional] Title of article, defaults to all articles
  * @param $userID Integer: [optional] ID of user, defaults to current user
  * @return Number of drafts in the table
  */
 public static function display($title = null, $userID = null)
 {
     global $wgOut, $wgRequest, $wgUser, $wgLang;
     // Gets draftID
     $currentDraft = Draft::newFromID($wgRequest->getIntOrNull('draft'));
     // Output HTML for list of drafts
     $drafts = Drafts::get($title, $userID);
     if (count($drafts) > 0) {
         global $egDraftsLifeSpan;
         // Internationalization
         // Add a summary, on Special:Drafts only
         if (!$title || $title->getNamespace() == NS_SPECIAL) {
             $wgOut->wrapWikiMsg('<div class="mw-drafts-summary">$1</div>', array('drafts-view-summary', $wgLang->formatNum($egDraftsLifeSpan)));
         }
         // Build XML
         $wgOut->addHTML(Xml::openElement('table', array('cellpadding' => 5, 'cellspacing' => 0, 'width' => '100%', 'border' => 0, 'id' => 'drafts-list-table')));
         $wgOut->addHTML(Xml::openElement('tr'));
         $wgOut->addHTML(Xml::element('th', array('width' => '75%', 'nowrap' => 'nowrap'), wfMsg('drafts-view-article')));
         $wgOut->addHTML(Xml::element('th', null, wfMsg('drafts-view-saved')));
         $wgOut->addHTML(Xml::element('th'));
         $wgOut->addHTML(Xml::closeElement('tr'));
         // Add existing drafts for this page and user
         foreach ($drafts as $draft) {
             // Get article title text
             $htmlTitle = $draft->getTitle()->getEscapedText();
             // Build Article Load link
             $urlLoad = $draft->getTitle()->getFullURL('action=edit&draft=' . urlencode($draft->getID()));
             // Build discard link
             $urlDiscard = SpecialPage::getTitleFor('Drafts')->getFullURL(sprintf('discard=%s&token=%s', urlencode($draft->getID()), urlencode($wgUser->editToken())));
             // If in edit mode, return to editor
             if ($wgRequest->getText('action') == 'edit' || $wgRequest->getText('action') == 'submit') {
                 $urlDiscard .= '&returnto=' . urlencode('edit');
             }
             // Append section to titles and links
             if ($draft->getSection() !== null) {
                 // Detect section name
                 $lines = explode("\n", $draft->getText());
                 // If there is any content in the section
                 if (count($lines) > 0) {
                     $htmlTitle .= '#' . htmlspecialchars(trim(trim(substr($lines[0], 0, 255), '=')));
                 }
                 // Modify article link and title
                 $urlLoad .= '&section=' . urlencode($draft->getSection());
                 $urlDiscard .= '&section=' . urlencode($draft->getSection());
             }
             // Build XML
             $wgOut->addHTML(Xml::openElement('tr'));
             $wgOut->addHTML(Xml::openElement('td'));
             $wgOut->addHTML(Xml::element('a', array('href' => $urlLoad, 'style' => 'font-weight:' . ($currentDraft->getID() == $draft->getID() ? 'bold' : 'normal')), $htmlTitle));
             $wgOut->addHTML(Xml::closeElement('td'));
             $wgOut->addHTML(Xml::element('td', null, $wgLang->timeanddate($draft->getSaveTime(), true)));
             $wgOut->addHTML(Xml::openElement('td'));
             $jsClick = "if( wgDraft.getState() !== 'unchanged' )" . "return confirm('" . Xml::escapeJsString(wfMsgHTML('drafts-view-warn')) . "')";
             $wgOut->addHTML(Xml::element('a', array('href' => $urlDiscard, 'onclick' => $jsClick), wfMsg('drafts-view-discard')));
             $wgOut->addHTML(Xml::closeElement('td'));
             $wgOut->addHTML(Xml::closeElement('tr'));
         }
         $wgOut->addHTML(Xml::closeElement('table'));
         // Return number of drafts
         return count($drafts);
     }
     return 0;
 }
Beispiel #7
0
 /**
  * AJAX function export DraftHooks::AjaxSave
  * Respond to ajax queries
  */
 public static function AjaxSave($dtoken, $etoken, $id, $title, $section, $starttime, $edittime, $scrolltop, $text, $summary, $minoredit)
 {
     global $wgUser, $wgRequest;
     // Verify token
     if ($wgUser->editToken() == $etoken) {
         // Create Draft
         $draft = Draft::newFromID($id);
         // Load draft with info
         $draft->setToken($dtoken);
         $draft->setTitle(Title::newFromText($title));
         $draft->setSection($section == '' ? null : $section);
         $draft->setStartTime($starttime);
         $draft->setEditTime($edittime);
         $draft->setSaveTime(wfTimestampNow());
         $draft->setScrollTop($scrolltop);
         $draft->setText($text);
         $draft->setSummary($summary);
         $draft->setMinorEdit($minoredit);
         // Save draft
         $draft->save();
         // Return draft id to client (used for next save)
         return (string) $draft->getID();
     } else {
         // Return failure
         return '-1';
     }
 }
Beispiel #8
0
 /**
  * EditPage::showEditForm:initial hook
  * Load draft...
  */
 public static function loadForm(EditPage $editpage)
 {
     global $wgRequest;
     $context = $editpage->getArticle()->getContext();
     $user = $context->getUser();
     if (!$user->getOption('extensionDrafts_enable', 'true')) {
         return true;
     }
     //XXCHANGED
     $isGuidedEditor = isset($editpage->mGuided) && $editpage->mGuided;
     $adv = $isGuidedEditor ? "" : "&advanced=true";
     $wgRequest->setVal("guidededitor", $isGuidedEditor);
     // Check permissions
     $request = $context->getRequest();
     if ($user->isAllowed('edit') && $user->isLoggedIn()) {
         // Get draft
         $draft = Draft::newFromID($request->getIntOrNull('draft'));
         // Load form values
         if ($draft->exists()) {
             // Override initial values in the form with draft data
             $editpage->textbox1 = $draft->getText();
             $editpage->summary = $draft->getSummary();
             $editpage->scrolltop = $draft->getScrollTop();
             $editpage->minoredit = $draft->getMinorEdit() ? true : false;
         }
         // Save draft on non-save submission
         if ($request->getVal('action') == 'submit' && $user->getEditToken() == $request->getText('wpEditToken') && is_null($request->getText('wpDraftTitle'))) {
             // If the draft wasn't specified in the url, try using a
             // form-submitted one
             if (!$draft->exists()) {
                 $draft = Draft::newFromID($request->getIntOrNull('wpDraftID'));
             }
             // Load draft with info
             $draft->setTitle(Title::newFromText($request->getText('wpDraftTitle')));
             $draft->setSection($request->getInt('wpSection'));
             $draft->setStartTime($request->getText('wpStarttime'));
             $draft->setEditTime($request->getText('wpEdittime'));
             $draft->setSaveTime(wfTimestampNow());
             $draft->setScrollTop($request->getInt('wpScrolltop'));
             $draft->setText($request->getText('wpTextbox1'));
             $draft->setSummary($request->getText('wpSummary'));
             $draft->setMinorEdit($request->getInt('wpMinoredit', 0));
             // Save draft
             $draft->save();
             // Use the new draft id
             $request->setVal('draft', $draft->getID());
         }
     }
     $out = $context->getOutput();
     $numDrafts = Drafts::num($context->getTitle());
     // Show list of drafts
     if ($numDrafts > 0) {
         if ($request->getText('action') !== 'submit') {
             $out->addHTML(Xml::openElement('div', array('id' => 'drafts-list-box', 'class' => 'minor_section')));
             $out->addHTML(Xml::element('h3', null, $context->msg('drafts-view-existing')->text()));
             Drafts::display($context->getTitle());
             $out->addHTML(Xml::closeElement('div'));
         } else {
             $jsWarn = "if( !wgAjaxSaveDraft.insync ) return confirm('" . Xml::escapeJsString($context->msg('drafts-view-warn')->escaped()) . "')";
             $link = Xml::element('a', array('href' => $context->getTitle()->getFullURL('action=edit'), 'onclick' => $jsWarn), $context->msg('drafts-view-notice-link')->numParams($numDrafts)->text());
             $out->addHTML($context->msg('drafts-view-notice')->rawParams($link)->escaped());
         }
     }
     // Continue
     return true;
 }