function _deleteWithRelatives($id) { // Don't delete someone who is the only parent of someone that cannot be deleted $relatives = $this->UserCache->read('Relatives', $id); $delete_ids = array($id); foreach ($relatives as $relative) { if (empty($relative['Relative']['user_id'])) { if (count($this->UserCache->read('RelatedToIDs', $relative['Relative']['id'])) == 1) { $dependencies = $this->Person->dependencies($relative['Relative']['id'], array('Affiliate', 'Group', 'Relative', 'Related', 'Skill', 'Setting')); if ($dependencies !== false) { $this->Session->setFlash(__('You cannot delete the only parent of a child with history in the system.', true), 'default', array('class' => 'info')); $this->redirect('/'); } $delete_ids[] = $relative['Relative']['id']; } } } // User and person records may be in separate databases, so we need a transaction for each $user_transaction = new DatabaseTransaction($this->Auth->authenticate); $person_transaction = new DatabaseTransaction($this->Person); $success = true; foreach ($delete_ids as $id) { $user_id = $this->UserCache->read('Person.user_id', $id); if ($user_id) { if (method_exists($this->Auth->authenticate, 'delete_duplicate_user')) { $success &= $this->Auth->authenticate->delete_duplicate_user($user_id); } else { $success &= $this->Auth->authenticate->delete($user_id, false); } } $success &= $this->Person->delete($id); $relatives = $this->UserCache->read('RelatedToIDs', $id); foreach ($relatives as $relative) { $this->UserCache->clear('Relatives', $relative); $this->UserCache->clear('RelativeIDs', $relative); $this->UserCache->clear('RelatedTo', $relative); $this->UserCache->clear('RelatedToIDs', $relative); } Cache::delete("person/{$id}", 'file'); } if ($success) { $user_transaction->commit(); $person_transaction->commit(); } return $success; }
function create_account() { if (!Configure::read('feature.manage_accounts')) { $this->Session->setFlash(__('This system uses ' . Configure::read('feature.manage_name') . ' to manage user accounts. Account creation through Zuluru is disabled.', true), 'default', array('class' => 'info')); $this->redirect('/'); } if (!$this->is_admin && !$this->is_manager && $this->UserCache->currentId()) { $this->Session->setFlash(__('You are already logged in!', true), 'default', array('class' => 'info')); $this->redirect('/'); } $this->_loadAddressOptions(); $groups = $this->_loadGroupOptions(); $this->_loadAffiliateOptions(); $user_model = $this->Auth->authenticate->name; $this->set(array('user_model' => $user_model, 'id_field' => $this->Auth->authenticate->primaryKey, 'user_field' => $this->Auth->authenticate->userField, 'email_field' => $this->Auth->authenticate->emailField)); if (!empty($this->data)) { // Set the default error message in advance. If it saves successfully, this will be overwritten. $this->Session->setFlash(sprintf(__('The %s could not be saved. Please correct the errors below and try again.', true), __('account', true)), 'default', array('class' => 'warning')); // The presence of data in a field that should not be filled in triggers anti-spam measures. // Also, anyone that fills the form out in under 15 seconds is a spambot. if (Configure::read('feature.antispam') && (!empty($this->data[$user_model]['subject']) || time() - $this->data[$user_model]['timestamp'] < 15)) { sleep(15); return; } // Handle affiliations if (Configure::read('feature.affiliates')) { if (Configure::read('feature.multiple_affiliates')) { if (empty($this->data['Affiliate']['Affiliate'][0])) { $this->Person->Affiliate->validationErrors['Affiliate'] = __('You must select at least one affiliate that you are interested in.', true); } } else { if (empty($this->data['Affiliate']['Affiliate'][0]) || count($this->data['Affiliate']['Affiliate']) > 1) { $this->Person->Affiliate->validationErrors['Affiliate'] = __('You must select an affiliate that you are interested in.', true); } } } else { $this->data['Affiliate']['Affiliate'] = array(1); } // SaveAll doesn't work correctly in this case. Save them separately, to make sure they're all validated. $this->Auth->authenticate->saveAll($this->data[$user_model], array('validate' => 'only')); $this->Person->saveAll($this->data['Person'], array('validate' => 'only')); foreach ($this->data['Person'] as $key => $person) { if (!empty($this->data['Person'][$key]['Skill']) && !$this->Person->Skill->saveAll($this->data['Person'][$key]['Skill'], array('validate' => 'only'))) { $this->Person->validationErrors[$key]['Skill'] = $this->Person->Skill->validationErrors; } } // Make sure someone isn't forging their way into an entirely unauthorized level. if (!$this->is_admin && !empty($this->data['Group']['Group'])) { $selected_groups = $this->Group->find('all', array('contain' => false, 'conditions' => array('id' => $this->data['Group']['Group']))); if ($this->is_manager) { $level = 5; } else { $level = 3; } $invalid_groups = Set::extract("/Group[level>{$level}]", $selected_groups); if (!empty($invalid_groups)) { $this->Person->Group->validationErrors['Group'] = __('You have selected an invalid group.', true); } } else { $selected_groups = array(); } if ($this->Auth->authenticate->validates() && $this->Person->validates() && $this->Person->Group->validates() && $this->Person->Affiliate->validates()) { // User and person records may be in separate databases, so we need a transaction for each $user_transaction = new DatabaseTransaction($this->Auth->authenticate); $person_transaction = new DatabaseTransaction($this->Person); if ($this->Auth->authenticate->save($this->data)) { // Tweak some data to be saved $this->data['Person'][0]['user_id'] = $this->Auth->authenticate->id; foreach ($this->data['Person'] as $key => $person) { $person['complete'] = true; if ($this->is_admin) { if ($key != 0) { $person['status'] = $this->data['Person'][0]['status']; } } else { if (Configure::read('feature.auto_approve')) { if ($key == 0) { // Check the requested groups and do not auto-approve above a certain level $invalid_groups = Set::extract('/Group[level>1]', $selected_groups); if (empty($invalid_groups)) { $person['status'] = 'active'; } } else { $person['status'] = 'active'; } } } $save = array('Person' => $person, 'Affiliate' => $this->data['Affiliate']); if (!empty($person['Skill'])) { $save['Skill'] = $person['Skill']; unset($person['Skill']); } if ($key == 0) { $save['Group'] = $this->data['Group']; } else { // Assume any secondary profiles are players $save['Group'] = array('Group' => array(GROUP_PLAYER)); if (isset($this->data['Person'][0]['status'])) { $save['Person']['status'] = $this->data['Person'][0]['status']; } } $this->Person->create(); if (!$this->Person->saveAll($save)) { return; } if (!isset($parent_id)) { $parent_id = $this->Person->id; } else { $this->Person->PeoplePerson->save(array('person_id' => $parent_id, 'relative_id' => $this->Person->id, 'approved' => true), array('validate' => false)); } } App::import('Helper', 'Html'); $html = new HtmlHelper(); if (Configure::read('feature.auto_approve')) { $msg = $html->tag('h2', __('THANK YOU', true)) . $html->para(null, sprintf(__('for creating an account with %s.', true), Configure::read('organization.name'))); } else { $msg = $html->para(null, __('Your account has been created.', true) . ' ' . __('It must be approved by an administrator before you will have full access to the site.', true) . ' ' . __('However, you can log in and start exploring right away.', true)); } if (isset($this->params['form']['continue'])) { $msg .= $html->para(null, __('Please proceed with entering your next child\'s details below.', true)); } $this->Session->setFlash($msg, 'default', array('class' => 'success')); // There may be callbacks to handle // TODO: How to handle this in conjunction with third-party auth systems? $this->data['Person']['id'] = $this->Person->id; $components = Configure::read('callbacks.user'); foreach ($components as $name => $config) { $component = $this->_getComponent('User', $name, $this, false, $config); $component->onAdd($this->data); } $user_transaction->commit(); $person_transaction->commit(); if (!$this->is_logged_in) { // Automatically log the user in $this->data[$this->Auth->authenticate->alias]['password'] = $this->data[$this->Auth->authenticate->alias]['passwd']; $this->Auth->login($this->Auth->hashPasswords($this->data)); } if (isset($this->params['form']['continue'])) { $this->redirect(array('controller' => 'people', 'action' => 'add_relative')); } $this->redirect('/'); } } } else { // By default, select the first group $this->data = array('Group' => array('Group' => array(current(array_keys($groups))))); } }
function delete_stage() { $id = $this->_arg('division'); if (!$id) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('division', true)), 'default', array('class' => 'info')); $this->redirect(array('controller' => 'leagues', 'action' => 'index')); } $stage = $this->_arg('stage'); if (!$stage) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('stage', true)), 'default', array('class' => 'info')); $this->redirect(array('controller' => 'leagues', 'action' => 'index')); } $this->Division->contain(array('League', 'Pool' => array('conditions' => array('Pool.stage' => $stage), 'Game'))); $division = $this->Division->read(null, $id); if (!$division) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('division', true)), 'default', array('class' => 'info')); $this->redirect(array('controller' => 'leagues', 'action' => 'index')); } $this->Configuration->loadAffiliate($division['League']['affiliate_id']); if (empty($division['Pool'])) { $this->Session->setFlash(__('There are currently no pools to delete in this stage.', true), 'default', array('class' => 'warning')); $this->redirect(array('controller' => 'schedules', 'action' => 'add', 'division' => $id)); } $games = Set::extract('/Game/id', $division['Pool']); $slots = Set::extract('/Game/game_slot_id', $division['Pool']); $transaction = new DatabaseTransaction($this->Division->Pool); // We'll overwrite this flash message if it succeeds $this->Session->setFlash(sprintf(__('%s were not deleted', true), __('Pools in this stage', true)), 'default', array('class' => 'warning')); if ($this->Division->Pool->deleteAll(array('Pool.division_id' => $id, 'Pool.stage >=' => $stage))) { if (empty($games) || $this->Division->Pool->Game->deleteAll(array('Game.id' => $games)) && $this->Division->Pool->Game->GameSlot->updateAll(array('GameSlot.assigned' => 0), array('GameSlot.id' => $slots))) { $transaction->commit(); Cache::delete('division/' . intval($id) . '/standings', 'long_term'); Cache::delete('division/' . intval($id) . '/schedule', 'long_term'); Cache::delete('league/' . $this->Division->league($id) . '/standings', 'long_term'); Cache::delete('league/' . $this->Division->league($id) . '/schedule', 'long_term'); $this->Session->setFlash(sprintf(__('%s deleted', true), __('All pools in this stage', true)), 'default', array('class' => 'success')); } } $this->redirect(array('controller' => 'schedules', 'action' => 'add', 'division' => $id)); }
function submit_score() { $id = $this->_arg('game'); if (!$id) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('game', true)), 'default', array('class' => 'info')); $this->redirect('/'); } $team_id = $this->_arg('team'); if (!$team_id) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('team', true)), 'default', array('class' => 'info')); $this->redirect('/'); } $contain = array('Division' => array('Person' => array($this->Auth->authenticate->name, 'fields' => array('Person.id', 'Person.user_id', 'Person.first_name', 'Person.last_name', 'Person.alternate_email')), 'League'), 'GameSlot' => array('Field' => 'Facility'), 'ScoreEntry' => array('Person' => array('fields' => array('id', 'first_name', 'last_name'))), 'SpiritEntry' => array('MostSpirited'), 'Incident'); if (Configure::read('scoring.allstars') || Configure::read('scoring.most_spirited')) { // We need roster details for potential allstar nominations. $contain = array_merge($contain, array('HomeTeam' => array('Person' => array($this->Auth->authenticate->name, 'conditions' => array('TeamsPerson.role' => Configure::read('extended_playing_roster_roles')), 'fields' => array('Person.id', 'Person.user_id', 'Person.first_name', 'Person.last_name', 'Person.alternate_email', 'Person.gender'))), 'AwayTeam' => array('Person' => array($this->Auth->authenticate->name, 'conditions' => array('TeamsPerson.role' => Configure::read('extended_playing_roster_roles')), 'fields' => array('Person.id', 'Person.user_id', 'Person.first_name', 'Person.last_name', 'Person.alternate_email', 'Person.gender'))), 'Allstar' => array('Person'))); } else { $contain = array_merge($contain, array('HomeTeam' => array('Person' => array($this->Auth->authenticate->name, 'conditions' => array('TeamsPerson.role' => Configure::read('privileged_roster_roles')), 'fields' => array('Person.id', 'Person.user_id', 'Person.first_name', 'Person.last_name', 'Person.alternate_email', 'Person.gender'))), 'AwayTeam' => array('Person' => array($this->Auth->authenticate->name, 'conditions' => array('TeamsPerson.role' => Configure::read('privileged_roster_roles')), 'fields' => array('Person.id', 'Person.user_id', 'Person.first_name', 'Person.last_name', 'Person.alternate_email', 'Person.gender'))))); } $this->Game->contain($contain); $game = $this->Game->read(null, $id); if (!$game) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('game', true)), 'default', array('class' => 'info')); $this->redirect('/'); } $this->Configuration->loadAffiliate($game['Division']['League']['affiliate_id']); Configure::load("sport/{$game['Division']['League']['sport']}"); $this->Game->_adjustEntryIndices($game); if ($game['Game']['home_team'] == $team_id) { $team = $game['HomeTeam']; $opponent = $game['AwayTeam']; } else { if ($game['Game']['away_team'] == $team_id) { $team = $game['AwayTeam']; $opponent = $game['HomeTeam']; } else { $this->Session->setFlash(__('That team is not playing in this game.', true), 'default', array('class' => 'info')); $this->redirect(array('action' => 'view', 'game' => $id)); } } $end_time = strtotime("{$game['GameSlot']['game_date']} {$game['GameSlot']['display_game_end']}") + Configure::read('timezone.adjust') * 60; if ($end_time - 60 * 60 > time()) { $this->Session->setFlash(__('That game has not yet occurred!', true), 'default', array('class' => 'info')); $this->redirect(array('action' => 'view', 'game' => $id)); } if ($this->Game->_is_finalized($game)) { $this->Session->setFlash(__('The score for that game has already been finalized.', true), 'default', array('class' => 'info')); $this->redirect(array('action' => 'view', 'game' => $id)); } if (empty($game['Game']['home_team']) || empty($game['Game']['away_team'])) { $this->Session->setFlash(__('The opponent for that game has not been determined, so a score cannot yet be submitted.', true), 'default', array('class' => 'info')); $this->redirect(array('action' => 'view', 'game' => $id)); } if ($this->Game->_get_score_entry($game, $team_id)) { // We have to use string 1 and 0 here, as that's what the // form helper checkbox function compares against, using === $game['Game']['allstar'] = !empty($game['Allstar']) ? '1' : '0'; $game['Game']['incident'] = !empty($game['Incident']) ? '1' : '0'; } if (!empty($game['SpiritEntry'][$opponent['id']]['most_spirited'])) { $game['SpiritEntry'][$opponent['id']]['has_most_spirited'] = '1'; } // We need this in a couple of places if (League::hasSpirit($game['Division']['League'])) { $spirit_obj = $this->_getComponent('Spirit', $game['Division']['League']['sotg_questions'], $this); } if (!empty($this->data)) { $transaction = new DatabaseTransaction($this->Game); // We could put these as hidden fields in the form, but we'd need to // validate them against the values from the URL anyway, so it's // easier to just set them directly here. // We use the team_id as the array index, here and in the views, // because order matters, and this is a good way to ensure that // the correct data gets into the correct form. $this->data['Game']['id'] = $id; $this->data['ScoreEntry'][$team_id]['team_id'] = $team_id; $unplayed = in_array($this->data['ScoreEntry'][$team_id]['status'], Configure::read('unplayed_status')); if ($unplayed) { unset($this->data['Allstar']); unset($this->data['SpiritEntry']); } else { if (isset($spirit_obj)) { $this->_spiritTeams($opponent['id'], $team_id, $this->data); } } // Ensure that the saved score entry ids (if any) are the same as the posted ids (if any) $saved = $posted = null; if (!empty($game['ScoreEntry'][$team_id]['id'])) { $saved = $game['ScoreEntry'][$team_id]['id']; } if (array_key_exists('id', $this->data['ScoreEntry'][$team_id])) { $posted = $this->data['ScoreEntry'][$team_id]['id']; } if ($saved !== $posted) { if (!$posted) { $this->Session->setFlash(__('There is already a score submitted by your team for this game. To update this, use the "edit" link.', true), 'default', array('class' => 'info')); } else { $this->Session->setFlash(__('ID for posted score does not match the saved ID.', true), 'default', array('class' => 'error')); } $this->redirect(array('action' => 'view', 'game' => $id)); } // Same process, for spirit entries if (!$unplayed && isset($spirit_obj)) { $saved = $posted = null; if (!empty($game['SpiritEntry'][$opponent['id']]['id'])) { $saved = $game['SpiritEntry'][$opponent['id']]['id']; } if (array_key_exists('id', $this->data['SpiritEntry'][$opponent['id']])) { $posted = $this->data['SpiritEntry'][$opponent['id']]['id']; } if ($saved !== $posted) { if (!$posted) { $this->Session->setFlash(__('There is already a spirit score submitted by your team for this game. To update this, use the "edit" link.', true), 'default', array('class' => 'info')); } else { $this->Session->setFlash(__('ID for posted spirit score does not match the saved ID.', true), 'default', array('class' => 'error')); } $this->redirect(array('action' => 'view', 'game' => $id)); } } if (Configure::read('scoring.allstars') && $game['Division']['allstars'] != 'never' && array_key_exists('Allstar', $this->data)) { if ($game['Division']['allstars_from'] == 'submitter') { $roster = Set::extract('/Person/id', $team); } else { $roster = Set::extract('/Person/id', $opponent); } foreach ($this->data['Allstar'] as $key => $data) { if (!$data['person_id']) { // Delete any pre-existing nominations that have been removed if (array_key_exists('id', $data)) { $this->Game->Allstar->delete($data['id']); } // Remove blank all-star fields, as they will cause insertion errors unset($this->data['Allstar'][$key]); } else { // Validate that the all-star submissions are on the correct roster if (!in_array($data['person_id'], $roster)) { $this->Session->setFlash(__('You have tried to perform an invalid all-star nomination.', true), 'default', array('class' => 'error')); $this->redirect('/'); } } } if (empty($this->data['Allstar'])) { unset($this->data['Allstar']); } } else { unset($this->data['Allstar']); } if (!Configure::read('scoring.most_spirited') || $game['Division']['most_spirited'] == 'never') { unset($this->data['SpiritEntry']['most_spirited']); } // Remove blank incident reports, as they will cause insertion errors if (Configure::read('scoring.incident_reports') && array_key_exists('incident', $this->data['Game']) && $this->data['Game']['incident']) { $this->data['Incident'][$team_id]['team_id'] = $team_id; } else { unset($this->data['Incident']); } // Set default values in the case of a default reported $status = $this->data['ScoreEntry'][$team_id]['status']; if ($status == 'home_default') { if ($game['Game']['home_team'] == $team_id) { $this->data['ScoreEntry'][$team_id]['score_for'] = Configure::read('scoring.default_losing_score'); $this->data['ScoreEntry'][$team_id]['score_against'] = Configure::read('scoring.default_winning_score'); if (isset($spirit_obj)) { $this->_spiritMerge($opponent['id'], $spirit_obj->expected(), $this->data); } } else { $this->data['ScoreEntry'][$team_id]['score_for'] = Configure::read('scoring.default_winning_score'); $this->data['ScoreEntry'][$team_id]['score_against'] = Configure::read('scoring.default_losing_score'); if (isset($spirit_obj)) { $this->_spiritMerge($opponent['id'], $spirit_obj->defaulted(), $this->data); } } } else { if ($status == 'away_default') { if ($game['Game']['home_team'] == $team_id) { $this->data['ScoreEntry'][$team_id]['score_for'] = Configure::read('scoring.default_winning_score'); $this->data['ScoreEntry'][$team_id]['score_against'] = Configure::read('scoring.default_losing_score'); if (isset($spirit_obj)) { $this->_spiritMerge($opponent['id'], $spirit_obj->defaulted(), $this->data); } } else { $this->data['ScoreEntry'][$team_id]['score_for'] = Configure::read('scoring.default_losing_score'); $this->data['ScoreEntry'][$team_id]['score_against'] = Configure::read('scoring.default_winning_score'); if (isset($spirit_obj)) { $this->_spiritMerge($opponent['id'], $spirit_obj->expected(), $this->data); } } } else { if ($unplayed) { $this->data['ScoreEntry'][$team_id]['score_for'] = $this->data['ScoreEntry'][$team_id]['score_against'] = null; } } } // Spirit score entry validation comes from the spirit component if (isset($spirit_obj)) { $this->Game->SpiritEntry->validate = $spirit_obj->getValidate($game['Division']['League']); } $resultMessage = null; if ($this->Game->saveAll($this->data, array('validate' => 'first'))) { // If the game was unplayed, and there's a spirit entry from a previous submission, // we must delete that entry. if ($unplayed && !empty($game['SpiritEntry'][$opponent['id']]['id'])) { $this->Game->SpiritEntry->delete($game['SpiritEntry'][$opponent['id']]['id'], false); } $transaction->commit(); Cache::delete("division/{$game['Division']['id']}/standings", 'long_term'); Cache::delete("division/{$game['Division']['id']}/schedule", 'long_term'); Cache::delete('league/' . $this->Game->Division->league($game['Division']['id']) . '/standings', 'long_term'); Cache::delete('league/' . $this->Game->Division->league($game['Division']['id']) . '/schedule', 'long_term'); // Check if the opponent has an entry if (!$this->Game->_get_score_entry($game, $opponent['id'])) { // No, so we just mention that it's been saved and move on $status = $this->data['ScoreEntry'][$team_id]['status']; if (in_array($status, Configure::read('unplayed_status'))) { $team_status = $opponent_status = __($status, true); } else { $score_for = $this->data['ScoreEntry'][$team_id]['score_for']; $score_against = $this->data['ScoreEntry'][$team_id]['score_against']; $default = strpos($status, 'default') !== false; if ($score_for > $score_against) { $team_status = __('a win for your team', true); if ($default) { $opponent_status = __('a default loss for your team', true); } else { $opponent_status = sprintf(__('a %s-%s loss for your team', true), $score_for, $score_against); } } else { if ($score_for < $score_against) { $team_status = __('a loss for your team', true); if ($default) { $opponent_status = __('a default win for your team', true); } else { $opponent_status = sprintf(__('a %s-%s win for your team', true), $score_against, $score_for); } } else { $team_status = __('a tie', true); $opponent_status = sprintf(__('a %s-%s tie', true), $score_for, $score_against); } } // We need to swap the for and against scores to reflect the opponent's view in the email below list($score_against, $score_for) = array($score_for, $score_against); } $resultMessage = sprintf(__('This score has been saved. Once your opponent has entered their score, it will be officially posted.<br/><br/>The score you have submitted indicates that this game was %s. If this is incorrect, you can edit the score to correct it.', true), $team_status); $resultClass = 'success'; // Email opposing captains with this score and an easy link $captains = array(); foreach (Configure::read('privileged_roster_roles') as $role) { $captains = array_merge($captains, Set::extract("/Person/TeamsPerson[role={$role}]/..", $opponent)); } if (!empty($captains)) { $division = $game['Division']; $this->set(compact('division', 'game', 'status', 'opponent_status', 'score_for', 'score_against', 'team', 'opponent', 'captains')); $this->_sendMail(array('to' => $captains, 'replyTo' => $this->UserCache->read('Person.email_formatted'), 'subject' => 'Opponent score submission', 'template' => 'score_submission', 'sendAs' => 'both')); } } else { // Otherwise, both teams have an entry. So, attempt to finalize using // this information. $result = $this->_finalize($id); if ($result === true) { $resultMessage = __('This score agrees with the score submitted by your opponent. It will now be posted as an official game result.', true); $resultClass = 'success'; } else { $resultMessage = $result; $resultClass = 'warning'; } } // TODO: Check for changes to the incident text to avoid sending a duplicate email, // and we probably want to change the text of the email slightly to let the recipient // know that it's an update instead of a new incident. if (Configure::read('scoring.incident_reports') && $this->data['Game']['incident']) { $addr = Configure::read('email.incident_report_email'); $incident = $this->data['Incident'][$team_id]; $this->set(array('incident' => $incident, 'game' => $game['Game'], 'division' => $game['Division'], 'slot' => $game['GameSlot'], 'field' => $game['GameSlot']['Field'], 'home_team' => $game['HomeTeam'], 'away_team' => $game['AwayTeam'])); if ($this->_sendMail(array('to' => "Incident Manager <{$addr}>", 'replyTo' => $this->UserCache->read('Person.email_formatted'), 'subject' => "Incident report: {$incident['type']}", 'template' => 'incident_report', 'sendAs' => 'html'))) { // TODO: Maybe send the incident report before saving data, and add in a column for // whether it was sent, thus allowing the cron to attempt to re-send it? $resultMessage .= ' ' . __('Your incident report details have been sent for handling.', true); } else { App::import('Helper', 'Html'); $html = new HtmlHelper(); $link = $html->link($addr, "mailto:{$addr}"); $resultMessage .= ' ' . sprintf(__('There was an error sending your incident report details. Please send them to %s to ensure proper handling.', true), $link); $resultClass = 'warning'; } } if ($resultMessage) { $this->Session->setFlash($resultMessage, 'default', array('class' => $resultClass)); } if (League::hasStats($game['Division']['League']) && $this->data['Game']['collect_stats']) { $this->redirect(array('action' => 'submit_stats', 'game' => $id, 'team' => $team_id)); } else { $this->redirect('/'); } } else { $this->Session->setFlash(sprintf(__('The %s could not be saved. Please correct the errors below and try again.', true), __('game results', true)), 'default', array('class' => 'warning')); } } else { $this->data = $game; if (array_key_exists('status', $this->params['named'])) { $this->data['ScoreEntry'][$team_id] = $this->params['named']; } } $this->set(compact('game', 'team_id', 'spirit_obj')); $this->set('is_coordinator', in_array($game['Division']['id'], $this->UserCache->read('DivisionIDs'))); }
function edit() { $id = $this->_arg('registration'); if (!$id && empty($this->data)) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('registration', true)), 'default', array('class' => 'info')); $this->redirect('/'); } $this->Registration->contain(array('Person', 'Event' => array('EventType', 'Price', 'Questionnaire' => array('Question' => array('Answer' => array('conditions' => array('active' => true)), 'conditions' => array('active' => true))), 'Division' => 'League'), 'Price', 'Response')); $registration = $this->Registration->read(null, $id); if (!$registration) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('registration', true)), 'default', array('class' => 'info')); $this->redirect('/'); } if (!$this->is_admin && !$this->is_manager && !in_array($registration['Registration']['payment'], Configure::read('registration_none_paid'))) { $this->Session->setFlash(__('You cannot edit a registration once a payment has been made.', true), 'default', array('class' => 'info')); $this->redirect('/'); } $this->Configuration->loadAffiliate($registration['Event']['affiliate_id']); $test = $this->CanRegister->test($this->UserCache->currentId(), $registration, array('for_edit' => true, 'all_rules' => true)); $event_obj = $this->_getComponent('EventType', $registration['Event']['EventType']['type'], $this); $this->_mergeAutoQuestions($registration, $event_obj, $registration['Event']['Questionnaire'], $registration['Person']['id']); $this->set(compact('registration')); if (!empty($this->data)) { // Adjust data for saving, to prevent shenanigans $this->data['Registration']['id'] = $id; $this->Registration->Response->validate = array_merge($this->Questionnaire->validation($registration['Event']['Questionnaire'], true), $event_obj->registrationFieldsValidation($registration, true)); // Remove any unchecked checkboxes; we only save the checked ones. list($data, $delete) = $this->_splitResponses($this->data); // This is all a little fragile, because of the weird format of the data we're saving. // We need to first set the response data, then validate it. We can't rely on // Registration->save to validate properly. $this->Registration->Response->set($data); // Find the requested price option $price = Set::extract("/Price[id={$data['Registration']['price_id']}]/.", $registration['Event']); // Validation of payment data is a manual process if (empty($price)) { $this->Registration->validationErrors['price_id'] = 'Select a valid price option.'; } else { $price = reset($price); $cost = $price['cost'] + $price['tax1'] + $price['tax2']; $test = $test['price_allowed'][$price['id']]; $this->set(compact('price')); $this->set($test); if ($registration['Registration']['person_id'] == $this->UserCache->currentId() && !$test['allowed']) { if (!empty($test['reason'])) { $this->Registration->validationErrors['price_id'] = $test['reason']; } else { $this->Registration->validationErrors['price_id'] = $test['messages']; } } else { $data['Registration']['total_amount'] = $cost; if (!$price['allow_deposit']) { $data['Registration']['payment_type'] = 'Full'; } else { if ($price['deposit_only'] || $this->data['Registration']['payment_type'] == 'Deposit') { $this->data['Registration']['payment_type'] = 'Deposit'; if ($price['fixed_deposit']) { $data['Registration']['deposit_amount'] = $price['minimum_deposit']; } else { if ($this->data['Registration']['deposit_amount'] < $price['minimum_deposit']) { $this->Registration->validationErrors['deposit_amount'] = sprintf(__('A minimum deposit of $%s is required.', true), $price['minimum_deposit']); } else { if ($this->data['Registration']['deposit_amount'] >= $cost) { $this->Registration->validationErrors['deposit_amount'] = sprintf(__('This deposit exceeds the total cost of $%s.', true), $cost); } } } } } if ($data['Registration']['payment_type'] == 'Full') { $data['Registration']['deposit_amount'] = 0; } } } if (!$this->Registration->Response->validates() || !empty($this->Registration->validationErrors)) { $this->Session->setFlash(sprintf(__('The %s could not be saved. Please correct the errors below and try again.', true), __('registration', true)), 'default', array('class' => 'warning')); return; } // Wrap the whole thing in a transaction, for safety. $transaction = new DatabaseTransaction($this->Registration); // Remove any old response records that are no longer valid if (!empty($delete) && !$this->Registration->Response->deleteAll(array('id' => $delete), false)) { $this->Session->setFlash(sprintf(__('The %s could not be saved. Please correct the errors below and try again.', true), __('registration', true)), 'default', array('class' => 'warning')); return; } if (!$this->is_admin && !$this->is_manager) { // Players cannot change their own payment status $data['Registration']['payment'] = $registration['Registration']['payment']; } if (!$this->Registration->save($data, array('validate' => false))) { $this->Session->setFlash(sprintf(__('The %s could not be saved. Please correct the errors below and try again.', true), __('registration', true)), 'default', array('class' => 'warning')); return; } // If the payment status has changed, or questionnaire answers updated, we may need to do extra processing if (!$this->_postProcess($registration, $registration, $data, $registration['Registration']['payment'], $data['Registration']['payment'])) { return; } if ($transaction->commit() !== false) { if ($this->is_admin || $this->is_manager) { $this->Session->setFlash(sprintf(__('The %s has been saved', true), __('registration', true)), 'default', array('class' => 'success')); $this->redirect(array('controller' => 'people', 'action' => 'registrations', 'person' => $registration['Person']['id'])); } else { $this->Session->setFlash(__('Your preferences for this registration have been saved.', true), 'default', array('class' => 'success')); $this->redirect(array('action' => 'checkout')); } } } else { // Convert saved response data into the format required by the output $this->data = $registration; if ($this->data['Registration']['deposit_amount'] == 0) { // Unset the deposit amount if it's zero, so the default is correct unset($this->data['Registration']['deposit_amount']); } $responses = array(); foreach ($registration['Event']['Questionnaire']['Question'] as $question) { if (array_key_exists('id', $question)) { $saved = Set::extract("/Response[question_id={$question['id']}]", $registration); if (!empty($saved)) { if ($question['type'] == 'checkbox') { // Deal with both checkbox groups and single checkboxes if (!empty($question['Answer'])) { foreach ($question['Answer'] as $answer) { $id = Set::extract("/Response[answer_id={$answer['id']}]", $saved); if (!empty($id)) { $responses[Question::_formName($question, $answer)] = $id[0]['Response']; } } } else { $responses[Question::_formName($question)] = $saved[0]['Response']; } } else { $responses[Question::_formName($question)] = $saved[0]['Response']; } } } } $this->data['Response'] = $responses; // Find the saved price option $price = Set::extract("/Price[id={$registration['Registration']['price_id']}]/.", $registration); if (!empty($price)) { $price = reset($price); $this->set(compact('price')); if (array_key_exists('price_allowed', $test)) { $test = $test['price_allowed'][$price['id']]; $this->set($test); } } } }
function initialize() { $id = $this->_arg('badge'); if (!$id) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('badge', true)), 'default', array('class' => 'info')); $this->redirect(array('action' => 'index')); } $this->Badge->contain(); $badge = $this->Badge->read(null, $id); if (!$badge) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('badge', true)), 'default', array('class' => 'info')); $this->redirect(array('action' => 'index')); } if (in_array($badge['Badge']['category'], array('nominated', 'assigned', 'runtime', 'aggregate'))) { $this->Session->setFlash(sprintf(__('This badge is %s, not calculated, so it cannot be initialized.', true), __($badge['Badge']['category'], true)), 'default', array('class' => 'info')); $this->redirect(array('action' => 'index')); } if (empty($badge['Badge']['handler'])) { $this->Session->setFlash(__('This badge has no handler.', true), 'default', array('class' => 'info')); $this->redirect(array('action' => 'index')); } $this->Configuration->loadAffiliate($badge['Badge']['affiliate_id']); $this->set(compact('badge')); // TODO: Graceful handling of missing handlers $handler = $this->_getComponent('Badge', $badge['Badge']['handler'], $this); $count = 0; $transaction = new DatabaseTransaction($this->Badge); $this->Badge->BadgesPerson->deleteAll(array('badge_id' => $badge['Badge']['id'])); switch ($badge['Badge']['category']) { case 'team': $this->Team->contain(array('Division')); $teams = $this->Team->find('all'); foreach ($teams as $team) { if ($handler->applicable($team)) { $people = $this->Team->TeamsPerson->find('all', array('conditions' => array('TeamsPerson.team_id' => $team['Team']['id'], 'TeamsPerson.status' => ROSTER_APPROVED, 'TeamsPerson.role' => Configure::read('regular_roster_roles')), 'contain' => array())); foreach ($people as $person) { $badge_data = array('badge_id' => $badge['Badge']['id'], 'person_id' => $person['TeamsPerson']['person_id'], 'team_id' => $person['TeamsPerson']['team_id'], 'approved' => true); $this->Badge->BadgesPerson->create(); $this->Badge->BadgesPerson->save($badge_data); ++$count; } } } break; case 'game': $this->Game->contain(); $games = $this->Game->find('all'); foreach ($games as $game) { $people = array(); $this->Team->contain(array('Person' => array('conditions' => array('TeamsPerson.role' => Configure::read('regular_roster_roles'), 'TeamsPerson.status' => ROSTER_APPROVED)))); if ($handler->applicable($game, $game['Game']['home_team'])) { $people = $this->Team->read(null, $game['Game']['home_team']); } else { if ($handler->applicable($game, $game['Game']['away_team'])) { $people = $this->Team->read(null, $game['Game']['away_team']); } } if (!empty($people)) { foreach ($people['Person'] as $person) { $badge_data = array('badge_id' => $badge['Badge']['id'], 'person_id' => $person['id'], 'team_id' => $people['Team']['id'], 'game_id' => $game['Game']['id'], 'approved' => true); $this->Badge->BadgesPerson->create(); $this->Badge->BadgesPerson->save($badge_data); ++$count; } } } break; case 'registration': $this->Registration->Event->contain(array('EventType')); $events = $this->Registration->Event->find('all'); foreach ($events as $event) { if ($handler->applicable($event)) { $people = $this->Registration->find('all', array('conditions' => array('Registration.event_id' => $event['Event']['id'], 'Registration.payment' => Configure::read('registration_paid')), 'contain' => array())); foreach ($people as $person) { $badge_data = array('badge_id' => $badge['Badge']['id'], 'person_id' => $person['Registration']['person_id'], 'registration_id' => $person['Registration']['id'], 'approved' => true); $this->Badge->BadgesPerson->create(); $this->Badge->BadgesPerson->save($badge_data); ++$count; } } } break; default: $this->Session->setFlash(sprintf(__('Unrecognized badge category "%s".', true), __($badge['Badge']['category'], true)), 'default', array('class' => 'info')); $this->redirect(array('action' => 'index')); break; } $transaction->commit(); $this->Session->setFlash(sprintf(__('Badge has been initialized, and has been awarded %d times.', true), $count), 'default', array('class' => 'info')); $this->redirect(array('action' => 'view', 'badge' => $badge['Badge']['id'])); }
function delete() { $division_id = $this->_arg('division'); if (!$division_id) { $league_id = $this->_arg('league'); if (!$league_id) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('division', true)), 'default', array('class' => 'info')); $this->redirect(array('controller' => 'leagues', 'action' => 'index')); } $this->Division->League->contain(array('Division' => array('Day' => array('order' => 'day_id')))); $league = $this->Division->League->read(null, $league_id); if (!$league) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('league', true)), 'default', array('class' => 'info')); $this->redirect(array('controller' => 'leagues', 'action' => 'index')); } if (empty($league['Division'])) { $this->Session->setFlash(__('This league has no divisions yet.', true), 'default', array('class' => 'info')); $this->redirect(array('controller' => 'leagues', 'action' => 'index')); } $divisions = Set::extract('/Division/id', $league); $multi_day = count(array_unique(Set::extract('/Division[schedule_type!=tournament]/Day/id', $league))) > 1; $this->Configuration->loadAffiliate($league['League']['affiliate_id']); $this->_addLeagueMenuItems($league['League']); } else { $this->Division->contain(array('Day' => array('order' => 'day_id'), 'Team' => array('order' => 'Team.name'), 'League', 'Pool' => array('order' => 'Pool.id', 'PoolsTeam' => array('order' => 'PoolsTeam.id')))); $division = $this->Division->read(null, $division_id); if (!$division) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('division', true)), 'default', array('class' => 'info')); $this->redirect(array('controller' => 'leagues', 'action' => 'index')); } $divisions = array($division['Division']['id']); $league_id = $division['Division']['league_id']; $multi_day = $division['Division']['schedule_type'] != 'tournament' && count($division['Day']) > 1; $this->Configuration->loadAffiliate($division['League']['affiliate_id']); $this->_addDivisionMenuItems($division['Division'], $division['League']); } $this->set(compact('division_id', 'division', 'league_id', 'league')); $date = $this->_arg('date'); $pool_id = $this->_arg('pool'); $conditions = array('Game.division_id' => $divisions); if ($date) { if ($multi_day) { $first_day = Configure::read('organization.first_day'); $offset = (6 + $first_day - date('N', strtotime($date))) % 7; $conditions['GameSlot.game_date >='] = $date; $conditions[] = "GameSlot.game_date <= DATE_ADD('{$date}', INTERVAL {$offset} DAY)"; } else { $conditions['GameSlot.game_date'] = $date; } $contain = array('GameSlot'); } if ($pool_id) { $conditions['Game.pool_id'] = $pool_id; $contain = array(); $this->Division->Pool->contain(); $pool = $this->Division->Pool->read(null, $pool_id); } $games = $this->Division->Game->find('all', array('conditions' => $conditions, 'contain' => $contain)); $pools = array_unique(Set::extract('/Game/pool_id', $games)); if (!empty($pools)) { $reset_pools = $pools; if ($date) { $same_pool = $this->Division->Game->find('all', array('conditions' => array('Game.pool_id' => $pools, 'GameSlot.game_date !=' => $date), 'fields' => array('Game.id', 'Game.published', 'Game.home_score', 'Game.pool_id', 'Game.game_slot_id'), 'contain' => array('GameSlot'))); } $stages = $this->Division->Pool->find('list', array('conditions' => array('Pool.id' => $pools), 'fields' => array('Pool.id', 'Pool.stage'), 'contain' => array())); if (!empty($stages)) { $later_pools = $this->Division->Pool->find('list', array('conditions' => array('Pool.division_id' => $divisions, 'Pool.stage >' => max($stages)), 'fields' => array('Pool.id', 'Pool.id'), 'contain' => array())); if (!empty($later_pools)) { $reset_pools = array_merge($reset_pools, $later_pools); $dependent = $this->Division->Game->find('all', array('conditions' => array('Game.pool_id' => $later_pools), 'fields' => array('Game.id', 'Game.published', 'Game.home_score', 'Game.pool_id', 'Game.game_slot_id'), 'contain' => array())); } } } if ($this->_arg('confirm')) { // Wrap the whole thing in a transaction, for safety. $transaction = new DatabaseTransaction($this->Division->Game); // Reset dependencies for affected pools if (!empty($reset_pools)) { $this->Division->Pool->PoolsTeam->updateAll(array('team_id' => null), array('pool_id' => $reset_pools)); } // Clear assigned flag from game_slots, and delete the games. $game_ids = Set::extract('/Game/id', $games); $slot_ids = Set::extract('/Game/game_slot_id', $games); if (!empty($same_pool)) { $game_ids = array_merge($game_ids, Set::extract('/Game/id', $same_pool)); $slot_ids = array_merge($slot_ids, Set::extract('/Game/game_slot_id', $same_pool)); } if (!empty($dependent)) { $game_ids = array_merge($game_ids, Set::extract('/Game/id', $dependent)); $slot_ids = array_merge($slot_ids, Set::extract('/Game/game_slot_id', $dependent)); } if ($this->Division->Game->GameSlot->updateAll(array('assigned' => 0), array('GameSlot.id' => $slot_ids)) && $this->Division->Game->deleteAll(array('Game.id' => $game_ids), false)) { if ($date) { $this->Session->setFlash(__('Deleted games on the requested date.', true), 'default', array('class' => 'success')); } else { $this->Session->setFlash(__('Deleted games from the requested pool.', true), 'default', array('class' => 'success')); } $transaction->commit(); foreach ($divisions as $id) { Cache::delete("division/{$id}/standings", 'long_term'); Cache::delete("division/{$id}/schedule", 'long_term'); } Cache::delete("league/{$league_id}/standings", 'long_term'); Cache::delete("league/{$league_id}/schedule", 'long_term'); if (isset($league)) { $this->redirect(array('controller' => 'leagues', 'action' => 'schedule', 'league' => $league_id)); } else { $this->redirect(array('controller' => 'divisions', 'action' => 'schedule', 'division' => $division_id)); } } else { $this->Session->setFlash(__('Failed to delete games on the requested date.', true), 'default', array('class' => 'warning')); } } $this->set(compact('date', 'pool_id', 'pool', 'games', 'same_pool', 'dependent')); }
function edit() { $id = $this->_arg('league'); if (!$id && empty($this->data)) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('league', true)), 'default', array('class' => 'info')); $this->redirect(array('action' => 'index')); } if (!empty($this->data)) { Configure::load("sport/{$this->data['League']['sport']}"); $this->Configuration->loadAffiliate($this->data['League']['affiliate_id']); if (array_key_exists('Day', $this->data['League'])) { $this->data['Day'] = $this->data['League']['Day']; } $transaction = new DatabaseTransaction($this->League); // Division->saveAll needs to not have League data in it if (array_key_exists('Division', $this->data)) { $division = $this->data; unset($division['League']); } if (isset($division) && $division['Division']['schedule_type'] != 'none' && (empty($this->data['Day']) || empty($this->data['Day'][0]))) { $this->League->save($this->data, array('validate' => 'only')); $this->League->Division->saveAll($division, array('validate' => 'only')); $this->League->validationErrors['Day'] = sprintf(__('You must select at least one %s!', true), __('day', true)); } else { if ($this->League->save($this->data) && (!isset($division) || $this->League->Division->saveAll($division))) { // Any time that this is called, the division seeding might change. // We just reset it here, and it will be recalculated as required elsewhere. if (isset($division)) { $divisions = array($this->data['Division']['id']); } else { $divisions = $this->League->divisions($id); } $this->League->Division->Team->updateAll(array('seed' => 0), array('Team.division_id' => $divisions)); foreach ($divisions as $division) { Cache::delete("division/{$division}/standings", 'long_term'); Cache::delete("division/{$division}/schedule", 'long_term'); } Cache::delete("league/{$id}/standings", 'long_term'); Cache::delete("league/{$id}/schedule", 'long_term'); $transaction->commit(); $this->Session->setFlash(sprintf(__('The %s has been saved', true), __('league', true)), 'default', array('class' => 'success')); $this->redirect(array('action' => 'index')); } } $this->Session->setFlash(sprintf(__('The %s could not be saved. Please correct the errors below and try again.', true), __('league', true)), 'default', array('class' => 'warning')); $this->Configuration->loadAffiliate($this->League->affiliate($id)); } // Very likely that we need to read existing league information for menu purposes $this->League->contain(array('Division' => array('Person', 'Day' => array('order' => 'day_id')), 'StatType')); $v = $this->League->validationErrors; $this->League->read(null, $id); $this->League->validationErrors = $v; if (!$this->League->data) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('league', true)), 'default', array('class' => 'info')); $this->redirect(array('action' => 'index')); } foreach (array_keys($this->League->data['Division']) as $key) { Division::_addNames($this->League->data['Division'][$key], $this->League->data['League']); } $this->_addLeagueMenuItems($this->League->data); $this->Configuration->loadAffiliate($this->League->data['League']['affiliate_id']); if (count($this->League->data['Division']) == 1) { // Adjust loaded data $this->League->data['Division'] = array_pop($this->League->data['Division']); $this->League->data['Day'] = $this->League->data['Division']['Day']; $this->set('league_obj', $this->_getComponent('LeagueType', $this->League->data['Division']['schedule_type'], $this)); $this->set('is_coordinator', false); } if (empty($this->data)) { $this->data = $this->League->data; Configure::load("sport/{$this->data['League']['sport']}"); } $this->set('days', $this->League->Division->Day->find('list')); $this->set('sport', $this->data['League']['sport']); $this->set('stat_types', $this->League->StatType->find('all', array('conditions' => array('sport' => $this->data['League']['sport'])))); $this->set('affiliates', $this->_applicableAffiliates(true)); if (Configure::read('feature.tiny_mce')) { $this->helpers[] = 'TinyMce.TinyMce'; } }
function submit_score() { $id = $this->_arg('slot'); if (!$id) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('game slot', true)), 'default', array('class' => 'info')); $this->redirect('/'); } $this->GameSlot->contain(array('Game' => array('HomeTeam', 'HomePoolTeam' => 'DependencyPool', 'Division' => 'League'), 'Field' => array('Facility' => 'Region'))); $gameSlot = $this->GameSlot->read(null, $id); if (!$gameSlot) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('game slot', true)), 'default', array('class' => 'info')); $this->redirect('/'); } if (empty($gameSlot['Game'])) { $this->Session->setFlash(__('This game slot has no games associated with it.', true), 'default', array('class' => 'info')); $this->redirect('/'); } $game = $gameSlot['Game'][0]; if ($game['Division']['schedule_type'] != 'competition') { $this->Session->setFlash(__('You can only enter scores for multiple games in "competition" divisions.', true), 'default', array('class' => 'info')); $this->redirect('/'); } if (Game::_is_finalized($game)) { $this->Session->setFlash(__('Games in this slot have already been finalized.', true), 'default', array('class' => 'info')); $this->redirect('/'); } $end_time = strtotime("{$gameSlot['GameSlot']['game_date']} {$gameSlot['GameSlot']['display_game_end']}") + Configure::read('timezone.adjust') * 60; if ($end_time - 60 * 60 > time()) { $this->Session->setFlash(__('That game has not yet occurred!', true), 'default', array('class' => 'info')); $this->redirect('/'); } // We need this in a couple of places if (League::hasSpirit($game['Division']['League'])) { $spirit_obj = $this->_getComponent('Spirit', $game['Division']['League']['sotg_questions'], $this); } $this->Configuration->loadAffiliate($gameSlot['Field']['Facility']['Region']['affiliate_id']); Configure::load("sport/{$game['Division']['League']['sport']}"); $ratings_obj = $this->_getComponent('Ratings', $game['Division']['rating_calculator'], $this); $this->set(compact('gameSlot')); if (!empty($this->data)) { $teams = $games = $incidents = $errors = array(); $unplayed = in_array($this->data['Game']['status'], Configure::read('unplayed_status')); // We could put these as hidden fields in the form, but we'd need to // validate them against the values from the URL anyway, so it's // easier to just set them directly here. // We use the team_id as the array index, here and in the views, // because order matters, and this is a good way to ensure that // the correct data gets into the correct form. foreach ($gameSlot['Game'] as $i => $game) { if (!array_key_exists($game['home_team'], $this->data['Game'])) { $errors[$game['home_team']]['home_score'] = 'Scores must be entered for all teams.'; } else { $details = $this->data['Game'][$game['home_team']]; if ($unplayed) { $score = $rating = null; } else { $score = $details['home_score']; $rating = $ratings_obj->calculateRatingsChange($details['home_score']); $teams[$game['home_team']] = array('id' => $game['home_team'], 'rating' => $game['HomeTeam']['rating'] + $rating, 'seed' => 0); } $games[$game['home_team']] = array('id' => $game['id'], 'status' => $this->data['Game']['status'], 'home_score' => $score, 'rating_points' => $rating, 'approved_by' => $this->UserCache->currentId()); if ($details['incident']) { $incidents[$game['home_team']] = array('game_id' => $game['id'], 'team_id' => $game['home_team'], 'type' => $details['type'], 'details' => $details['details'], 'game' => $game); } } } if (!empty($errors)) { $this->GameSlot->Game->validationErrors = $errors; } else { $transaction = new DatabaseTransaction($this->GameSlot); if ($this->GameSlot->Game->saveAll($games, array('validate' => 'first'))) { if (Configure::read('scoring.incident_reports') && !empty($incidents)) { if (!$this->GameSlot->Game->Incident->saveAll($incidents, array('validate' => 'first'))) { $this->Session->setFlash(sprintf(__('The %s could not be saved. Please correct the errors below and try again.', true), __('incident data', true)), 'default', array('class' => 'warning')); return; } } // TODO: Replace this with a call to GamesController::_adjustScoreAndRatings, which will // need to be moved to a shared location and adjusted to handle competition differences. // For now, all that function does that this doesn't is stats, and we have no idea how // stats might play out in competition divisions, so this will suffice. $this->GameSlot->Game->Division->Team->saveAll($teams); $transaction->commit(); foreach ($gameSlot['Game'] as $i => $game) { Cache::delete("division/{$game['Division']['id']}/standings", 'long_term'); Cache::delete("division/{$game['Division']['id']}/schedule", 'long_term'); Cache::delete('league/' . $this->GameSlot->Game->Division->league($game['Division']['id']) . '/standings', 'long_term'); Cache::delete('league/' . $this->GameSlot->Game->Division->league($game['Division']['id']) . '/schedule', 'long_term'); } $resultMessage = __('Scores have been saved and game results posted.', true); $resultClass = 'success'; // TODO: Check for changes to the incident text to avoid sending a duplicate email, // and we probably want to change the text of the email slightly to let the recipient // know that it's an update instead of a new incident. // TODO: Combine code from here and games controller? $incidentMessage = ''; if (Configure::read('scoring.incident_reports')) { $addr = Configure::read('email.incident_report_email'); foreach ($incidents as $incident) { $this->set(array('incident' => $incident, 'game' => $incident['game'], 'division' => $incident['game']['Division'], 'slot' => $gameSlot['GameSlot'], 'field' => $gameSlot['Field'], 'home_team' => $incident['game']['HomeTeam'])); if ($this->_sendMail(array('to' => "Incident Manager <{$addr}>", 'replyTo' => $this->UserCache->read('Person.email_formatted'), 'subject' => "Incident report: {$incident['type']}", 'template' => 'incident_report', 'sendAs' => 'html'))) { // TODO: Maybe send the incident report before saving data, and add in a column for // whether it was sent, thus allowing the cron to attempt to re-send it? $incidentMessage = ' ' . __('Your incident report details have been sent for handling.', true); } else { App::import('Helper', 'Html'); $html = new HtmlHelper(); $link = $html->link($addr, "mailto:{$addr}"); $incidentMessage = ' ' . sprintf(__('There was an error sending your incident report details. Please send them to %s to ensure proper handling.', true), $link); $resultClass = 'warning'; } } } $resultMessage .= $incidentMessage; if ($resultMessage) { $this->Session->setFlash($resultMessage, 'default', array('class' => $resultClass)); } $this->redirect('/'); } else { $this->Session->setFlash(sprintf(__('The %s could not be saved. Please correct the errors below and try again.', true), __('scores', true)), 'default', array('class' => 'warning')); } } } }
function edit() { $id = $this->_arg('facility'); if (!$id && empty($this->data)) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('facility', true)), 'default', array('class' => 'info')); $this->redirect(array('action' => 'index')); } if (!empty($this->data)) { $transaction = new DatabaseTransaction($this->Facility); if ($this->Facility->save($this->data) && $this->Facility->Field->save($this->data)) { if (!$this->data['Facility']['is_open']) { $this->Facility->Field->updateAll(array('is_open' => 0), array('Field.facility_id' => $id)); } $transaction->commit(); $this->Session->setFlash(sprintf(__('The %s has been saved', true), __('facility', true)), 'default', array('class' => 'success')); $this->redirect(array('action' => 'index')); } else { $this->Session->setFlash(sprintf(__('The %s could not be saved. Please correct the errors below and try again.', true), __('facility', true)), 'default', array('class' => 'warning')); $this->Configuration->loadAffiliate($this->Facility->affiliate($id)); } } if (empty($this->data)) { $this->Facility->contain(array('Region', 'Field')); $this->data = $this->Facility->read(null, $id); if (!$this->data) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('facility', true)), 'default', array('class' => 'info')); $this->redirect(array('action' => 'index')); } $this->Configuration->loadAffiliate($this->data['Region']['affiliate_id']); if (count($this->data['Field']) == 1) { // Adjust loaded data $this->data['Field'] = array_pop($this->data['Field']); } } $affiliates = $this->_applicableAffiliates(true); $regions = $this->Facility->Region->find('list', array('conditions' => array('Region.affiliate_id' => array_keys($affiliates)))); $this->set(compact('regions', 'affiliates')); $this->_loadAddressOptions(); $this->set('region', $this->_arg('region')); if (Configure::read('feature.tiny_mce')) { $this->helpers[] = 'TinyMce.TinyMce'; } }
function _setRosterRole($person, $team, $role, $status) { if (!isset($this->Roster)) { $this->Roster = ClassRegistry::init('TeamsPerson'); } // We can always remove people from rosters if ($role == 'none') { $transaction = new DatabaseTransaction($this->Roster); if ($this->Roster->delete($person['Person']['TeamsPerson']['id'])) { // Delete any future attendance records if ($this->Team->Attendance->deleteAll(array('Attendance.team_id' => $team['Team']['id'], 'Attendance.person_id' => $person['Person']['id'], 'Attendance.game_date > CURDATE()'))) { $transaction->commit(); $this->Session->setFlash(__('Removed the player from the team.', true), 'default', array('class' => 'success')); if (Configure::read('feature.generate_roster_email')) { $this->_sendRemove($person, $team); } $this->UserCache->_deleteTeamData($person['Person']['id']); return true; } } $this->Session->setFlash(__('Failed to remove the player from the team.', true), 'default', array('class' => 'warning')); return false; } $can_add = $this->_canAdd($person, $team, $role, $status); if ($can_add === true) { // Under certain circumstances, an invite is changed to an add if ($status === ROSTER_INVITED && ($team['Division']['roster_method'] == 'add' || $this->effective_admin) && in_array($role, Configure::read('playing_roster_roles'))) { $status = ROSTER_APPROVED; } } else { if ($status === ROSTER_INVITED) { // Redo the test, without being strict $can_add = $this->_canAdd($person, $team, $role, $status, false, false, true); if ($can_add !== true) { // Set the reason that they can't be added for the email $this->set('accept_warning', $can_add); $can_add = $this->_canInvite($person, $team, $role); } } if ($can_add !== true) { $this->Session->setFlash($can_add, 'default', array('class' => 'warning')); return false; } } if (empty($person['Person']['TeamsPerson'])) { $this->Roster->create(); } else { $this->Roster->id = $person['Person']['TeamsPerson']['id']; } $success = $this->Roster->save(array('team_id' => $team['Team']['id'], 'person_id' => $person['Person']['id'], 'role' => $role, 'status' => $status)); // If we were successful in the update, there may be emails to send if ($success) { $this->UserCache->_deleteTeamData($person['Person']['id']); if (!Configure::read('feature.generate_roster_email')) { return true; } $this->set('code', $this->_hash(array('id' => $this->Roster->id, 'team_id' => $team['Team']['id'], 'person_id' => $person['Person']['id'], 'role' => $role, 'created' => date('Y-m-d')))); if (empty($person['Person']['TeamsPerson'])) { switch ($status) { case ROSTER_APPROVED: $this->_sendAdd($person, $team, $role); break; case ROSTER_INVITED: $this->_sendInvite($person, $team, $role); break; case ROSTER_REQUESTED: $this->_sendRequest($person, $team, $role); break; } } else { $this->_sendChange($person, $team, $role); } return true; } else { $this->Session->setFlash(__('Failed to set player to that state.', true), 'default', array('class' => 'warning')); return false; } }
function finishSchedule($division_id, $publish, $double_booking) { if (empty($this->games)) { return false; } // Add the publish flag and division id to every game foreach (array_keys($this->games) as $i) { $this->games[$i]['division_id'] = $division_id; $this->games[$i]['published'] = $publish; if (!array_key_exists('round', $this->games[$i])) { $this->games[$i]['round'] = $this->division['Division']['current_round']; } } // Check that chosen game slots didn't somehow get allocated elsewhere in the meantime if (!$double_booking) { $slots = Set::extract('/game_slot_id', $this->games); $this->_controller->Division->Game->GameSlot->contain(); $taken = $this->_controller->Division->Game->GameSlot->find('all', array('conditions' => array('id' => $slots, 'assigned' => true))); if (!empty($taken)) { $this->_controller->Session->setFlash(__('A game slot chosen for this schedule has been allocated elsewhere in the interim. Please try again.', true), 'default', array('class' => 'warning')); return false; } } $transaction = new DatabaseTransaction($this->_controller->Division->Game); // for($x as $k => $v) works on a cached version of $x, so any changes // to the games made in beforeSave or afterSave will show up in // $this->games but not in the game variables as we iterate through. // So, iterate over the array keys instead and use that to directly // reference the array. foreach (array_keys($this->games) as $key) { $this->_controller->Division->Game->create(); if (!$this->beforeSave($key) || !$this->_controller->Division->Game->save($this->games[$key]) || !$this->afterSave($key)) { return false; } } return $transaction->commit() !== false; }
function cron() { if (!Configure::read('feature.registration')) { return; } $this->layout = 'bare'; if (!ini_get('safe_mode')) { set_time_limit(1800); } if (!$this->Lock->lock('cron')) { return false; } $transaction = new DatabaseTransaction($this->Event); // Update any event open and close dates that have changed because of prices // being added or edited $prices = $this->Event->Price->find('all', array('conditions' => array('OR' => array('Price.open != Event.open', 'Price.close != Event.close')), 'contain' => 'Event')); $events = array(); foreach ($prices as $price) { if (!array_key_exists($price['Price']['event_id'], $events)) { $events[$price['Price']['event_id']] = array('id' => $price['Price']['event_id'], 'open' => $price['Price']['open'], 'close' => $price['Price']['close']); } else { $events[$price['Price']['event_id']]['open'] = min($events[$price['Price']['event_id']]['open'], $price['Price']['open']); $events[$price['Price']['event_id']]['close'] = max($events[$price['Price']['event_id']]['close'], $price['Price']['close']); } } foreach ($events as $id => $event) { $saved = Set::extract("/Event[id={$id}]", $prices); if ($saved[0]['Event']['open'] == $event['open'] && $saved[0]['Event']['close'] == $event['close']) { unset($events[$id]); } } if (!empty($events)) { $this->Event->saveAll($events); } $transaction->commit(); if (!Configure::read('feature.badges')) { $this->Lock->unlock(); return; } $badges = $this->Event->Registration->Person->Badge->find('all', array('conditions' => array('Badge.category' => 'registration', 'Badge.active' => true), 'contain' => array())); if (empty($badges)) { $this->Lock->unlock(); return; } $badge_obj = $this->_getComponent('badge', '', $this); $transaction = new DatabaseTransaction($this->Event); $activity_log = ClassRegistry::init('ActivityLog'); $today = date('Y-m-d'); // Find all membership events for which the membership has started, // but we haven't opened it. The only ones that can possibly be // opened are ones that are closed, but not even all of those will be. $events = $this->Event->find('all', array('conditions' => array('NOT' => array('id' => $activity_log->find('list', array('conditions' => array('type' => 'membership_opened'), 'fields' => array('id', 'custom')))), 'open <= CURDATE()', 'affiliate_id' => $this->_applicableAffiliateIDs(), 'event_type_id' => $this->Event->EventType->find('list', array('conditions' => array('type' => 'membership'), 'fields' => array('id', 'id')))), 'contain' => array())); foreach ($events as $event) { if ($event['Event']['membership_begins'] <= $today) { $this->Event->contain(array('Registration' => array('conditions' => array('Registration.payment' => Configure::read('registration_paid'))))); $event = $this->Event->read(null, $event['Event']['id']); foreach ($event['Registration'] as $person) { // We are only dealing with paid and pending registrations, so the $extra parameter is true $badge_obj->update('registration', array('Registration' => $person), true); } $activity_log->create(); $activity_log->save(array('type' => 'membership_opened', 'custom' => $event['Event']['id'])); } } // Find all membership events for which the membership has ended, // but we haven't closed it. The only ones that can possibly be // ended are ones that are closed, but not even all of those will be. $events = $this->Event->find('all', array('conditions' => array('NOT' => array('id' => $activity_log->find('list', array('conditions' => array('type' => 'membership_closed'), 'fields' => array('id', 'custom')))), 'close < CURDATE()', 'affiliate_id' => $this->_applicableAffiliateIDs(), 'event_type_id' => $this->Event->EventType->find('list', array('conditions' => array('type' => 'membership'), 'fields' => array('id', 'id')))), 'contain' => array())); foreach ($events as $event) { if ($event['Event']['membership_ends'] < $today) { $this->Event->contain(array('Registration' => array('conditions' => array('Registration.payment' => Configure::read('registration_paid'))))); $event = $this->Event->read(null, $event['Event']['id']); foreach ($event['Registration'] as $person) { // We are only dealing with paid and pending registrations, so the $extra parameter is true $badge_obj->update('registration', array('Registration' => $person), true); } $activity_log->create(); $activity_log->save(array('type' => 'membership_closed', 'custom' => $event['Event']['id'])); } } $transaction->commit(); $this->Lock->unlock(); }