/**
  * Re-build from data posted by this control a single data object which this control is editing
  *
  * @param int $i_counter
  * @param int $i_id
  */
 protected function BuildPostedItem($i_counter = null, $i_id = null)
 {
     $match = new Match($this->GetSettings());
     $match->SetMatchType(MatchType::TOURNAMENT_MATCH);
     $key = $this->GetNamingPrefix() . 'MatchId' . $i_counter;
     if (isset($_POST[$key]) and is_numeric($_POST[$key])) {
         $match->SetId($_POST[$key]);
     }
     $key = $this->GetNamingPrefix() . 'MatchOrder' . $i_counter;
     if (isset($_POST[$key]) and is_numeric($_POST[$key])) {
         $match->SetOrderInTournament($_POST[$key]);
     }
     $key = $this->GetNamingPrefix() . 'MatchIdValue' . $i_counter;
     if (isset($_POST[$key])) {
         $match->SetTitle($_POST[$key]);
     }
     $key = $this->GetNamingPrefix() . 'HomeTeamId' . $i_counter;
     if (isset($_POST[$key]) and $_POST[$key]) {
         $team = new Team($this->GetSettings());
         $team->SetId($_POST[$key]);
         $match->SetHomeTeam($team);
     }
     $key = $this->GetNamingPrefix() . 'AwayTeamId' . $i_counter;
     if (isset($_POST[$key]) and $_POST[$key]) {
         $team = new Team($this->GetSettings());
         $team->SetId($_POST[$key]);
         $match->SetAwayTeam($team);
     }
     if ($match->GetId() or $match->GetHomeTeamId() and $match->GetAwayTeamId()) {
         $this->DataObjects()->Add($match);
     } else {
         $this->IgnorePostedItem($i_counter);
     }
 }
 protected function CreateControls()
 {
     $match = $this->GetDataObject();
     if (is_null($match)) {
         $match = new Match($this->GetSettings());
         $match->SetMatchType(MatchType::TOURNAMENT);
     }
     /* @var $match Match */
     $match_box = new XhtmlElement('div');
     $this->CreateSeasonControls($match, $match_box);
 }
    /**
     * @return void
     * @param Match $o_match
     * @desc Save the fixture details of the supplied Match to the database, and return the id
     */
    public function SaveFixture(Match $o_match)
    {
        /* @var $o_away_team Team */
        $s_match = $this->GetSettings()->GetTable('Match');
        $s_season_match = $this->GetSettings()->GetTable('SeasonMatch');
        $statistics = $this->GetSettings()->GetTable('PlayerMatch');
        # check permissions - only save limited fields if not admin
        $b_user_is_match_admin = AuthenticationManager::GetUser()->Permissions()->HasPermission(PermissionType::MANAGE_MATCHES);
        $b_is_new_match = !$o_match->GetId();
        # Ensure we know the match type because we'll make decisions based on it
        if (!$b_is_new_match and !$b_user_is_match_admin) {
            # Match type can't be changed on this request so MatchType property usually not populated.
            # Read from db, otherwise these variables can be wrong and the code can follow the wrong path.
            $s_sql = "SELECT match_type FROM {$s_match} WHERE match_id = " . Sql::ProtectNumeric($o_match->GetId());
            $result = $this->GetDataConnection()->query($s_sql);
            if ($row = $result->fetch()) {
                $o_match->SetMatchType($row->match_type);
            }
            $result->closeCursor();
        }
        $is_friendly = $o_match->GetMatchType() == MatchType::FRIENDLY;
        $is_tournament = $o_match->GetMatchType() == MatchType::TOURNAMENT;
        $is_tournament_match = ($o_match->GetMatchType() == MatchType::TOURNAMENT_MATCH and $o_match->GetTournament() instanceof Match);
        # Ensure all involved teams have their name, because that's essential to building a match title,
        # and short URL because that's used to build a non-tournament match URL
        $teams_without_data = array();
        if ($o_match->GetHomeTeamId() and (!$o_match->GetHomeTeam()->GetName() or !$o_match->GetHomeTeam()->GetShortUrl())) {
            $teams_without_data[] = $o_match->GetHomeTeamId();
        }
        foreach ($o_match->GetAwayTeams() as $team) {
            /* @var $team Team */
            if ($team->GetId() and (!$team->GetName() or !$team->GetShortUrl())) {
                $teams_without_data[] = $team->GetId();
            }
        }
        if (count($teams_without_data)) {
            $result = $this->GetDataConnection()->query("SELECT team_id, team_name, short_url FROM nsa_team WHERE team_id IN (" . implode(",", $teams_without_data) . ")");
            while ($row = $result->fetch()) {
                if ($row->team_id == $o_match->GetHomeTeamId()) {
                    $o_match->GetHomeTeam()->SetName($row->team_name);
                    $o_match->GetHomeTeam()->SetShortUrl($row->short_url);
                }
                foreach ($o_match->GetAwayTeams() as $team) {
                    /* @var $team Team */
                    if ($row->team_id == $team->GetId()) {
                        $team->SetName($row->team_name);
                        $team->SetShortUrl($row->short_url);
                    }
                }
            }
            $result->closeCursor();
        }
        # Make sure it's not a duplicate. If it is, just return the existing match's id.
        $duplicate_match = $this->GetDuplicateFixture($o_match, $b_user_is_match_admin);
        if ($duplicate_match instanceof Match) {
            return $duplicate_match->GetId();
        }
        # build query
        # NOTE: dates are user-selected, therefore they don't need adjusting
        $o_tournament = $o_match->GetTournament();
        $i_tournament = is_null($o_tournament) ? null : $o_tournament->GetId();
        $i_ground = $o_match->GetGroundId() > 0 ? $o_match->GetGroundId() : null;
        # if no id, it's a new match; otherwise update the match
        # All changes to master data from here are logged, because this method can be called from the public interface
        if (!$b_is_new_match) {
            # Update the main match record
            $s_sql = 'UPDATE nsa_match SET ';
            $updated_type = "";
            $updated_title = "";
            if ($b_user_is_match_admin) {
                $updated_type = 'match_type = ' . Sql::ProtectNumeric($o_match->GetMatchType()) . ', ';
                $updated_title = "match_title = " . Sql::ProtectString($this->GetDataConnection(), $o_match->GetTitle()) . ", ";
                $s_sql .= $updated_type . $updated_title . 'custom_title' . Sql::ProtectBool($o_match->GetUseCustomTitle(), false, true) . ', ';
            } else {
                # Non-admin user not given chance to amend a custom title, so if there is a custom title
                # it must be left unchanged. But if title was generated, it can be regenerated based on
                # the user's changes.
                $o_result = $this->GetDataConnection()->query("SELECT custom_title FROM {$s_match} WHERE {$s_match}.match_id = " . Sql::ProtectNumeric($o_match->GetId()));
                $o_row = $o_result->fetch();
                if (!is_null($o_row)) {
                    $o_match->SetUseCustomTitle($o_row->custom_title);
                }
                if (!$o_match->GetUseCustomTitle()) {
                    $updated_title = "match_title = " . Sql::ProtectString($this->GetDataConnection(), $o_match->GetTitle()) . ", ";
                    $s_sql .= $updated_title;
                }
            }
            $player_type = Sql::ProtectNumeric($this->WorkOutPlayerType($o_match), true, false);
            $ground_id = Sql::ProtectNumeric($i_ground, true);
            $start_time = Sql::ProtectNumeric($o_match->GetStartTime());
            $s_sql .= 'player_type_id = ' . $player_type . ', 
			qualification = ' . Sql::ProtectNumeric($o_match->GetQualificationType(), false, false) . ', 
			tournament_match_id = ' . Sql::ProtectNumeric($i_tournament, true) . ', 
    		ground_id = ' . $ground_id . ', ' . 'start_time = ' . $start_time . ', ' . 'start_time_known = ' . Sql::ProtectBool($o_match->GetIsStartTimeKnown()) . ', ' . "match_notes = " . Sql::ProtectString($this->GetDataConnection(), $o_match->GetNotes()) . ", \r\n            update_search = 1,  \r\n\t\t\tdate_changed = " . gmdate('U') . ", \r\n            modified_by_id = " . Sql::ProtectNumeric(AuthenticationManager::GetUser()->GetId()) . ' ' . 'WHERE match_id = ' . Sql::ProtectNumeric($o_match->GetId());
            $this->LoggedQuery($s_sql);
            # Update fields which are cached in the player statistics table
            $sql = "UPDATE {$statistics} SET\r\n\t\t\t{$updated_type}\r\n\t\t\tmatch_player_type = {$player_type},\r\n\t\t\tmatch_time = {$start_time},\r\n\t\t\t{$updated_title}\r\n\t\t\tground_id = {$ground_id}\r\n\t\t\tWHERE match_id = " . Sql::ProtectNumeric($o_match->GetId());
            $this->GetDataConnection()->query($sql);
        } else {
            # If it's not a duplicate, insert the match
            $s_sql = 'INSERT INTO ' . $s_match . ' SET ' . "match_title = " . Sql::ProtectString($this->GetDataConnection(), $o_match->GetTitle()) . ", " . 'custom_title' . Sql::ProtectBool($o_match->GetUseCustomTitle(), false, true) . ', ' . 'match_type = ' . Sql::ProtectNumeric($o_match->GetMatchType()) . ', ' . 'player_type_id = ' . Sql::ProtectNumeric($this->WorkOutPlayerType($o_match), true, false) . ', 
			qualification = ' . Sql::ProtectNumeric($o_match->GetQualificationType(), false, false) . ', 
            tournament_match_id = ' . Sql::ProtectNumeric($i_tournament, true) . ', 
    		ground_id = ' . Sql::ProtectNumeric($i_ground, true) . ', ' . 'start_time = ' . Sql::ProtectNumeric($o_match->GetStartTime()) . ', ' . 'start_time_known = ' . Sql::ProtectBool($o_match->GetIsStartTimeKnown()) . ', ' . "match_notes = " . Sql::ProtectString($this->GetDataConnection(), $o_match->GetNotes()) . ", \r\n\t\t\tupdate_search = 1,  \r\n            added_by " . Sql::ProtectNumeric(AuthenticationManager::GetUser()->GetId(), false, true) . ', ' . 'date_added = ' . gmdate('U') . ', ' . 'date_changed = ' . gmdate('U') . ", \r\n            modified_by_id = " . Sql::ProtectNumeric(AuthenticationManager::GetUser()->GetId());
            $this->LoggedQuery($s_sql);
            # get autonumber
            $o_match->SetId($this->GetDataConnection()->insertID());
        }
        # Save teams, unless this is a tournament, in which case it happens separately
        if (!$is_tournament) {
            $this->SaveTeams($o_match);
        }
        if ($is_tournament) {
            $this->CopyTournamentDetailsToTournamentMatches($o_match);
        } else {
            if ($is_tournament_match) {
                $this->CopyTournamentMatchDetailsFromTournament($o_match->GetTournament(), $o_match);
            }
        }
        # Only save players per side/overs for tournaments and friendlies. For other match types it's based on the
        # seasons and updated during SaveSeasons()
        if ($is_tournament or $is_friendly) {
            $players_per_team = $o_match->GetIsMaximumPlayersPerTeamKnown() ? Sql::ProtectNumeric($o_match->GetMaximumPlayersPerTeam()) : "NULL";
            $overs = $o_match->GetIsOversKnown() ? Sql::ProtectNumeric($o_match->GetOvers()) : "NULL";
            $s_sql = "UPDATE {$s_match} SET players_per_team = {$players_per_team}, overs = {$overs} " . " WHERE match_id = " . Sql::ProtectNumeric($o_match->GetId()) . " OR tournament_match_id = " . Sql::ProtectNumeric($o_match->GetId());
            $this->LoggedQuery($s_sql);
        }
        $this->UpdateMatchUrl($o_match, $b_user_is_match_admin);
        # Match data has changed so notify moderator
        $this->QueueForNotification($o_match->GetId(), $b_is_new_match);
    }
 /**
  * @return bool
  * @param Match $o_match
  * @desc Add a match which forms part of this tournament
  */
 function AddMatchInTournament(Match $o_match)
 {
     if ($this->GetMatchType() == MatchType::TOURNAMENT) {
         $o_match->SetMatchType(MatchType::TOURNAMENT_MATCH);
         $o_match->SetTournament($this);
         $this->a_matches_in_tournament[] =& $o_match;
         return true;
     } else {
         return false;
     }
 }
 /**
  * Builds a match object containing the result information posted by the control
  *
  */
 public function BuildPostedDataObject()
 {
     $o_match = new Match($this->GetSettings());
     # Get match id
     $s_key = $this->GetNamingPrefix() . 'item';
     if (isset($_POST[$s_key])) {
         $s_id = $_POST[$s_key];
         if (strlen($s_id)) {
             $o_match->SetId($s_id);
         }
     }
     # Get the short URL
     $s_key = $this->GetNamingPrefix() . 'ShortUrl';
     if (isset($_POST[$s_key])) {
         $o_match->SetShortUrl($_POST[$s_key]);
     }
     # Get the start date
     $s_key = $this->GetNamingPrefix() . 'Start';
     $o_match->SetStartTime(DateControl::GetPostedTimestampUtc($s_key));
     $o_match->SetIsStartTimeKnown(DateControl::GetIsTimePosted($s_key));
     # Get the home team
     # Test for (int)$_POST[$s_key] deliberately excludes "Not known" value, which is 0
     $o_home = new Team($this->GetSettings());
     $s_key = $this->GetNamingPrefix() . 'Home';
     if (isset($_POST[$s_key]) and strlen($_POST[$s_key]) and (int) $_POST[$s_key]) {
         $o_home->SetId($_POST[$s_key]);
         $o_match->SetHomeTeam($o_home);
     }
     # Get the away team
     # Test for (int)$_POST[$s_key] deliberately excludes "Not known" value, which is 0
     $o_away = new Team($this->GetSettings());
     $s_key = $this->GetNamingPrefix() . 'Away';
     if (isset($_POST[$s_key]) and strlen($_POST[$s_key]) and (int) $_POST[$s_key]) {
         $o_away->SetId($_POST[$s_key]);
         $o_match->SetAwayTeam($o_away);
     }
     # Get the ground
     $s_key = $this->GetNamingPrefix() . 'Ground';
     if (isset($_POST[$s_key]) and strlen($_POST[$s_key])) {
         $o_ground = new Ground($this->GetSettings());
         $o_ground->SetId($_POST[$s_key]);
         $o_match->SetGround($o_ground);
     }
     # Get the notes
     $s_key = $this->GetNamingPrefix() . 'Notes';
     if (isset($_POST[$s_key])) {
         $o_match->SetNotes($_POST[$s_key]);
     }
     # Get the match type
     $s_key = $this->GetNamingPrefix() . 'MatchType';
     if (isset($_POST[$s_key]) and is_numeric($_POST[$s_key])) {
         $o_match->SetMatchType($_POST[$s_key]);
     }
     # Get the tournament
     if ($o_match->GetMatchType() == MatchType::TOURNAMENT_MATCH) {
         $s_key = $this->GetNamingPrefix() . 'Tournament';
         if (isset($_POST[$s_key]) and is_numeric($_POST[$s_key])) {
             $tournament = new Match($this->GetSettings());
             $tournament->SetMatchType(MatchType::TOURNAMENT);
             $tournament->SetId($_POST[$s_key]);
             $o_match->SetTournament($tournament);
         }
     }
     # Get the season
     $s_key = $this->GetNamingPrefix() . 'Season';
     if (isset($_POST[$s_key]) and strlen($_POST[$s_key])) {
         $o_season = new Season($this->GetSettings());
         $o_season->SetId($_POST[$s_key]);
         $o_match->Seasons()->Add($o_season);
     }
     $this->SetDataObject($o_match);
 }