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; }