/**
  * Add full scorecard data to the currently selected matches
  */
 public function ExpandMatchScorecards()
 {
     $a_ids = array();
     foreach ($this->GetItems() as $match) {
         $a_ids[] = $match->GetId();
     }
     # Select batting and bowling separately because when selecting it all together they create so many duplicate rows that
     # it would significantly increase the amount of data sent across the wire
     $s_sql = "SELECT mt.match_id, mt.team_role,\r\n\t\tbat.player_id, bat.how_out, bat.dismissed_by_id, bat.bowler_id, bat.runs, bat.balls_faced,\r\n\t\tbatter.player_name AS batter_name, batter.player_role AS batter_role, batter.short_url AS batter_url,\r\n\t\tdismissed_by.player_name AS dismissed_by_name, dismissed_by.player_role AS dismissed_by_role, dismissed_by.short_url AS dismissed_by_url,\r\n\t\tbowler.player_name AS bowler_name, bowler.player_role AS bowler_role, bowler.short_url AS bowler_url\r\n\t\tFROM nsa_match_team mt\r\n\t\tINNER JOIN nsa_batting bat ON mt.match_team_id = bat.match_team_id\r\n\t\tINNER JOIN nsa_player batter ON bat.player_id = batter.player_id\r\n\t\tLEFT JOIN nsa_player dismissed_by ON bat.dismissed_by_id = dismissed_by.player_id\r\n\t\tLEFT JOIN nsa_player bowler ON bat.bowler_id = bowler.player_id\r\n\t\tWHERE mt.team_role IN (" . TeamRole::Home() . "," . TeamRole::Away() . ") ";
     if (count($a_ids)) {
         $s_sql .= "AND mt.match_id IN (" . join(', ', $a_ids) . ') ';
     }
     $s_sql .= "ORDER BY mt.match_id, mt.match_team_id, bat.position";
     $result = $this->GetDataConnection()->query($s_sql);
     while ($row = $result->fetch()) {
         $match = $this->GetItemByProperty('GetId', $row->match_id);
         if (!$match instanceof Match) {
             continue;
         }
         # shouldn't ever happen
         $batter = new Player($this->GetSettings());
         $batter->SetId($row->player_id);
         $batter->SetName($row->batter_name);
         $batter->SetPlayerRole($row->batter_role);
         $batter->SetShortUrl($row->batter_url);
         if (!is_null($row->dismissed_by_id)) {
             $dismissed_by = new Player($this->GetSettings());
             $dismissed_by->SetId($row->dismissed_by_id);
             $dismissed_by->SetName($row->dismissed_by_name);
             $dismissed_by->SetPlayerRole($row->dismissed_by_role);
             $dismissed_by->SetShortUrl($row->dismissed_by_url);
         } else {
             $dismissed_by = null;
         }
         if (!is_null($row->bowler_id)) {
             $bowler = new Player($this->GetSettings());
             $bowler->SetId($row->bowler_id);
             $bowler->SetName($row->bowler_name);
             $bowler->SetPlayerRole($row->bowler_role);
             $bowler->SetShortUrl($row->bowler_url);
         } else {
             $bowler = null;
         }
         $batting = new Batting($batter, $row->how_out, $dismissed_by, $bowler, $row->runs, $row->balls_faced);
         if (intval($row->team_role) == TeamRole::Home()) {
             $match->Result()->HomeBatting()->Add($batting);
         } else {
             if (intval($row->team_role) == TeamRole::Away()) {
                 $match->Result()->AwayBatting()->Add($batting);
             }
         }
     }
     $result->closeCursor();
     # select over-by-over bowling figures
     $s_sql = "SELECT mt.match_id, mt.team_role,\r\n\t\tp.player_name, p.player_role, p.short_url,\r\n\t\tb.player_id, b.position, b.balls_bowled, b.no_balls, b.wides, b.runs_in_over\r\n\t\tFROM nsa_match_team mt\r\n\t\tINNER JOIN nsa_bowling b ON mt.match_team_id = b.match_team_id\r\n\t\tINNER JOIN nsa_player p ON p.player_id = b.player_id\r\n\t\tWHERE mt.team_role IN (" . TeamRole::Home() . "," . TeamRole::Away() . ") ";
     if (count($a_ids)) {
         $s_sql .= "AND mt.match_id IN (" . join(', ', $a_ids) . ') ';
     }
     $s_sql .= "ORDER BY mt.match_id, mt.match_team_id, ISNULL(b.position), b.position";
     # null positions sorted last
     $result = $this->GetDataConnection()->query($s_sql);
     while ($row = $result->fetch()) {
         $match = $this->GetItemByProperty('GetId', $row->match_id);
         if (!$match instanceof Match) {
             continue;
         }
         # shouldn't ever happen
         $bowler = new Player($this->GetSettings());
         $bowler->SetId($row->player_id);
         $bowler->SetName($row->player_name);
         $bowler->SetPlayerRole($row->player_role);
         $bowler->SetShortUrl($row->short_url);
         $bowling = new Over($bowler);
         if (!is_null($row->position)) {
             $bowling->SetOverNumber($row->position);
         }
         if (!is_null($row->balls_bowled)) {
             $bowling->SetBalls($row->balls_bowled);
         }
         if (!is_null($row->no_balls)) {
             $bowling->SetNoBalls($row->no_balls);
         }
         if (!is_null($row->wides)) {
             $bowling->SetWides($row->wides);
         }
         if (!is_null($row->runs_in_over)) {
             $bowling->SetRunsInOver($row->runs_in_over);
         }
         if (intval($row->team_role) == TeamRole::Home()) {
             $match->Result()->HomeOvers()->Add($bowling);
         } else {
             if (intval($row->team_role) == TeamRole::Away()) {
                 $match->Result()->AwayOvers()->Add($bowling);
             }
         }
     }
     $result->closeCursor();
     unset($result);
     # select overall bowling figures for each bowler
     $s_sql = "SELECT mt.match_id, mt.team_role,\r\n\t\tp.player_name, p.player_role, p.short_url,\r\n\t\tb.player_id, b.overs, b.maidens, b.runs_conceded, b.wickets\r\n\t\tFROM nsa_match_team mt\r\n\t\tINNER JOIN nsa_player_match b ON mt.match_team_id = b.match_team_id\r\n\t\tINNER JOIN nsa_player p ON p.player_id = b.player_id\r\n\t\tWHERE mt.team_role IN (" . TeamRole::Home() . "," . TeamRole::Away() . ")\r\n\t\tAND b.wickets IS NOT NULL ";
     if (count($a_ids)) {
         $s_sql .= "AND mt.match_id IN (" . join(', ', $a_ids) . ') ';
     }
     $s_sql .= "ORDER BY mt.match_id, mt.match_team_id, b.first_over";
     $result = $this->GetDataConnection()->query($s_sql);
     while ($row = $result->fetch()) {
         $match = $this->GetItemByProperty('GetId', $row->match_id);
         if (!$match instanceof Match) {
             continue;
         }
         # shouldn't ever happen
         $bowler = new Player($this->GetSettings());
         $bowler->SetId($row->player_id);
         $bowler->SetName($row->player_name);
         $bowler->SetPlayerRole($row->player_role);
         $bowler->SetShortUrl($row->short_url);
         $figures = new Bowling($bowler);
         if (!is_null($row->overs)) {
             $figures->SetOvers($row->overs);
         }
         if (!is_null($row->maidens)) {
             $figures->SetMaidens($row->maidens);
         }
         if (!is_null($row->runs_conceded)) {
             $figures->SetRunsConceded($row->runs_conceded);
         }
         if (!is_null($row->wickets)) {
             $figures->SetWickets($row->wickets);
         }
         if (intval($row->team_role) == TeamRole::Home()) {
             $match->Result()->HomeBowling()->Add($figures);
         } else {
             if (intval($row->team_role) == TeamRole::Away()) {
                 $match->Result()->AwayBowling()->Add($figures);
             }
         }
     }
     $result->closeCursor();
     unset($result);
 }
 public function OnLoadPageData()
 {
     # Always get the player's unfiltered profile, because it's needed for the page description
     require_once "stoolball/player-manager.class.php";
     $player_manager = new PlayerManager($this->GetSettings(), $this->GetDataConnection());
     $player_manager->ReadPlayerById($this->player->GetId());
     $this->player_unfiltered = $player_manager->GetFirst();
     if (!$this->player_unfiltered instanceof Player or $this->player_unfiltered->GetPlayerRole() !== Player::PLAYER) {
         http_response_code(404);
         $this->not_found = true;
         return;
     }
     # Update search engine
     if ($this->player_unfiltered->GetSearchUpdateRequired()) {
         require_once "search/player-search-adapter.class.php";
         $this->SearchIndexer()->DeleteFromIndexById("player" . $this->player->GetId());
         $adapter = new PlayerSearchAdapter($this->player_unfiltered);
         $this->SearchIndexer()->Index($adapter->GetSearchableItem());
         $this->SearchIndexer()->CommitChanges();
         $player_manager->SearchUpdated($this->player->GetId());
     }
     unset($player_manager);
     # Check first for a player created using 'add player', who hasn't played yet
     if ($this->player_unfiltered->GetTotalMatches() == 0) {
         $this->player = $this->player_unfiltered;
     } else {
         # Now get statistics for the player
         $statistics_manager = new StatisticsManager($this->GetSettings(), $this->GetDataConnection());
         $statistics_manager->FilterByPlayer(array($this->player->GetId()));
         # Apply filters common to all statistics
         $this->filter_control = new StatisticsFilterControl();
         $filter_match_type = StatisticsFilter::SupportMatchTypeFilter($statistics_manager);
         $this->filter_control->SupportMatchTypeFilter($filter_match_type);
         $this->filter .= $filter_match_type[2];
         $filter_opposition = StatisticsFilter::SupportOppositionFilter($statistics_manager);
         $this->filter_control->SupportOppositionFilter($filter_opposition);
         $this->filter .= $filter_opposition[2];
         $filter_competition = StatisticsFilter::SupportCompetitionFilter($statistics_manager);
         $this->filter_control->SupportCompetitionFilter($filter_competition);
         $this->filter .= $filter_competition[2];
         $this->filter .= StatisticsFilter::ApplySeasonFilter($this->GetSettings(), $this->GetDataConnection(), $statistics_manager);
         $filter_ground = StatisticsFilter::SupportGroundFilter($statistics_manager);
         $this->filter_control->SupportGroundFilter($filter_ground);
         $this->filter .= $filter_ground[2];
         $filter_date = StatisticsFilter::SupportDateFilter($statistics_manager);
         if (!is_null($filter_date[0])) {
             $this->filter_control->SupportAfterDateFilter($filter_date[0]);
         }
         if (!is_null($filter_date[1])) {
             $this->filter_control->SupportBeforeDateFilter($filter_date[1]);
         }
         $this->filter .= $filter_date[2];
         $filter_innings = StatisticsFilter::SupportInningsFilter($statistics_manager);
         $this->filter_control->SupportInningsFilter($filter_innings[1]);
         $this->filter .= $filter_innings[2];
         $filter_won_match = StatisticsFilter::SupportMatchResultFilter($statistics_manager);
         $this->filter_control->SupportMatchResultFilter($filter_won_match[1]);
         $this->filter .= $filter_won_match[2];
         # Now get the statistics for the player
         $data = $statistics_manager->ReadPlayerSummary();
         if (count($data)) {
             $this->player = $data[0];
         } else {
             if ($this->filter) {
                 # If no matches matched the filter, ensure we have the player's name and team
                 $this->player = $this->player_unfiltered;
                 $this->filter_matched_nothing = true;
             } else {
                 $this->regenerating = true;
             }
         }
         $data = $statistics_manager->ReadBestPlayerAggregate("catches");
         $this->player->SetCatches(count($data) ? $data[0]["statistic"] : 0);
         $data = $statistics_manager->ReadBestPlayerAggregate("run_outs");
         $this->player->SetRunOuts(count($data) ? $data[0]["statistic"] : 0);
         if ($this->player->GetPlayerRole() == Player::PLAYER) {
             $data = $statistics_manager->ReadBestPlayerAggregate("player_of_match");
             $this->player->SetTotalPlayerOfTheMatchNominations(count($data) ? $data[0]["statistic"] : 0);
         }
         $data = $statistics_manager->ReadBestBowlingPerformance();
         foreach ($data as $performance) {
             $bowling = new Bowling($this->player);
             $bowling->SetOvers($performance["overs"]);
             $bowling->SetMaidens($performance["maidens"]);
             $bowling->SetRunsConceded($performance["runs_conceded"]);
             $bowling->SetWickets($performance["wickets"]);
             $this->player->Bowling()->Add($bowling);
         }
         unset($statistics_manager);
     }
 }