public function execute()
 {
     global $wgUser;
     if (!$wgUser->isAllowed('contestadmin') || $wgUser->isBlocked()) {
         $this->dieUsageMsg(array('badaccess-groups'));
     }
     $params = $this->extractRequestParams();
     $everythingOk = true;
     $contestIds = is_null($params['contestids']) ? array() : $params['contestids'];
     $challengeIds = is_null($params['challengeids']) ? array() : $params['challengeids'];
     if (!is_null($params['challengetitles'])) {
         $challenges = ContestChallenge::s()->select('id', array('title' => $params['challengetitles']));
         if ($challenges === false) {
             // TODO: error
         }
         foreach ($challenges as $challenge) {
             $challengeIds[] = $challenge->getId();
         }
     }
     if (!is_null($params['contestnames'])) {
         $contests = Contest::s()->select('id', array('name' => $params['contestnames']));
         if ($contests === false) {
             // TODO: error
         }
         foreach ($contests as $contest) {
             $contestIds[] = $contest->getId();
         }
     }
     $conditions = array();
     if (count($contestIds) > 0) {
         $conditions['contest_id'] = $contestIds;
     }
     if (count($challengeIds) > 0) {
         $conditions['challenge_id'] = $challengeIds;
     }
     if (!is_null($params['ids']) && count($params['ids']) > 0) {
         $conditions['id'] = $params['ids'];
     }
     $contestants = ContestContestant::s()->select(array('id', 'user_id', 'contest_id', 'email'), $conditions);
     $contestantCount = count($contestants);
     if ($contestants !== false && $contestantCount > 0) {
         $setSize = ContestSettings::get('reminderJobSize');
         $limit = count($contestants);
         for ($i = 0; $i <= $limit; $i += $setSize) {
             $this->createReminderJob(array_slice($contestants, $i, $setSize));
         }
     } else {
         $everythingOk = false;
     }
     $this->getResult()->addValue(null, 'success', $everythingOk);
     if ($everythingOk) {
         $this->getResult()->addValue(null, 'contestantcount', $contestantCount);
     }
 }
 public function execute()
 {
     if (!ContestSettings::get('contestDeletionEnabled')) {
         $this->dieUsage('Contest deletion is disabled', 'contestdeletiondisabled');
     }
     global $wgUser;
     if (!$wgUser->isAllowed('contestadmin') || $wgUser->isBlocked()) {
         $this->dieUsageMsg(array('badaccess-groups'));
     }
     $params = $this->extractRequestParams();
     $everythingOk = true;
     foreach ($params['ids'] as $id) {
         $contest = new Contest(array('id' => $id));
         $everythingOk = $contest->removeAllFromDB() && $everythingOk;
     }
     $this->getResult()->addValue(null, 'success', $everythingOk);
 }
 /**
  * HTMLForm field validation-callback for the submission field.
  * Warning: regexes used! o_O
  *
  * @since 0.1
  *
  * @param $value String
  * @param $alldata Array
  *
  * @return true|string
  */
 public static function validateSubmissionField($value, $alldata = null)
 {
     $value = trim($value);
     if ($value == '') {
         return true;
     }
     $allowedPatterns = array();
     foreach (ContestSettings::get('submissionDomains') as $domain) {
         $allowedPatterns[] = '@^https?://(([a-z0-9]+)\\.)?' . str_replace('.', '\\.', $domain) . '/.*$@i';
     }
     foreach ($allowedPatterns as $pattern) {
         if (preg_match($pattern, $value)) {
             return true;
         }
     }
     return wfMsg('contest-submission-invalid-url');
 }
 /**
  * Send a reminder email.
  *
  * @since 0.1
  *
  * @return Status
  */
 public function sendReminderEmail($emailText, array $params = array())
 {
     if (!array_key_exists('daysLeft', $params)) {
         $params['daysLeft'] = $this->getContest()->getDaysLeft();
     }
     $title = wfMsgExt('contest-email-reminder-title', 'parsemag', $params['daysLeft']);
     $user = $this->getUser();
     $sender = ContestSettings::get('mailSender');
     $senderName = ContestSettings::get('mailSenderName');
     wfRunHooks('ContestBeforeReminderEmail', array(&$this, &$title, &$emailText, &$user, &$sender, &$senderName));
     return UserMailer::send(new MailAddress($user), new MailAddress($sender, $senderName), $title, $emailText, null, 'text/html; charset=ISO-8859-1');
 }
 /**
  * The UI keeps track of 'removed' challenges by storing them into a
  * hidden HTML input, pipe-separated. On submission, this method
  * takes this string and actually deletes them.
  *
  * @since 0.1
  *
  * @param string $idString
  *
  * @return boolean Success indicator
  */
 protected function removeDeletedChallenges($idString)
 {
     if ($idString == '') {
         return true;
     }
     if (!ContestSettings::get('contestDeletionEnabled')) {
         // Shouldn't get here (UI should prevent it)
         throw new MWException('Contest deletion is disabled', 'contestdeletiondisabled');
     }
     return ContestChallenge::s()->delete(array('id' => explode('|', $idString)));
 }
 /**
  * Displays a list of all contests.
  *
  * @since 0.1
  *
  * @param array $contests
  */
 protected function displayContestsTable(array $contests)
 {
     $user = $this->getUser();
     $out = $this->getOutput();
     $out->addHTML(Html::element('h2', array('class' => 'contests-title'), wfMsg('contest-special-existing')));
     $out->addHTML(Xml::openElement('table', array('class' => 'wikitable sortable contests-table')));
     $headers = array(Html::element('th', array(), wfMsg('contest-special-name')), Html::element('th', array(), wfMsg('contest-special-status')), Html::element('th', array(), wfMsg('contest-special-submissioncount')));
     $headers[] = Html::element('th', array('class' => 'unsortable'));
     $out->addHTML('<thead><tr>' . implode('', $headers) . '</tr></thead>');
     $out->addHTML('<tbody>');
     foreach ($contests as $contest) {
         /**
          * @var $contest Contest
          */
         $fields = array();
         if ($user->isAllowed('contestant')) {
             $name = Html::element('a', array('href' => SpecialPage::getTitleFor('ContestWelcome', $contest->getField('name'))->getLocalURL()), $contest->getField('name'));
         } else {
             $name = $contest->getField('name');
         }
         $fields[] = Html::rawElement('td', array('data-sort-value' => $contest->getField('name')), $name);
         $fields[] = Html::element('td', array('data-sort-value' => $contest->getStatus()), Contest::getStatusMessage($contest->getStatus()));
         $fields[] = Html::element('td', array(), $this->getLanguage()->formatNum($contest->getField('submission_count')));
         $links = array();
         if ($user->isAllowed('contestjudge')) {
             $links[] = Html::element('a', array('href' => SpecialPage::getTitleFor('Contest', $contest->getField('name'))->getLocalURL()), wfMsg('contest-nav-contest'));
         }
         if ($user->isAllowed('contestadmin')) {
             $links[] = Html::element('a', array('href' => SpecialPage::getTitleFor('EditContest', $contest->getField('name'))->getLocalURL()), wfMsg('contest-special-edit'));
             if (ContestSettings::get('contestDeletionEnabled')) {
                 $links[] = Html::element('a', array('href' => '#', 'class' => 'contest-delete', 'data-contest-id' => $contest->getId(), 'data-contest-token' => $this->getUser()->editToken('deletecontest' . $contest->getId())), wfMsg('contest-special-delete'));
             }
         }
         $links[] = Html::element('a', array('href' => SpecialPage::getTitleFor('ContestWelcome', $contest->getField('name'))->getLocalURL()), wfMsg('contest-nav-contestwelcome'));
         if ($user->isAllowed('contestant')) {
             $links[] = Html::element('a', array('href' => SpecialPage::getTitleFor('ContestSignup', $contest->getField('name'))->getLocalURL()), wfMsg('contest-nav-contestsignup'));
         }
         $fields[] = Html::rawElement('td', array(), $this->getLanguage()->pipeList($links));
         $out->addHTML('<tr>' . implode('', $fields) . '</tr>');
     }
     $out->addHTML('</tbody>');
     $out->addHTML('</table>');
     $out->addModules('contest.special.contests');
 }
 /**
  * Remove the contest and all it's linked data from the database.
  *
  * @since 0.1
  *
  * @return boolean Success indicator
  */
 public function removeAllFromDB()
 {
     if (!ContestSettings::get('contestDeletionEnabled')) {
         // Shouldn't get here (UI should prevent it)
         throw new MWException('Contest deletion is disabled', 'contestdeletiondisabled');
     }
     $condition = array('contest_id' => $this->getId());
     $success = ContestChallenge::s()->delete($condition);
     if ($success) {
         $contestantIds = array();
         foreach (ContestContestant::s()->select('id', $condition) as $contestant) {
             $contestantIds[] = $contestant->getId();
         }
         if (count($contestantIds) > 0) {
             $success = ContestComment::s()->delete(array('contestant_id' => $contestantIds)) && $success;
             $success = ContestVote::s()->delete(array('contestant_id' => $contestantIds)) && $success;
         }
         $success = ContestContestant::s()->delete($condition) && $success;
     }
     if ($success) {
         $success = parent::removeFromDB();
     }
     return $success;
 }
 /**
  * Display the current rating the judge gave if any and a control to
  * (re)-rate.
  *
  * @since 0.1
  *
  * @param ContestContestant $contestant
  */
 protected function showRating(ContestContestant $contestant)
 {
     $out = $this->getOutput();
     $out->addHTML(Html::element('h2', array(), wfMsg('contest-contestant-rate')));
     $vote = ContestVote::s()->selectRow(array('value', 'id'), array('user_id' => $this->getUser()->getId(), 'contestant_id' => $contestant->getId()));
     if ($vote === false) {
         $message = wfMsg('contest-contestant-not-voted');
     } else {
         $message = wfMsgExt('contest-contestant-voted', 'parsemag', $this->getLanguage()->formatNum($vote->getField('value')));
         $out->addHTML(Html::hidden('contestant-vote-id', $vote->getId()));
     }
     $out->addHTML(Html::element('p', array(), $message));
     foreach (ContestSettings::get('voteValues') as $value) {
         $attribs = array('type' => 'radio', 'value' => $value, 'name' => 'contestant-rating', 'id' => 'contestant-rating-' . $value);
         if ($vote !== false && $value == $vote->getField('value')) {
             $attribs['checked'] = 'checked';
         }
         $out->addHTML(Html::element('input', $attribs) . Html::element('label', array('for' => 'contestant-rating-' . $value), $this->getLanguage()->formatNum($value)));
     }
 }
 /**
  * Adds the preferences of Contest to the list of available ones.
  * @see https://www.mediawiki.org/wiki/Manual:Hooks/GetPreferences
  *
  * @since 0.1
  *
  * @param User $user
  * @param array $preferences
  *
  * @return true
  */
 public static function onGetPreferences(User $user, array &$preferences)
 {
     if (ContestSettings::get('enableTopLink')) {
         $preferences['contest_showtoplink'] = array('type' => 'toggle', 'label-message' => 'contest-prefs-showtoplink', 'section' => 'contest');
     }
     return true;
 }