/**
  * Concatenate categories on EditPage POST
  *
  * @param EditPage $editPage
  * @param WebRequest $request
  *
  * @return Boolean because it's a hook
  */
 public static function onEditPageImportFormData($editPage, $request)
 {
     $app = F::app();
     if ($request->wasPosted()) {
         $categories = $editPage->safeUnicodeInput($request, 'categories');
         $categories = CategoryHelper::changeFormat($categories, 'json', 'array');
         // Concatenate categories to article wikitext (if there are any).
         if (!empty($categories)) {
             if (!empty($app->wg->EnableAnswers)) {
                 // don't add categories if the page is a redirect
                 $magicWords = $app->wg->ContLang->getMagicWords();
                 $redirects = $magicWords['redirect'];
                 // first element doesn't interest us
                 array_shift($redirects);
                 // check for localized versions of #REDIRECT
                 foreach ($redirects as $alias) {
                     if (stripos($editPage->textbox1, $alias) === 0) {
                         return true;
                     }
                 }
             }
             // Extract categories from the article, merge them with those passed in, weed out
             // duplicates and finally append them back to the article (BugId:99348).
             $data = CategoryHelper::extractCategoriesFromWikitext($editPage->textbox1, true);
             $categories = CategoryHelper::getUniqueCategories($data['categories'], $categories);
             $categories = CategoryHelper::changeFormat($categories, 'array', 'wikitext');
             // Remove trailing whitespace (BugId:11238)
             $editPage->textbox1 = $data['wikitext'] . rtrim($categories);
         }
     }
     return true;
 }
 public function getPreview($wikitext)
 {
     // TODO: use wgParser here because some parser hooks initialize themselves on wgParser (should on provided parser instance)
     global $wgParser, $wgUser, $wgRequest;
     wfProfileIn(__METHOD__);
     $wg = $this->app->wg;
     $parserOptions = new ParserOptions($wgUser);
     $originalWikitext = $wikitext;
     if (!empty($wg->EnableCategorySelectExt)) {
         // if CategorySelect is enabled, add categories to wikitext
         $categories = $wg->Request->getVal('categories', '');
         $wikitext .= CategoryHelper::changeFormat($categories, 'json', 'wikitext');
     }
     // call preSaveTransform so signatures, {{subst:foo}}, etc. will work
     $wikitext = $wgParser->preSaveTransform($wikitext, $this->mTitle, $this->app->getGlobal('wgUser'), $parserOptions);
     // parse wikitext using MW parser
     $parserOutput = $wgParser->parse($wikitext, $this->mTitle, $parserOptions);
     /**
      * Allow extensions to modify the ParserOutput
      */
     wfRunHooks('ArticlePreviewAfterParse', [$parserOutput, $this->mTitle]);
     $html = $parserOutput->getText();
     $html = EditPageService::wrapBodyText($this->mTitle, $wgRequest, $html);
     // we should also render categories and interlanguage links
     $catbox = $this->renderCategoryBoxFromParserOutput($parserOutput);
     $interlanglinks = $this->renderInterlangBoxFromParserOutput($parserOutput);
     /**
      * bugid: 47995 -- Treat JavaScript and CSS as raw text wrapped in <pre> tags
      * We still rely on the parser for other stuff
      */
     if ($this->mTitle->isCssOrJsPage()) {
         $html = '<pre>' . htmlspecialchars($originalWikitext) . '</pre>';
     }
     wfProfileOut(__METHOD__);
     return array($html, $catbox, $interlanglinks);
 }
 /**
  * Return wikitext
  */
 public function getWikitextFromRequest()
 {
     // "wikitext" field used when generating preview / diff
     $wikitext = $this->request->getText('wikitext');
     $method = $this->request->getVal('method', '');
     if ($wikitext == '') {
         if ($method == 'preview' || $method == 'diff') {
             $wikitext = $this->getWikitextFromField('content');
             // Add categories to wikitext for preview and diff
             if (!empty($this->app->wg->EnableCategorySelectExt)) {
                 $categories = $this->request->getVal('categories', '');
                 if (!empty($categories)) {
                     $wikitext .= CategoryHelper::changeFormat($categories, 'json', 'wikitext');
                 }
             }
             // "wpTextbox1" field used when submitting editpage
             // (needs to be processed by Reverse Parser if saved from wysiwyg mode)
         } else {
             $wikitext = $this->getWikitextFromField('wpTextbox1');
         }
     }
     return $wikitext;
 }
 public function testChangeFormatFromArrayToWikiText()
 {
     $expectedWikiText = "[[Category:test category|test sort key]]\n[[Category:2nd test category|2nd test sort key]]";
     $wikiText = CategoryHelper::changeFormat(self::$data, 'array', 'wikitext');
     $this->assertEquals($expectedWikiText, trim($wikiText));
 }
 /**
  * Save categories sent via AJAX into article
  */
 public function save()
 {
     wfProfileIn(__METHOD__);
     $articleId = $this->request->getVal('articleId', 0);
     $categories = $this->request->getVal('categories', array());
     $response = array();
     $title = Title::newFromID($articleId);
     if (wfReadOnly()) {
         $response['error'] = wfMessage('categoryselect-error-db-locked')->text();
     } else {
         if (is_null($title)) {
             $response['error'] = wfMessage('categoryselect-error-article-doesnt-exist', $articleId)->text();
         } else {
             if (!$title->userCan('edit') || $this->wg->User->isBlocked()) {
                 $response['error'] = wfMessage('categoryselect-error-user-rights')->text();
             } else {
                 if (!empty($categories) && is_array($categories)) {
                     Wikia::setVar('EditFromViewMode', 'CategorySelect');
                     $article = new Article($title);
                     $wikitext = $article->fetchContent();
                     // Pull in categories from templates inside of the article (BugId:100980)
                     $options = new ParserOptions();
                     $preprocessedWikitext = ParserPool::preprocess($wikitext, $title, $options);
                     $preprocessedData = CategoryHelper::extractCategoriesFromWikitext($preprocessedWikitext, true);
                     // Compare the new categories with those already in the article to weed out duplicates
                     $newCategories = CategoryHelper::getDiffCategories($preprocessedData['categories'], $categories);
                     // Append the new categories to the end of the article wikitext
                     $wikitext .= CategoryHelper::changeFormat($newCategories, 'array', 'wikitext');
                     // Update the array of categories for the front-end
                     $categories = array_merge($preprocessedData['categories'], $newCategories);
                     $dbw = wfGetDB(DB_MASTER);
                     $dbw->begin();
                     $editPage = new EditPage($article);
                     $editPage->edittime = $article->getTimestamp();
                     $editPage->recreate = true;
                     $editPage->textbox1 = $wikitext;
                     $editPage->summary = wfMessage('categoryselect-edit-summary')->inContentLanguage()->text();
                     $editPage->watchthis = $editPage->mTitle->userIsWatching();
                     $bot = $this->wg->User->isAllowed('bot');
                     $status = $editPage->internalAttemptSave($result, $bot)->value;
                     $response['status'] = $status;
                     switch ($status) {
                         case EditPage::AS_SUCCESS_UPDATE:
                         case EditPage::AS_SUCCESS_NEW_ARTICLE:
                             $dbw->commit();
                             $title->invalidateCache();
                             Article::onArticleEdit($title);
                             $response['html'] = $this->app->renderView('CategorySelectController', 'categories', array('categories' => $categories));
                             wfRunHooks('CategorySelectSave', array($title, $newCategories));
                             break;
                         case EditPage::AS_SPAM_ERROR:
                             $dbw->rollback();
                             $response['error'] = wfMessage('spamprotectiontext')->text() . '<p>( Case #8 )</p>';
                             break;
                         default:
                             $dbw->rollback();
                             $response['error'] = wfMessage('categoryselect-error-edit-abort')->text();
                     }
                 }
             }
         }
     }
     $this->response->setData($response);
     wfProfileOut(__METHOD__);
 }