/**
  * Creates or changes a review for a page. Called by remote handler.
  * @return bool Allow other hooked methods to be executed. Always true.
  */
 public static function doEditReview()
 {
     if (BsCore::checkAccessAdmission('workflowedit') === false) {
         return true;
     }
     $aAnswer = array('success' => true, 'errors' => array(), 'messages' => array());
     $oUser = BsCore::loadCurrentUser();
     $oReview = BsExtensionManager::getExtension('Review');
     $userIsSysop = in_array('sysop', $oUser->getGroups());
     //TODO: getEffectiveGroups()?
     if (!$userIsSysop && !$oUser->isAllowed('workflowedit')) {
         $aAnswer['success'] = false;
         $aAnswer['messages'][] = wfMessage('bs-review-save-norights')->plain();
         return json_encode($aAnswer);
     }
     global $wgRequest;
     $paramRvPid = $wgRequest->getInt('pid', -1);
     // Check for id 0 prevents special pages to be put on a review
     if (empty($paramRvPid)) {
         $aAnswer['success'] = false;
         $aAnswer['messages'][] = wfMessage('bs-review-save-noid')->plain();
         return json_encode($aAnswer);
     }
     $oReviewProcess = BsReviewProcess::newFromPid($paramRvPid);
     $bIsEdit = false;
     if (is_object($oReviewProcess) && $oReviewProcess->hasSteps()) {
         $bIsEdit = true;
     }
     if (!$userIsSysop && $oReviewProcess && BsConfig::get('MW::Review::CheckOwner') && $oReviewProcess->owner != $oUser->getID()) {
         $aAnswer['success'] = false;
         $aAnswer['messages'][] = wfMessage('bs-review-save-norights')->plain();
         return json_encode($aAnswer);
     }
     $paramCmd = $wgRequest->getVal('cmd', '');
     $paramSaveTmpl = $wgRequest->getInt('save_tmpl', 0);
     if (!($paramCmd === false)) {
         switch ($paramCmd) {
             case 'insert':
                 $aErrors = array();
                 $review = BsReviewProcess::newFromJSON($wgRequest->getVal('review', ''), $aErrors);
                 if (is_array($aErrors) && count($aErrors) > 0) {
                     $aAnswer['success'] = false;
                     foreach ($aErrors as $sError) {
                         $aAnswer['messages'][] = wfMessage('bs-review-' . $sError)->plain();
                     }
                     return json_encode($aAnswer);
                 }
                 $review->setOwner($oUser->getID());
                 $oOldReview = BsReviewProcess::newFromPid($paramRvPid);
                 $update = is_object($oOldReview) ? $oOldReview->getPid() : false;
                 BsReviewProcess::removeReviewSteps($paramRvPid);
                 if ($paramSaveTmpl == 1) {
                     $paramTmplChoice = $wgRequest->getInt('tmpl_choice', -1);
                     $paramTmplName = $wgRequest->getVal('tmpl_name', '');
                     $review->asTemplate($paramTmplChoice, $paramTmplName);
                 }
                 if (!is_array($review->steps)) {
                     $aAnswer['success'] = false;
                     $aAnswer['messages'][] = wfMessage('bs-review-save-nosteps')->plain();
                     return json_encode($aAnswer);
                 }
                 if ($review->store($update)) {
                     $oTitle = Title::newFromID($paramRvPid);
                     $oTitle->invalidateCache();
                     $oWatchlist = WatchedItem::fromUserTitle($oUser, $oTitle);
                     if (!$oWatchlist->isWatched()) {
                         $oWatchlist->addWatch();
                     }
                     $aParams = array('action' => $bIsEdit ? 'modify' : 'create', 'target' => $oTitle, 'comment' => '', 'params' => null, 'doer' => $oUser);
                     $oReview->oLogger->addEntry($aParams['action'], $aParams['target'], $aParams['comment'], $aParams['params'], $aParams['doer']);
                     $aAnswer['messages'][] = wfMessage('bs-review-save-success')->plain();
                     // Identify owner
                     $oReviewProcess = BsReviewProcess::newFromPid($paramRvPid);
                     $oReview->emailNotifyNextUsers($oReviewProcess);
                     return json_encode($aAnswer);
                 } else {
                     $aAnswer['success'] = false;
                     $aAnswer['messages'][] = wfMessage('bs-review-save-error')->plain();
                     return json_encode($aAnswer);
                 }
                 break;
                 // 22.08.13 STM: WTF?
             // 22.08.13 STM: WTF?
             case 'delete':
                 BsReviewProcess::removeReviews($paramRvPid);
                 $oTitle = Title::newFromID($paramRvPid);
                 $oTitle->invalidateCache();
                 $oWatchlist = WatchedItem::fromUserTitle($oUser, $oTitle);
                 if ($oWatchlist->isWatched()) {
                     $oWatchlist->removeWatch();
                 }
                 $aParams = array('action' => 'delete', 'target' => $oTitle, 'comment' => '', 'params' => null, 'doer' => $oUser);
                 $oReview->oLogger->addEntry($aParams['action'], $aParams['target'], $aParams['comment'], $aParams['params'], $aParams['doer']);
                 $aAnswer['messages'][] = wfMessage('bs-review-save-removed')->plain();
                 return json_encode($aAnswer);
                 break;
         }
     }
     return true;
 }