function applicable($game, $team_id) { if (Game::_is_finalized($game) && $game['Game']['type'] == BRACKET_GAME && ($game['Game']['name'] == '1st' || strpos($game['Game']['name'], '-1st') !== false)) { if ($game['Game']['home_team'] == $team_id && $game['Game']['home_score'] > $game['Game']['away_score']) { return true; } if ($game['Game']['away_team'] == $team_id && $game['Game']['away_score'] > $game['Game']['home_score']) { return true; } } return false; }
function submit_stats() { $id = $this->_arg('game'); if (!$id) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('game', true)), 'default', array('class' => 'info')); $this->redirect('/'); } $this->Game->contain(array('Division' => array('League' => array('StatType' => array('conditions' => array('StatType.type' => 'entered'))), 'Day'), 'GameSlot' => array('Field' => 'Facility'), 'ScoreEntry', 'ScoreDetail' => array('ScoreDetailStat'), 'HomeTeam', 'AwayTeam')); $game = $this->Game->read(null, $id); if (!$game) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('game', true)), 'default', array('class' => 'info')); $this->redirect('/'); } $team_id = $this->_arg('team'); // Allow specified individuals (referees, umpires, volunteers) to submit stats without a team id if (!$this->is_volunteer && !$this->is_official && !$team_id && !in_array($game['Division']['id'], $this->UserCache->read('DivisionIDs'))) { $this->Session->setFlash(__('You must provide a team ID.', true), 'default', array('class' => 'info')); $this->redirect('/'); } if (!League::hasStats($game['Division']['League'])) { $this->Session->setFlash(__('That league does not have stat tracking enabled!', true), 'default', array('class' => 'info')); $this->redirect('/'); } if ($team_id && $team_id != $game['Game']['home_team'] && $team_id != $game['Game']['away_team']) { $this->Session->setFlash(__('That team did not play in that game!', true), 'default', array('class' => 'info')); $this->redirect('/'); } if (!Game::_is_finalized($game)) { $this->Game->_adjustEntryIndices($game); if ($team_id && !array_key_exists($team_id, $game['ScoreEntry'])) { $this->Session->setFlash(__('You must submit a score for this game before you can submit stats.', true), 'default', array('class' => 'info')); $this->redirect(array('action' => 'submit_score', 'game' => $id, 'team' => $team_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('/'); } $this->Configuration->loadAffiliate($game['Division']['League']['affiliate_id']); Configure::load("sport/{$game['Division']['League']['sport']}"); $sport_obj = $this->_getComponent('Sport', $game['Division']['League']['sport'], $this); // Remove any empty stats. We DON'T remove '0' stats, as that's still a stat. $teams = array_unique(Set::extract('/Stat/team_id', $this->data)); $entry_stats = Set::extract('/StatType/id', $game['Division']['League']); if (!empty($this->data)) { $had_data = true; foreach ($this->data['Stat'] as $key => $datum) { if ($datum['value'] === '' || !in_array($datum['stat_type_id'], $entry_stats)) { unset($this->data['Stat'][$key]); } } // Locate existing records that we want to delete $to_delete = $this->Game->Stat->find('list', array('conditions' => array('game_id' => $id, 'team_id' => $teams, 'NOT' => array('id' => Set::extract('/Stat/id', $this->data))), 'contain' => array())); } if (!empty($to_delete) || !empty($this->data['Stat'])) { $transaction = new DatabaseTransaction($this->Game->Stat); } if (!empty($to_delete)) { if (!$this->Game->Stat->deleteAll(array('Stat.id' => $to_delete))) { $this->Session->setFlash(sprintf(__('Failed to delete previously saved %s', true), __('stats', true)), 'default', array('class' => 'error')); unset($transaction); } else { // This will be overridden, unless the user erased all previous stats and didn't enter new ones $this->Session->setFlash(sprintf(__('The previously saved %s have been removed.', true), __('stats', true)), 'default', array('class' => 'success')); } } if (!empty($this->data['Stat'])) { if (isset($transaction)) { // Add calculated stats to the array to be saved. We will have deleted any prior calculated stats above. $calc_stats = $this->Game->Division->League->StatType->find('all', array('contain' => array(), 'conditions' => array('StatType.type' => 'game_calc', 'StatType.sport' => $game['Division']['League']['sport']), 'fields' => array('id', 'handler'))); foreach ($calc_stats as $stat_type) { $func = "{$stat_type['StatType']['handler']}_game"; if (method_exists($sport_obj, $func)) { $sport_obj->{$func}($stat_type['StatType'], $game, $this->data); } else { trigger_error("Game stat handler {$stat_type['StatType']['handler']} was not found in the {$game['Division']['League']['sport']} component!", E_USER_ERROR); } } if ($this->Game->Stat->saveAll($this->data['Stat'], array('validate' => 'first'))) { $this->Session->setFlash(sprintf(__('The %s have been saved', true), __('stats', true)), 'default', array('class' => 'success')); $transaction->commit(); if ($team_id) { Cache::delete("team/{$team_id}/stats", 'long_term'); } else { Cache::delete("team/{$game['Game']['home_team']}/stats", 'long_term'); Cache::delete("team/{$game['Game']['away_team']}/stats", 'long_term'); } Cache::delete("division/{$game['Division']['id']}/stats", 'long_term'); Cache::delete('league/' . $this->Game->Division->league($game['Division']['id']) . '/stats', 'long_term'); $this->redirect(array('action' => 'view', 'game' => $id)); } else { $this->Session->setFlash(sprintf(__('The %s could not be saved. Please correct the errors below and try again.', true), __('stats', true)), 'default', array('class' => 'warning')); } } else { // The deletion above failed, so we don't want to try to save the other data, // but let's validate it anyway, in case there's errors we can report. $this->Game->Stat->saveAll($this->data['Stat'], array('validate' => 'only')); } } else { if (isset($transaction)) { // This will happen if stats were previously saved but all were erased in the input form. // Since there was no new data to save, commit the deletions. $transaction->commit(); $this->redirect(array('action' => 'view', 'game' => $id)); } else { if (isset($had_data)) { // This will happen if an empty form was submitted. $this->Session->setFlash(__('You did not submit any stats. You can return to complete this at any time.', true), 'default', array('class' => 'info')); $this->redirect(array('action' => 'view', 'game' => $id)); } } $this->data = $this->Game->Stat->find('all', array('contain' => array(), 'conditions' => array('game_id' => $id))); if (empty($this->data)) { // Extract counts of stats per player from the live scoring $this->data['Stat'] = array(); foreach ($game['ScoreDetail'] as $detail) { foreach ($detail['ScoreDetailStat'] as $stat) { $key = "{$stat['person_id']}:{$stat['stat_type_id']}"; if (!array_key_exists($key, $this->data['Stat'])) { $this->data['Stat'][$key] = array('game_id' => $id, 'team_id' => $detail['team_id'], 'person_id' => $stat['person_id'], 'stat_type_id' => $stat['stat_type_id'], 'value' => 1); } else { ++$this->data['Stat'][$key]['value']; } } } $this->data['Stat'] = array_values($this->data['Stat']); } else { // Reformat the data into the form needed for saving multiple records, // which is the same form the display expects, in case errors cause it // to be redisplayed. $this->data = array('Stat' => Set::extract('/Stat/.', $this->data)); } } if ($team_id) { $attendance = $this->Game->_read_attendance($team_id, Set::extract('/Division/Day/id', $game), $id, null, true); usort($attendance['Person'], array('Person', 'comparePerson')); } else { $home_attendance = $this->Game->_read_attendance($game['Game']['home_team'], Set::extract('/Division/Day/id', $game), $id, null, true); usort($home_attendance['Person'], array('Person', 'comparePerson')); $away_attendance = $this->Game->_read_attendance($game['Game']['away_team'], Set::extract('/Division/Day/id', $game), $id, null, true); usort($away_attendance['Person'], array('Person', 'comparePerson')); } $this->set(compact('game', 'team_id', 'attendance', 'home_attendance', 'away_attendance', 'sport_obj')); }
function initialize_dependencies() { $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')); } $date = $this->_arg('date'); $pool = $this->_arg('pool'); $this->Division->contain(array('Day' => array('order' => 'day_id'), 'Team' => array('Franchise'), 'League', 'Game' => array('GameSlot', 'HomePoolTeam' => array('Pool', 'DependencyPool'), 'AwayPoolTeam' => array('Pool', 'DependencyPool'), 'conditions' => array('NOT' => array('Game.status' => Configure::read('unplayed_status'))), 'order' => 'Game.id'))); $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']); $conditions = array('Game.division_id' => $id, 'Game.type !=' => SEASON_GAME, 'Game.approved_by' => null, 'OR' => array('HomePoolTeam.dependency_type' => array('seed', 'pool', 'ordinal', 'copy'), 'AwayPoolTeam.dependency_type' => array('seed', 'pool', 'ordinal', 'copy'))); // If there are tournament pools with finalized games in them, we do not want to // initialize any games in those pools. $finalized_pools = array_unique(Set::extract('/Game[approved_by!=][pool_id!=]/pool_id', $division)); if (!empty($finalized_pools)) { $conditions['NOT'] = array('Game.pool_id' => $finalized_pools); } if ($pool) { if (in_array($pool, $finalized_pools)) { $this->Session->setFlash(__('There are already games finalized in this pool. Unable to proceed.', true), 'default', array('class' => 'warning')); $this->redirect(array('action' => 'schedule', 'division' => $id)); } $conditions['Game.pool_id'] = $pool; } $games = $this->Division->Game->find('all', array('contain' => array('HomePoolTeam', 'AwayPoolTeam', 'GameSlot'), 'conditions' => $conditions)); if ($date) { $multi_day = $division['Division']['schedule_type'] != 'tournament' && count($division['Day']) > 1; if ($multi_day) { $first_day = Configure::read('organization.first_day'); $offset = (6 + $first_day - date('N', strtotime($date))) % 7; $end = date('Y-m-d', strtotime($date) + $offset * DAY); $games = Set::extract("/GameSlot[game_date>={$date}][game_date<={$end}]/..", $games); } else { $games = Set::extract("/GameSlot[game_date={$date}]/..", $games); } } if (empty($games)) { $this->Session->setFlash(__('There are currently no dependencies to initialize in this division.', true), 'default', array('class' => 'warning')); $this->redirect(array('action' => 'schedule', 'division' => $id)); } $pools = array_unique(Set::extract('/Game/pool_id', $games)); if ($division['Division']['schedule_type'] == 'tournament') { $seeds = Set::extract('/Team/initial_seed', $division); if (count($division['Team']) != count(array_unique($seeds))) { $this->Session->setFlash(__('Each team must have a unique initial seed.', true), 'default', array('class' => 'warning')); $this->redirect(array('action' => 'seeds', 'division' => $id)); } } $league_obj = $this->_getComponent('LeagueType', $division['Division']['schedule_type'], $this); $spirit_obj = $this->_getComponent('Spirit', $division['League']['sotg_questions'], $this); $league_obj->sort($division['Team'], $division['Division'], $division['League'], $division['Game'], $spirit_obj, false); $reset = $this->_arg('reset'); $operation = $reset ? 'reset' : 'update'; // Wrap the whole thing in a transaction, for safety. $transaction = new DatabaseTransaction($this->Division); // Go through all games, updating seed dependencies foreach ($division['Game'] as $game) { if (!in_array($game['pool_id'], $pools)) { continue; } if (Game::_is_finalized($game)) { continue; } $this->Division->Game->id = $game['id']; foreach (array('Home', 'Away') as $type) { if (!empty($game["{$type}PoolTeam"])) { $field = low($type) . '_team'; $this->Division->Game->HomePoolTeam->id = $game["{$type}PoolTeam"]['id']; if ($reset) { $team_id = null; } else { switch ($game["{$type}PoolTeam"]['dependency_type']) { case 'seed': $seed = $game["{$type}PoolTeam"]['dependency_id']; if ($seed > count($division['Team'])) { $this->Session->setFlash(__('Not enough teams in the division to fulfill all scheduled seeds', true), 'default', array('class' => 'warning')); $this->redirect(array('action' => 'schedule', 'division' => $id)); } $team_id = $division['Team'][$seed - 1]['id']; break; case 'pool': $stage = $game["{$type}PoolTeam"]['DependencyPool']['stage']; $pool_id = $game["{$type}PoolTeam"]['dependency_pool_id']; $seed = $game["{$type}PoolTeam"]['dependency_id']; $results = $division['Division']['Pools'][$stage][$pool_id]['Results']; usort($results, array($league_obj, 'compareTeamsResults')); $league_obj->detectAndResolveTies($results, 'compareTeamsResults'); $team_id = $results[$seed - 1]['id']; break; case 'ordinal': // The stage we're looking at for these results might be the // one before this one, or it might be two stages ago, if // the previous stage was crossover games. $stage = $game["{$type}PoolTeam"]['Pool']['stage'] - 1; $pool_id = reset(array_keys($division['Division']['Pools'][$stage])); if ($division['Division']['Pools'][$stage][$pool_id]['Game'][0]['HomePoolTeam']['Pool']['type'] == 'crossover') { --$stage; } $ordinal = $game["{$type}PoolTeam"]['dependency_ordinal']; $teams = array(); foreach ($division['Division']['Pools'][$stage] as $pool_id => $results) { usort($results['Team'], array($league_obj, 'compareTeamsResults')); $league_obj->detectAndResolveTies($results['Team'], 'compareTeamsResults'); $teams[] = $results['Team'][$ordinal - 1]; } usort($teams, array($league_obj, 'compareTeamsResultsCrossPool')); $seed = $game["{$type}PoolTeam"]['dependency_id']; $team_id = $teams[$seed - 1]['id']; break; } } if (!$this->Division->Game->saveField($field, $team_id) || !$this->Division->Game->HomePoolTeam->saveField('team_id', $team_id)) { $this->Session->setFlash(sprintf(__('Failed to %s game dependency', true), __($operation, true)), 'default', array('class' => 'warning')); $this->redirect(array('action' => 'schedule', 'division' => $id)); } $game[$field] = $team_id; } } // Handle any carried-forward results if ($game['home_dependency_type'] == 'copy') { if ($reset) { $save = array('home_score' => null, 'away_score' => null, 'approved_by' => null, 'status' => 'normal'); } else { $copy = Set::extract("/Game[home_team={$game['home_team']}][away_team={$game['away_team']}][pool_id={$game['HomePoolTeam']['dependency_pool_id']}]", $division); if (empty($copy)) { $copy = Set::extract("/Game[home_team={$game['away_team']}][away_team={$game['home_team']}][pool_id={$game['HomePoolTeam']['dependency_pool_id']}]", $division); $home = 'away'; $away = 'home'; } else { $home = 'home'; $away = 'away'; } if (empty($copy)) { $this->Session->setFlash(sprintf(__('Failed to %s game dependency', true), __('locate', true)), 'default', array('class' => 'warning')); $this->redirect(array('action' => 'schedule', 'division' => $id)); } $copy = $copy[0]['Game']; $save = array('home_score' => $copy["{$home}_score"], 'away_score' => $copy["{$away}_score"], 'approved_by' => $copy['approved_by'], 'status' => $copy['status'], 'updated' => $copy['updated']); } if (!$this->Division->Game->save($save)) { $this->Session->setFlash(sprintf(__('Failed to %s game dependency', true), __($operation, true)), 'default', array('class' => 'warning')); $this->redirect(array('action' => 'schedule', 'division' => $id)); } } } $this->Session->setFlash(sprintf(__('Dependencies have been %s.', true), __($reset ? 'reset' : 'resolved', true)), 'default', array('class' => 'success')); $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->redirect(array('action' => 'schedule', 'division' => $id)); }
function _is_tie($game, $team_id) { if (Game::_is_finalized($game)) { if ($game['Game']['home_score'] == $game['Game']['away_score']) { return 1; } else { return 0; } } else { if (!empty($game['ScoreEntry'])) { $entry = reset($game['ScoreEntry']); if ($entry['status'] != 'in_progress' && $entry['score_for'] == $entry['score_against']) { return 1; } else { return 0; } } else { // Return a 0 and trust that it will be corrected later return 0; } } }
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 displayScore($game, $division, $league, $show_score_for_team = false) { // Data may come in one of two forms. if (array_key_exists('Game', $game)) { // Either all the models are at the same level in the array... $details = $game['Game']; } else { // ...or the Game model is at the top and others are below $details = $game; } $view =& ClassRegistry::getObject('view'); $is_logged_in = $view->viewVars['is_logged_in']; $is_admin = $view->viewVars['is_admin']; $is_manager = $view->viewVars['is_manager'] && in_array($league['affiliate_id'], $this->UserCache->read('ManagedAffiliateIDs')); $is_volunteer = $view->viewVars['is_volunteer']; $is_official = $view->viewVars['is_official']; $is_coordinator = in_array($details['division_id'], $this->UserCache->read('DivisionIDs')); // Calculate the game start and end time stamps $start_time = strtotime("{$game['GameSlot']['game_date']} {$game['GameSlot']['game_start']}") + Configure::read('timezone.adjust') * 60; $end_time = strtotime("{$game['GameSlot']['game_date']} {$game['GameSlot']['display_game_end']}") + Configure::read('timezone.adjust') * 60; // Check if one of the teams involved in the game is a team the current user is a captain of $teams = array_intersect(array($details['home_team'], $details['away_team']), $this->UserCache->read('OwnedTeamIDs')); $team_id = array_pop($teams); $links = array(); if (Game::_is_finalized($details)) { if (in_array($details['status'], Configure::read('unplayed_status'))) { __($details['status']); } else { if ($division['schedule_type'] == 'competition') { echo $details['home_score']; } else { // If scores are being shown from a particular team's perspective, // we may need to swap the home and away scores. if ($show_score_for_team == $details['away_team']) { $first_score = $details['away_score']; $second_score = $details['home_score']; } else { $first_score = $details['home_score']; $second_score = $details['away_score']; } echo "{$first_score} - {$second_score}"; } if (strpos($details['status'], 'default') !== false) { echo ' (' . __('default', true) . ')'; } if (League::hasStats($league)) { if ($team_id || $is_admin || $is_coordinator) { $links[] = $this->Html->link(__('Submit Stats', true), array('controller' => 'games', 'action' => 'submit_stats', 'game' => $details['id'], 'team' => $team_id)); } if (($this->params['controller'] != 'games' || $this->params['action'] != 'stats') && ($is_logged_in || Configure::read('feature.public'))) { $links[] = $this->ZuluruHtml->iconLink('stats_24.png', array('controller' => 'games', 'action' => 'stats', 'game' => $details['id'], 'team' => $show_score_for_team), array('alt' => __('Game Stats', true), 'title' => __('Game Stats', true))); } } } } else { $score_entry = Game::_get_best_score_entry($game); if (!empty($score_entry)) { if (in_array($score_entry['status'], Configure::read('unplayed_status'))) { __($score_entry['status']); } else { if ($division['schedule_type'] == 'competition') { echo $score_entry['score_for']; } else { // If scores are being shown from a particular team's perspective, // we may need to swap the home and away scores. if ($show_score_for_team == $score_entry['team_id'] || $show_score_for_team === false && $score_entry['team_id'] == $details['home_team']) { $first_score = $score_entry['score_for']; $second_score = $score_entry['score_against']; } else { $first_score = $score_entry['score_against']; $second_score = $score_entry['score_for']; } echo "{$first_score} - {$second_score}"; } } if ($team_id) { if ($score_entry['status'] == 'in_progress') { $links[] = $this->Html->link(__('Live Score', true), array('controller' => 'games', 'action' => 'live_score', 'game' => $details['id'], 'team' => $team_id)); } else { if ($score_entry['team_id'] == $team_id) { $links[] = $this->Html->link(__('Edit score', true), array('controller' => 'games', 'action' => 'submit_score', 'game' => $details['id'], 'team' => $team_id)); } else { $links[] = $this->Html->link(__('Submit', true), array('controller' => 'games', 'action' => 'submit_score', 'game' => $details['id'], 'team' => $team_id)); } } // Check if someone is a captain on both teams that played each other $second_team_id = array_pop($teams); if ($second_team_id) { $links[] = $this->Html->link(__('Submit', true), array('controller' => 'games', 'action' => 'submit_score', 'game' => $details['id'], 'team' => $second_team_id)); } } else { if ($is_volunteer || $is_official) { // Allow specified individuals (referees, umpires, volunteers) to live score without a team id if ($score_entry['status'] == 'in_progress') { $links[] = $this->Html->link(__('Live Score', true), array('controller' => 'games', 'action' => 'live_score', 'game' => $details['id'])); } else { $links[] = $this->Html->link(__('Edit score', true), array('controller' => 'games', 'action' => 'edit', 'game' => $details['id'])); } } } if ($score_entry['status'] == 'in_progress') { echo ' (' . __('in progress', true) . ')'; } else { echo ' (' . __('unofficial', true) . ')'; } } else { if ($score_entry === null) { __('score mismatch'); if ($team_id) { if ($score_entry['status'] == 'in_progress') { $links[] = $this->Html->link(__('Live Score', true), array('controller' => 'games', 'action' => 'live_score', 'game' => $details['id'], 'team' => $team_id)); } else { $links[] = $this->Html->link(__('Edit score', true), array('controller' => 'games', 'action' => 'submit_score', 'game' => $details['id'], 'team' => $team_id)); } } } else { if (time() > ($start_time + 3 * $end_time) / 4) { if ($division['schedule_type'] != 'competition') { // Allow score submissions any time after 3/4 through the game. // Some people like to submit via mobile phone immediately, and games can end early. if ($team_id) { $links[] = $this->Html->link(__('Submit', true), array('controller' => 'games', 'action' => 'submit_score', 'game' => $details['id'], 'team' => $team_id)); } else { __('not entered'); } } else { if ($is_admin || $is_manager || $is_coordinator) { $links[] = $this->Html->link(__('Submit', true), array('controller' => 'game_slots', 'action' => 'submit_score', 'slot' => $details['game_slot_id'])); } } } else { if (time() > $start_time - 30 * 60) { if ($details['home_team'] != null && $details['away_team'] != null) { // Allow live scoring to start up to half an hour before scheduled game start time. // This allows score keepers to get the page loaded and ready to go in advance. if ($team_id) { $links[] = $this->Html->link(__('Live Score', true), array('controller' => 'games', 'action' => 'live_score', 'game' => $details['id'], 'team' => $team_id)); } else { if ($is_volunteer || $is_official) { // Allow specified individuals (referees, umpires, volunteers) to live score without a team id $links[] = $this->Html->link(__('Live Score', true), array('controller' => 'games', 'action' => 'live_score', 'game' => $details['id'])); } } } } else { // Check if one of the teams involved in the game is a team the current user is on $player_team_id = array_pop(array_intersect(array($details['home_team'], $details['away_team']), $this->UserCache->read('TeamIDs'))); if (!$player_team_id) { $player_team_id = array_pop(array_intersect(array($details['home_team'], $details['away_team']), $this->UserCache->read('RelativeTeamIDs'))); } if ($player_team_id) { $links[] = $this->Html->link(__('iCal', true), array('controller' => 'games', 'action' => 'ical', $details['id'], $player_team_id, 'game.ics')); } } } } } } // Give admins, managers and coordinators the option to edit games if ($is_admin || $is_manager || $is_coordinator) { $links[] = $this->ZuluruHtml->iconLink('edit_24.png', array('controller' => 'games', 'action' => 'edit', 'game' => $details['id'], 'return' => true), array('alt' => __('Edit', true), 'title' => __('Edit', true))); } echo $this->Html->tag('span', implode('', $links), array('class' => 'actions')); }
function roundRobinResults($division, $league, $games, $spirit_obj) { $results = array(); foreach ($games as $game) { // Season games use the round indicator for which of possible multiple passes // through the entire round robin we are in. Tournament games use it for which // game in the single round robin we are in, which is needed when scheduling // but not when analysing results. if ($game['type'] == SEASON_GAME) { $round = $game['round']; } else { $round = 1; } if (!in_array($game['status'], Configure::read('unplayed_status'))) { if (Game::_is_finalized($game)) { $this->addGameResult($division, $league, $results, $game['home_team'], $game['away_team'], $round, $game['home_score'], $game['away_score'], $game['home_carbon_flip'], Game::_get_spirit_entry($game, $game['home_team'], $spirit_obj), $spirit_obj, $game['status'] == 'home_default', $game['status'] == 'normal'); $this->addGameResult($division, $league, $results, $game['away_team'], $game['home_team'], $round, $game['away_score'], $game['home_score'], 2 - $game['home_carbon_flip'], Game::_get_spirit_entry($game, $game['away_team'], $spirit_obj), $spirit_obj, $game['status'] == 'away_default', $game['status'] == 'normal'); } else { $this->addUnplayedGame($division, $results, $game['home_team'], $game['away_team'], $round); $this->addUnplayedGame($division, $results, $game['away_team'], $game['home_team'], $round); } } } return $results; }