/** * Creates the controls when the editor is in its fixture view * */ private function CreateFixtureControls(Match $match, XhtmlElement $match_box) { $css_class = 'TournamentEdit'; if ($this->GetCssClass()) { $css_class .= ' ' . $this->GetCssClass(); } $match_outer_1 = new XhtmlElement('div'); $match_outer_1->SetCssClass($css_class); $this->SetCssClass(''); $match_outer_1->SetXhtmlId($this->GetNamingPrefix()); $match_outer_2 = new XhtmlElement('div'); $this->AddControl($match_outer_1); $match_outer_1->AddControl($match_outer_2); $match_outer_2->AddControl($match_box); if ($match->GetId()) { $heading = "Edit tournament"; } else { $heading = "Add your tournament"; } if ($this->show_step_number) { $heading .= ' – step 1 of 3'; } $o_title_inner_1 = new XhtmlElement('span', $heading); $o_title_inner_2 = new XhtmlElement('span', $o_title_inner_1); $o_title_inner_3 = new XhtmlElement('span', $o_title_inner_2); $match_box->AddControl(new XhtmlElement('h2', $o_title_inner_3, "large")); # Tournament title $suggested_title = $match->GetTitle(); if (isset($this->context_season)) { $suggested_title = $this->GetContextSeason()->GetCompetition()->GetName(); if (strpos(strtolower($suggested_title), 'tournament') === false) { $suggested_title .= ' tournament'; } } else { if (isset($this->context_team)) { $suggested_title = $this->GetContextTeam()->GetName(); if (strpos(strtolower($suggested_title), 'tournament') === false) { $suggested_title .= ' tournament'; } } } if ($suggested_title == "To be confirmed tournament") { $suggested_title = ""; } if ($suggested_title == "To be confirmed v To be confirmed") { $suggested_title = ""; } $title = new TextBox($this->GetNamingPrefix() . 'Title', $suggested_title, $this->IsValidSubmit()); $title->SetMaxLength(200); $match_box->AddControl(new FormPart('Tournament name', $title)); # Open or invite? require_once 'xhtml/forms/radio-button.class.php'; $qualify_set = new XhtmlElement('fieldset'); $qualify_set->SetCssClass('formPart radioButtonList'); $qualify_set->AddControl(new XhtmlElement('legend', 'Who can play?', 'formLabel')); $qualify_radios = new XhtmlElement('div', null, 'formControl'); $qualify_set->AddControl($qualify_radios); $qualify_radios->AddControl(new RadioButton($this->GetNamingPrefix() . 'Open', $this->GetNamingPrefix() . 'Qualify', 'any team may enter', MatchQualification::OPEN_TOURNAMENT, $match->GetQualificationType() === MatchQualification::OPEN_TOURNAMENT or !$match->GetId(), $this->IsValidSubmit())); $qualify_radios->AddControl(new RadioButton($this->GetNamingPrefix() . 'Qualify', $this->GetNamingPrefix() . 'Qualify', 'only invited or qualifying teams can enter', MatchQualification::CLOSED_TOURNAMENT, $match->GetQualificationType() === MatchQualification::CLOSED_TOURNAMENT, $this->IsValidSubmit())); $match_box->AddControl($qualify_set); # Player type $suggested_type = 2; if (isset($this->context_season)) { $suggested_type = $this->context_season->GetCompetition()->GetPlayerType(); } elseif (isset($this->context_team)) { $suggested_type = $this->context_team->GetPlayerType(); } if (!is_null($match->GetPlayerType())) { $suggested_type = $match->GetPlayerType(); } # Saved value overrides suggestion $player_set = new XhtmlElement('fieldset'); $player_set->SetCssClass('formPart radioButtonList'); $player_set->AddControl(new XhtmlElement('legend', 'Type of teams', 'formLabel')); $player_radios = new XhtmlElement('div', null, 'formControl'); $player_set->AddControl($player_radios); $player_radios_1 = new XhtmlElement('div', null, 'column'); $player_radios_2 = new XhtmlElement('div', null, 'column'); $player_radios->AddControl($player_radios_1); $player_radios->AddControl($player_radios_2); $player_radios_1->AddControl(new RadioButton($this->GetNamingPrefix() . 'Ladies', $this->GetNamingPrefix() . 'PlayerType', 'Ladies', 2, $suggested_type === 2, $this->IsValidSubmit())); $player_radios_1->AddControl(new RadioButton($this->GetNamingPrefix() . 'Mixed', $this->GetNamingPrefix() . 'PlayerType', 'Mixed', 1, $suggested_type === 1, $this->IsValidSubmit())); $player_radios_2->AddControl(new RadioButton($this->GetNamingPrefix() . 'Girls', $this->GetNamingPrefix() . 'PlayerType', 'Junior girls', 5, $suggested_type === 5, $this->IsValidSubmit())); $player_radios_2->AddControl(new RadioButton($this->GetNamingPrefix() . 'Children', $this->GetNamingPrefix() . 'PlayerType', 'Junior mixed', 4, $suggested_type === 6, $this->IsValidSubmit())); $match_box->AddControl($player_set); # How many? $per_side_box = new XhtmlSelect($this->GetNamingPrefix() . "Players", null, $this->IsValid()); $per_side_box->SetBlankFirst(true); for ($i = 6; $i <= 16; $i++) { $per_side_box->AddControl(new XhtmlOption($i)); } if ($match->GetIsMaximumPlayersPerTeamKnown()) { $per_side_box->SelectOption($match->GetMaximumPlayersPerTeam()); } else { if (!$match->GetId()) { # Use eight as sensible default for new tournaments $per_side_box->SelectOption(8); } } $players_per_team = new XhtmlElement("label", $per_side_box); $players_per_team->AddAttribute("for", $this->GetNamingPrefix() . "Players"); $players_per_team->AddControl(" players per team"); $players_part = new FormPart("How many players?", $players_per_team); $players_part->AddCssClass("playersPerTeam"); $match_box->AddControl($players_part); # Overs $overs_box = new XhtmlSelect($this->GetNamingPrefix() . "Overs", null, $this->IsValid()); $overs_box->SetBlankFirst(true); for ($i = 2; $i <= 8; $i++) { $overs_box->AddControl(new XhtmlOption($i)); } if ($match->GetIsOversKnown()) { $overs_box->SelectOption($match->GetOvers()); } $overs_label = new XhtmlElement("label", "Overs per innings"); $overs_label->AddAttribute("for", $overs_box->GetXhtmlId()); $overs_part = new FormPart($overs_label, new XhtmlElement("div", $overs_box)); $overs_part->AddCssClass("overs"); $match_box->AddControl($overs_part); # Start date and time if (!$match->GetStartTime()) { # if no date set, use specified default if ($this->i_default_time) { $match->SetStartTime($this->i_default_time); } else { # if no date set and no default, default to today at 10.30am BST # NOTE that if this is a new tournament in an old season, this date won't be selected because the available # dates will be limited below and won't include today. It'll be the same day in the relevant year though. $i_now = gmdate('U'); $match->SetStartTime(gmmktime(9, 30, 00, (int) gmdate('n', $i_now), (int) gmdate('d', $i_now), (int) gmdate('Y', $i_now))); $match->SetIsStartTimeKnown(true); } } $o_date = new DateControl($this->GetNamingPrefix() . 'Start', $match->GetStartTime(), $match->GetIsStartTimeKnown(), $this->IsValidSubmit()); $o_date->SetShowTime(true); $o_date->SetRequireTime(false); $o_date->SetMinuteInterval(5); # if only one season to choose from, limit available dates to the length of that season if ($this->context_season instanceof Season) { if ($this->context_season->GetStartYear() == $this->context_season->GetEndYear()) { $i_mid_season = gmmktime(0, 0, 0, 6, 30, $this->context_season->GetStartYear()); } else { $i_mid_season = gmmktime(0, 0, 0, 12, 31, $this->context_season->GetStartYear()); } $season_dates = Season::SeasonDates($i_mid_season); $season_start_month = gmdate('n', $season_dates[0]); $season_end_month = gmdate('n', $season_dates[1]); if ($season_start_month) { $o_date->SetMonthStart($season_start_month); } if ($season_end_month) { $o_date->SetMonthEnd($season_end_month); } $season_start_year = $this->context_season->GetStartYear(); $season_end_year = $this->context_season->GetEndYear(); if ($season_start_year) { $o_date->SetYearStart($season_start_year); } if ($season_end_year) { $o_date->SetYearEnd($season_end_year); } } $o_date_part = new FormPart('When?', $o_date); $o_date_part->SetIsFieldset(true); $match_box->AddControl($o_date_part); # Where? $o_ground_list = new XhtmlSelect($this->GetNamingPrefix() . 'Ground'); $o_ground_list->AddControl(new XhtmlOption("Don't know", -1)); $o_ground_list->AddControl(new XhtmlOption('Not listed (type the address in the notes field)', -2)); # Promote the most likely grounds to the top of the list $likely_ground_ids = array(); if ($match->GetGroundId()) { $likely_ground_ids[] = $match->GetGroundId(); } foreach ($this->probable_teams as $o_team) { $likely_ground_ids[] = $o_team->GetGround()->GetId(); } if (isset($this->context_season)) { foreach ($this->context_season->GetTeams() as $o_team) { $likely_ground_ids[] = $o_team->GetGround()->GetId(); } } if (isset($this->context_team) and is_object($this->context_team->GetGround())) { $likely_ground_ids[] = $this->context_team->GetGround()->GetId(); } $likely_grounds = array(); $a_other_grounds = array(); /* @var $o_ground Ground */ foreach ($this->grounds->GetItems() as $o_ground) { if (array_search($o_ground->GetId(), $likely_ground_ids) > -1) { $likely_grounds[] = $o_ground; } else { $a_other_grounds[] = $o_ground; } } # Add home grounds foreach ($likely_grounds as $o_ground) { $option = new XhtmlOption($o_ground->GetNameAndTown(), $o_ground->GetId()); $option->SetGroupName('Likely grounds'); $o_ground_list->AddControl($option); } # Add away grounds foreach ($a_other_grounds as $o_ground) { $option = new XhtmlOption($o_ground->GetNameAndTown(), $o_ground->GetId()); $option->SetGroupName('Other grounds'); $o_ground_list->AddControl($option); } # Select ground if ($match->GetGroundId()) { $o_ground_list->SelectOption($match->GetGroundId()); } elseif (isset($this->context_team)) { $o_ground_list->SelectOption($this->context_team->GetGround()->GetId()); } $o_ground_part = new FormPart('Where?', $o_ground_list); $match_box->AddControl($o_ground_part); # Notes $o_notes = new TextBox($this->GetNamingPrefix() . 'Notes', $match->GetNotes()); $o_notes->SetMode(TextBoxMode::MultiLine()); $o_notes_part = new FormPart('Notes<br />(remember to include contact details)', $o_notes); $match_box->AddControl($o_notes_part); # Remember short URL $o_short_url = new TextBox($this->GetNamingPrefix() . 'ShortUrl', $match->GetShortUrl()); $o_short_url->SetMode(TextBoxMode::Hidden()); $match_box->AddControl($o_short_url); # Note the context team to be added to the tournament by default if (isset($this->context_team)) { $context_team_box = new TextBox($this->GetNamingPrefix() . 'ContextTeam', $this->context_team->GetId()); $context_team_box->SetMode(TextBoxMode::Hidden()); $match_box->AddControl($context_team_box); } # Change Save button to "Next" button if ($this->show_step_number) { $this->SetButtonText('Next »'); } }
/** * Adds controls to edit a team score * * @param XhtmlElement $o_container * @param string $s_id_prefix * @param Match $o_match * @param Team $o_team * @param int $i_runs * @param int $i_wickets */ private function CreateTeamScoreControls($o_container, $s_team_role, Match $o_match, Team $o_team = null, $i_runs, $i_wickets) { $o_box = new XhtmlElement('div'); $o_runs = new TextBox($this->GetNamingPrefix() . $s_team_role . 'Runs', $i_runs); $o_runs->SetCssClass("numeric"); if ($i_runs == null) { $o_runs->PopulateData(); } $s_runs_label = (is_null($o_team) ? $s_team_role : $o_team->GetName()) . ' score'; $o_part = new FormPart($s_runs_label, $o_box); $o_box->AddControl($o_runs); $o_part->GetLabel()->AddAttribute('for', $o_runs->GetXhtmlId()); $o_wickets = new XhtmlSelect($this->GetNamingPrefix() . $s_team_role . 'Wickets', ' for '); $o_wickets->SetBlankFirst(true); $max_wickets = $o_match->GetMaximumPlayersPerTeam() - 2; $season_dates = Season::SeasonDates($o_match->GetStartTime()); # working with GMT if (Date::Year($season_dates[0]) != Date::Year($season_dates[1])) { # outdoor needs maximum-2, but indoor needs maximum-1 cos last batter can play on. # if there's any chance it's indoor use maximum-1 $max_wickets = $o_match->GetMaximumPlayersPerTeam() - 1; } for ($i = 0; $i <= $max_wickets; $i++) { $o_wickets->AddControl(new XhtmlOption($i)); } $o_wickets->AddControl(new XhtmlOption('all out', -1)); $o_wickets->SelectOption($i_wickets); $o_box->AddControl($o_wickets); $o_container->AddControl($o_part); }
/** * @return array of IDs of players featured in records added, updated or deleted * @param Match $match * @param bool $is_home_innings * @param int $batting_match_team_id * @param Batting[] $team_batting * @desc Saves the batting scorecard for one innings */ private function SaveBattingScorecard(Match $match, $is_home_innings, $batting_match_team_id, $team_batting) { require_once "stoolball/player-manager.class.php"; $player_manager = new PlayerManager($this->GetSettings(), $this->GetDataConnection()); # Get tables $batting_table = $this->GetSettings()->GetTable("Batting"); $match_table = $this->GetSettings()->GetTable('Match'); # Check whether anything's changed and don't re-save if not $unchanged_batting = array(); $new_batting = array(); $batting_added = false; $batting_deleted = false; $totals_changed = false; $players_affected = array(); # check if batting changed for this innings $position = 0; foreach ($team_batting as $batting) { $position++; /* @var $batting Batting */ $sql = "SELECT batting_id FROM {$batting_table} WHERE\r\n\t\t\t\t\tmatch_team_id = {$batting_match_team_id}\r\n\t\t\t\t\tAND player_id = " . Sql::ProtectNumeric($player_manager->SaveOrMatchPlayer($batting->GetPlayer())) . "\r\n\t\t\t\t\tAND position = {$position}\r\n\t\t\t\t\tAND how_out " . Sql::ProtectNumeric($batting->GetHowOut(), false, true) . "\r\n\t\t\t\t\tAND dismissed_by_id " . Sql::ProtectNumeric($player_manager->SaveOrMatchPlayer($batting->GetDismissedBy()), true, true) . "\r\n\t\t\t\t\tAND bowler_id " . Sql::ProtectNumeric($player_manager->SaveOrMatchPlayer($batting->GetBowler()), true, true) . "\r\n\t\t\t\t\tAND runs " . Sql::ProtectNumeric($batting->GetRuns(), true, true) . "\r\n AND balls_faced " . Sql::ProtectNumeric($batting->GetBallsFaced(), true, true); $result = $this->GetDataConnection()->query($sql); if ($row = $result->fetch()) { $unchanged_batting[] = $row->batting_id; } else { # Save IDs of players added or updated $player_id = $player_manager->SaveOrMatchPlayer($batting->GetPlayer()); $dismissed_by_id = $player_manager->SaveOrMatchPlayer($batting->GetDismissedBy()); $bowler_id = $player_manager->SaveOrMatchPlayer($batting->GetBowler()); $players_affected[] = $player_id; if (!is_null($dismissed_by_id)) { $players_affected[] = $dismissed_by_id; } if (!is_null($bowler_id)) { $players_affected[] = $bowler_id; } # Prepare insert query $player_id = Sql::ProtectNumeric($player_id); $dismissed_by_id = Sql::ProtectNumeric($dismissed_by_id, true); $bowler_id = Sql::ProtectNumeric($bowler_id, true); $new_batting[] = "INSERT INTO {$batting_table} SET\r\n\t\t\t\t\tmatch_team_id = {$batting_match_team_id},\r\n\t\t\t\t\tplayer_id = " . $player_id . ",\r\n\t\t\t\t\tposition = {$position},\r\n\t\t\t\t\thow_out = " . Sql::ProtectNumeric($batting->GetHowOut()) . ",\r\n\t\t\t\t\tdismissed_by_id = {$dismissed_by_id},\r\n\t\t\t\t\tbowler_id = {$bowler_id},\r\n\t\t\t\t\truns = " . Sql::ProtectNumeric($batting->GetRuns(), true) . ",\r\n balls_faced = " . Sql::ProtectNumeric($batting->GetBallsFaced(), true) . ",\r\n\t\t\t\t\tdate_added = " . gmdate('U'); $batting_added = true; } } # See whether any batting records have been changed or removed $sql = "SELECT batting_id, player_id, dismissed_by_id, bowler_id FROM {$batting_table} WHERE match_team_id = {$batting_match_team_id}"; # match_team_id is autonumber from db so can be trusted if (count($unchanged_batting)) { $sql .= " AND batting_id NOT IN(" . implode(',', $unchanged_batting) . ")"; } $result = $this->GetDataConnection()->query($sql); while ($row = $result->fetch()) { # Save IDs of players whose records will be updated or deleted $players_affected[] = $row->player_id; if (!is_null($row->dismissed_by_id)) { $players_affected[] = $row->dismissed_by_id; } if (!is_null($row->bowler_id)) { $players_affected[] = $row->bowler_id; } $batting_deleted = true; } # Final step for the batting is to update, if necessary, the total runs/wickets in the main match record if ($is_home_innings) { $runs_and_wickets = "home_runs = " . Sql::ProtectNumeric($match->Result()->GetHomeRuns(), true, false) . "\r\n\t\t\t\t\tAND home_wickets = " . Sql::ProtectNumeric($match->Result()->GetHomeWickets(), true, false); } else { $runs_and_wickets = "away_runs = " . Sql::ProtectNumeric($match->Result()->GetAwayRuns(), true, false) . "\r\n\t\t\t\t\tAND away_wickets = " . Sql::ProtectNumeric($match->Result()->GetAwayWickets(), true, false); } $sql = "SELECT match_id FROM {$match_table} WHERE {$runs_and_wickets} AND match_id " . Sql::ProtectNumeric($match->GetId(), false, true); $result = $this->GetDataConnection()->query($sql); $totals_changed = $result->fetch() === false; # All changes to master data from here are logged, because this method can be called from the public interface # Delete batting for this innings if changed or removed if ($batting_deleted) { $sql = "DELETE FROM {$batting_table} WHERE match_team_id = {$batting_match_team_id}"; # match_team_id is autonumber from db so can be trusted if (count($unchanged_batting)) { $sql .= " AND batting_id NOT IN(" . implode(',', $unchanged_batting) . ")"; } $this->LoggedQuery($sql); } # Insert batting for this innings if changed or added if ($batting_added) { foreach ($new_batting as $sql) { $this->LoggedQuery($sql); } } # If run or wicket totals changed update that at the same time as recording match audit data $runs_and_wickets = ""; if ($totals_changed) { if ($is_home_innings) { $runs_and_wickets = "home_runs = " . Sql::ProtectNumeric($match->Result()->GetHomeRuns(), true, false) . ",\r\n\t\t\t\t\thome_wickets = " . Sql::ProtectNumeric($match->Result()->GetHomeWickets(), true, false) . ", "; } else { $runs_and_wickets = "away_runs = " . Sql::ProtectNumeric($match->Result()->GetAwayRuns(), true, false) . ",\r\n\t\t\t\t\taway_wickets = " . Sql::ProtectNumeric($match->Result()->GetAwayWickets(), true, false) . ", "; } } # if match data has changed record that for audit, and notify moderator # We can also update the number of players per team so that the same number of boxes are shown next time. if ($batting_added or $batting_deleted or $totals_changed) { $players_per_team = $match->GetMaximumPlayersPerTeam(); $sql = "UPDATE {$match_table} SET {$runs_and_wickets}\r\n players_per_team = {$players_per_team}, \r\n date_changed = " . gmdate('U') . ", \r\n modified_by_id = " . Sql::ProtectNumeric(AuthenticationManager::GetUser()->GetId()) . ' ' . "WHERE match_id " . Sql::ProtectNumeric($match->GetId(), false, true); $this->LoggedQuery($sql); $this->QueueForNotification($match->GetId(), false); } return $players_affected; }
private function CreateWicketsRow(Match $match, $wickets_taken) { $wickets_header = new XhtmlCell(true, "Wickets"); $wickets_header->SetColumnSpan(4); $wickets = new XhtmlSelect("batWickets", null, $this->IsValidSubmit()); $wickets->SetBlankFirst(true); $max_wickets = $match->GetMaximumPlayersPerTeam() - 2; $season_dates = Season::SeasonDates($match->GetStartTime()); # working with GMT if (Date::Year($season_dates[0]) != Date::Year($season_dates[1])) { # outdoor needs maximum-2, but indoor needs maximum-1 cos last batter can play on. # if there's any chance it's indoor use maximum-1 $max_wickets = $match->GetMaximumPlayersPerTeam() - 1; } for ($i = 0; $i <= $max_wickets; $i++) { $wickets->AddControl(new XhtmlOption($i)); } $wickets->AddControl(new XhtmlOption('all out', -1)); if ($this->IsValidSubmit() and !is_null($wickets_taken)) { $wickets->SelectOption($wickets_taken); } $balls_column = new XhtmlCell(false, null); $wickets_row = new XhtmlRow(array($wickets_header, $wickets, $balls_column)); $wickets_row->SetCssClass("totals"); return $wickets_row; }