function _afterFind($record) { if (array_key_exists('game_end', $record['GameSlot'])) { if ($record['GameSlot']['game_end'] === null) { $record['GameSlot']['display_game_end'] = local_sunset_for_date($record['GameSlot']['game_date']); } else { $record['GameSlot']['display_game_end'] = $record['GameSlot']['game_end']; } } return $record; }
/** * Game end time, for display purposes. * * If one is provided for this game, we use it. Otherwise, we calculate based on sunset time. */ function display_game_end() { # Return our end time, if available if ($this->game_end) { return $this->game_end; } # Otherwise, guess based on date if ($this->timestamp) { return local_sunset_for_date($this->timestamp); } return ''; }
function process() { global $dbh; $this->template_name = 'api/1/schedule/gamestoday.tpl'; $now = time(); $sth = $dbh->prepare('SELECT COUNT(*), COUNT(DISTINCT(game_end)) from gameslot WHERE game_date = ? AND NOT ISNULL(game_id)'); $sth->execute(array(strftime('%Y-%m-%d', $now))); list($game_count, $distinct_end_times) = $sth->fetch(); $this->smarty->assign('game_count', $game_count); $this->smarty->assign('date', strftime('%Y/%m/%d', $now)); /* Also, take a stab at guessing timecap. Since only summer usually * has a "default" timecap, we will only display for that season. */ if ($game_count > 0) { $season = strtolower(variable_get('current_season', "Summer")); if ($season == 'summer') { $this->smarty->assign('timecap', local_sunset_for_date(time())); $this->smarty->assign('multiple_end_times', $distinct_end_times > 1); } } return true; }
function add() { $field = $this->_arg('field'); if (Configure::read('feature.affiliates')) { $affiliate = $this->_arg('affiliate'); if (!$affiliate && !$field) { $this->Session->setFlash(sprintf(__('Invalid %s', true), __('affiliate', true)), 'default', array('class' => 'info')); $this->redirect('/'); } } else { $affiliate = 1; } if ($field) { $this->GameSlot->Field->contain(array('Facility' => 'Region')); $field = $this->GameSlot->Field->read(null, $field); $affiliate = $field['Facility']['Region']['affiliate_id']; $this->set(compact('field')); } else { $regions = $this->GameSlot->Field->Facility->Region->find('all', array('conditions' => array('Region.affiliate_id' => $affiliate), 'contain' => array('Facility' => array('conditions' => array('Facility.is_open' => true), 'order' => 'Facility.name', 'Field' => array('conditions' => array('Field.is_open' => true), 'order' => 'Field.num'))), 'order' => 'Region.id')); $this->set(compact('regions')); } $this->Configuration->loadAffiliate($affiliate); $this->set(compact('affiliate')); if (!empty($this->data)) { Configure::load("sport/{$this->data['GameSlot']['sport']}"); // Find the list of holidays to avoid $holiday = ClassRegistry::init('Holiday'); $holidays = $holiday->find('list', array('fields' => array('Holiday.date', 'Holiday.name'))); $this->set(compact('holidays')); if (array_key_exists('confirm', $this->data['GameSlot'])) { if (!array_key_exists('Create', $this->data['GameSlot'])) { $this->Session->setFlash(__('You must select at least one game slot!', true), 'default', array('class' => 'info')); $this->action = 'confirm'; } else { // Build the list of times to re-use $times = array(); $start = strtotime($this->data['GameSlot']['game_date'] . $this->data['GameSlot']['game_start']); $end = strtotime($this->data['GameSlot']['game_date'] . $this->data['GameSlot']['game_end']); if ($end < $start) { $end += DAY; } if ($this->data['GameSlot']['length'] > 0) { $space = $this->data['GameSlot']['length'] * 60; while ($start + $space <= $end) { $times[] = date('H:i:s', $start); $start += $space; } } else { $times[] = date('H:i:s', $start); } // Build the list of dates to re-use $weeks = array(); // Use noon as the time, to avoid problems when we switch between DST and non-DST dates $date = strtotime($this->data['GameSlot']['game_date'] . ' 12:00:00'); while (count($weeks) < $this->data['GameSlot']['weeks']) { if (!array_key_exists(date('Y-m-d', $date), $holidays)) { $weeks[] = date('Y-m-d', $date); } $date += WEEK; } // saveAll handles hasMany relations OR multiple records, but not both, // so we have to save each slot separately. Wrap the whole thing in a // transaction, for safety. $transaction = new DatabaseTransaction($this->GameSlot); foreach ($this->data['GameSlot']['Create'] as $field_id => $field_dates) { foreach ($field_dates as $date => $field_times) { $week = $weeks[$date]; $sunset = local_sunset_for_date($week); foreach (array_keys($field_times) as $time) { $game_start = $times[$time]; $game_start_time = strtotime("{$week} {$game_start}"); if ($this->data['GameSlot']['length'] > 0) { $game_end_time = $game_start_time + ($this->data['GameSlot']['length'] - $this->data['GameSlot']['buffer']) * 60; $game_end = $actual_game_end = date('H:i:s', $game_end_time); } else { if (empty($this->data['GameSlot']['game_end'])) { $game_end = null; $actual_game_end = $sunset; $game_end_time = strtotime("{$week} {$actual_game_end}"); } else { $game_end = $actual_game_end = $this->data['GameSlot']['game_end']; $game_end_time = strtotime("{$week} {$game_end}"); } } // Validate the end time if ($game_end_time < $game_start_time) { $this->Session->setFlash(sprintf(__('Game end time of %s is before game start time of %s!', true), date('H:i:s', $game_end_time), date('H:i:s', $game_start_time)), 'default', array('class' => 'error')); return; } $conditions = array('field_id' => $field_id, 'game_date' => $week, 'OR' => array(array('game_start >=' => $game_start, 'game_start <' => $actual_game_end), array('game_start <' => $game_start, 'game_end >' => $game_start))); if ($sunset > $this->data['GameSlot']['game_start']) { $conditions['OR'][] = array('game_start <' => $this->data['GameSlot']['game_start'], 'game_end' => null); } $overlap = $this->GameSlot->find('count', array('contain' => array(), 'conditions' => $conditions)); if ($overlap) { if (!isset($field)) { $this->GameSlot->Field->contain('Facility'); $field = $this->GameSlot->Field->read(null, $field_id); } $name = "{$field['Facility']['name']} {$field['Field']['num']}"; $this->Session->setFlash(sprintf(__('Detected a pre-existing conflict with the game slot to be created at %s on %s at %s. Unable to continue. (There may be more conflicts; this is only the first one detected.)', true), $game_start, $week, $name), 'default', array('class' => 'error')); return; } $slot = array('GameSlot' => array('field_id' => $field_id, 'game_date' => $week, 'game_start' => $game_start, 'game_end' => $game_end), 'DivisionGameslotAvailability' => array()); foreach (array_keys($this->data['Division']) as $division_id) { $slot['DivisionGameslotAvailability'][] = array('division_id' => $division_id); } // Try to save if (!$this->GameSlot->saveAll($slot)) { $this->Session->setFlash(sprintf(__('The %s could not be saved. Please correct the errors below and try again.', true), __('game slots', true)), 'default', array('class' => 'warning')); return; } } } } if ($transaction->commit() !== false) { $this->Session->setFlash(sprintf(__('The %s have been saved', true), __('game slots', true)), 'default', array('class' => 'success')); // We intentionally don't redirect here, leaving the user back on the // original "add" form, with the last game date/start/end/weeks options // already selected. Fields and divisions are NOT selected, because those // are no longer in $this->data, but that's more of a feature than a bug. } else { $this->Session->setFlash(sprintf(__('The %s could not be saved. Please correct the errors below and try again.', true), __('game slots', true)), 'default', array('class' => 'warning')); } } // Validate the input } else { if (!array_key_exists('Field', $this->data)) { $this->Session->setFlash(sprintf(__('You must select at least one %s!', true), Configure::read('ui.field')), 'default', array('class' => 'info')); } else { if (!array_key_exists('Division', $this->data)) { $this->Session->setFlash(__('You must select at least one division!', true), 'default', array('class' => 'info')); } else { // By calling 'set', we deconstruct the dates from arrays to more useful strings $this->GameSlot->set($this->data); $this->data = $this->GameSlot->data; if (empty($this->data['GameSlot']['game_end'])) { if ($this->data['GameSlot']['length'] > 0) { $this->GameSlot->validationErrors['length'] = 'You cannot specify game lengths in conjunction with sunset end times!'; $this->Session->setFlash(sprintf(__('The %s could not be saved. Please correct the errors below and try again.', true), __('game slots', true)), 'default', array('class' => 'warning')); } else { // Make sure we're not mixing indoor fields with sunset times foreach (array_keys($this->data['Field']) as $field_id) { $indoor = Set::extract("/Facility/Field[id={$field_id}][indoor=1]/.", $regions); if (!empty($indoor)) { break; } } if (!empty($indoor)) { $this->GameSlot->validationErrors['game_end'] = sprintf(__('You cannot select indoor %s in conjunction with sunset end times!', true), Configure::read('sport.fields')); $this->Session->setFlash(sprintf(__('The %s could not be saved. Please correct the errors below and try again.', true), __('game slots', true)), 'default', array('class' => 'warning')); } else { $this->action = 'confirm'; } } } else { $this->action = 'confirm'; } } } } } }