function OnLoadPageData() { require_once "data/process-manager.class.php"; $this->process = new ProcessManager(); if ($this->process->ReadyToDeleteAll()) { $stats = $this->GetSettings()->GetTable("PlayerMatch"); $sql = "TRUNCATE TABLE {$stats}"; $this->GetDataConnection()->query($sql); } $matches = $this->GetSettings()->GetTable("MatchTeam"); $mt = $this->GetSettings()->GetTable('MatchTeam'); $sql = "SELECT match_id, match_team_id FROM {$matches} ORDER BY match_team_id " . $this->process->GetQueryLimit(); $result = $this->GetDataConnection()->query($sql); require_once "stoolball/player-manager.class.php"; $player_manager = new PlayerManager($this->GetSettings(), $this->GetDataConnection()); require_once 'stoolball/statistics/statistics-manager.class.php'; $statistics_manager = new StatisticsManager($this->GetSettings(), $this->GetDataConnection()); while ($row = $result->fetch()) { $affected_players = $player_manager->ReadPlayersInMatch(array($row->match_id)); # generate player statistics from the data entered if (count($affected_players)) { $statistics_manager->UpdateBattingStatistics($affected_players, array($row->match_team_id)); # get the match_team_id for the bowling that goes with this batting $sql = "SELECT match_team_id FROM {$mt}\n\t\t\t\t\t\tWHERE match_id = (SELECT match_id FROM {$mt} WHERE match_team_id = {$row->match_team_id})\n\t\t\t\t\t\tAND match_team_id != {$row->match_team_id}\n\t\t\t\t\t\tAND team_role IN (" . TeamRole::Home() . ", " . TeamRole::Away() . ")"; $result2 = $this->GetDataConnection()->query($sql); $row2 = $result2->fetch(); $bowling_match_team_id = $row2->match_team_id; $statistics_manager->UpdateFieldingStatistics($affected_players, array($bowling_match_team_id)); $statistics_manager->UpdateBowlingStatistics($affected_players, array($bowling_match_team_id)); $statistics_manager->UpdatePlayerOfTheMatchStatistics($row->match_id); $statistics_manager->DeleteObsoleteStatistics($row->match_id); } $this->process->OneMoreDone(); } }
/** * Merges the records for two players, retaining the id of the destination player * @param int $source_player_id * @param int $destination_player_id * @return void */ public function MergePlayers(Player $source_player, Player $destination_player) { if (!$source_player->GetId()) { throw new Exception("source_player must have an Id"); } if (!$destination_player->GetId()) { throw new Exception("destination_player must have an Id"); } if ($source_player->GetPlayerRole() != PLAYER::PLAYER) { throw new Exception("Cannot merge source player because it's an extras player"); } if ($destination_player->GetPlayerRole() != PLAYER::PLAYER) { throw new Exception("Cannot merge destination player because it's an extras player"); } $players = $this->GetSettings()->GetTable("Player"); $batting = $this->GetSettings()->GetTable("Batting"); $bowling = $this->GetSettings()->GetTable("Bowling"); $matches = $this->GetSettings()->GetTable("Match"); $statistics = $this->GetSettings()->GetTable("PlayerMatch"); # Make a note of matches where source player was involved $sql = "SELECT DISTINCT match_team_id FROM {$batting} WHERE player_id = " . $source_player->GetId(); $result = $this->GetDataConnection()->query($sql); $source_batted = array(); while ($row = $result->fetch()) { $source_batted[] = $row->match_team_id; } $sql = "SELECT match_team_id FROM {$statistics}\n\t\t\t\tWHERE player_id = " . $source_player->GetId() . " AND (run_outs > 0 OR catches > 0)"; $result = $this->GetDataConnection()->query($sql); $source_fielded = array(); while ($row = $result->fetch()) { $source_fielded[] = $row->match_team_id; } $sql = "SELECT match_team_id FROM {$statistics}\n\t\t\t\tWHERE player_id = " . $source_player->GetId() . " AND wickets IS NOT NULL"; $result = $this->GetDataConnection()->query($sql); $source_bowled = array(); while ($row = $result->fetch()) { $source_bowled[] = $row->match_team_id; } $sql = "SELECT match_id FROM {$statistics}\n\t\t\t\tWHERE player_id = " . $source_player->GetId() . " AND player_of_match = 1"; $result = $this->GetDataConnection()->query($sql); $source_player_of_match = array(); while ($row = $result->fetch()) { $source_player_of_match[] = $row->match_id; } # Transfer batting and bowling $this->LoggedQuery("UPDATE {$batting} SET player_id = " . Sql::ProtectNumeric($destination_player->GetId()) . "\n\t\tWHERE player_id = " . Sql::ProtectNumeric($source_player->GetId())); $this->LoggedQuery("UPDATE {$batting} SET dismissed_by_id = " . Sql::ProtectNumeric($destination_player->GetId()) . "\n\t\tWHERE dismissed_by_id = " . Sql::ProtectNumeric($source_player->GetId())); $this->LoggedQuery("UPDATE {$batting} SET bowler_id = " . Sql::ProtectNumeric($destination_player->GetId()) . "\n\t\tWHERE bowler_id = " . Sql::ProtectNumeric($source_player->GetId())); $this->LoggedQuery("UPDATE {$bowling} SET player_id = " . Sql::ProtectNumeric($destination_player->GetId()) . "\n\t\tWHERE player_id = " . Sql::ProtectNumeric($source_player->GetId())); # Update dismissals in stats table too, because then fielding statistics will update correctly below. # Normally dismissals are updated with the batting, but here it's quite possible we are only updating the fielding. $this->LoggedQuery("UPDATE {$statistics} SET caught_by = " . Sql::ProtectNumeric($destination_player->GetId()) . "\n\t\tWHERE caught_by = " . Sql::ProtectNumeric($source_player->GetId())); $this->LoggedQuery("UPDATE {$statistics} SET run_out_by = " . Sql::ProtectNumeric($destination_player->GetId()) . "\n\t\tWHERE run_out_by = " . Sql::ProtectNumeric($source_player->GetId())); if (!$this->is_internal_delete) { # Doing an internal delete the destination player will be Unknown. Transfer batting and bowling # because that preserves the position for other bowlers and batters as well as related statistics # such as number of runs. But set player of the match to null because there's not much value in # setting it unknown. # Transfer player of the match award $this->LoggedQuery("UPDATE {$matches} SET player_of_match_id = " . Sql::ProtectNumeric($destination_player->GetId()) . ",\n\t\t\tdate_changed = " . gmdate('U') . "\n\t\t\tWHERE player_of_match_id = " . Sql::ProtectNumeric($source_player->GetId())); $this->LoggedQuery("UPDATE {$matches} SET player_of_match_home_id = " . Sql::ProtectNumeric($destination_player->GetId()) . ",\n\t\t\tdate_changed = " . gmdate('U') . "\n\t\t\tWHERE player_of_match_home_id = " . Sql::ProtectNumeric($source_player->GetId())); $this->LoggedQuery("UPDATE {$matches} SET player_of_match_away_id = " . Sql::ProtectNumeric($destination_player->GetId()) . ",\n\t\t\tdate_changed = " . gmdate('U') . "\n\t\t\tWHERE player_of_match_away_id = " . Sql::ProtectNumeric($source_player->GetId())); # If a user has claimed either player, remember that. If two different claimants, prefer the destination one. if ($source_player->GetUser() instanceof User and $source_player->GetUser()->GetId()) { $this->LoggedQuery("UPDATE {$players}\n\t\t\t\tSET user_id = " . Sql::ProtectNumeric($source_player->GetUser()->GetId()) . ",\n\t\t\t\tdate_changed = " . gmdate('U') . "\n\t\t\t\tWHERE player_id = " . Sql::ProtectNumeric($destination_player->GetId()) . " AND user_id = NULL"); } # Now that the source player's data has been moved, delete the source player $this->Delete(array($source_player->GetId())); } # Recalculate all the derived data # Note: this method is tightly integrated with the Delete() method. They call each other. When the source player # is deleted, above, it will call back into this method before all the derived statistics for the source player # have gone. Therefore the queries at the top of this method will find the source player still exists. That in turn # leads to these methods being called for a player which has only derived statistics, and no actual data. It is # important therefore to call DeleteObsoleteStatistics() to clear out the redundant records as soon as they created. require_once 'stoolball/statistics/statistics-manager.class.php'; $statistics_manager = new StatisticsManager($this->GetSettings(), $this->GetDataConnection()); if (count($source_batted)) { $statistics_manager->UpdateBattingStatistics(array($destination_player->GetId()), $source_batted); } if (count($source_fielded)) { $statistics_manager->UpdateFieldingStatistics(array($destination_player->GetId()), $source_fielded); } if (count($source_bowled)) { $statistics_manager->UpdateBowlingStatistics(array($destination_player->GetId()), $source_bowled); } foreach ($source_player_of_match as $match_id) { $statistics_manager->UpdatePlayerOfTheMatchStatistics($match_id); $statistics_manager->DeleteObsoleteStatistics($match_id); } $statistics_manager->UpdatePlayerStatistics(array($destination_player->GetId())); unset($statistics_manager); }
/** * @return void * @param Match $match * @param bool $is_first_innings * @desc Saves the batting and bowling scorecards for one innings */ public function SaveScorecard(Match $match, $is_first_innings, ISearchIndexProvider $search) { # To add a scorecard there must always already be a match to update if (!$match->GetId()) { return; } # This isn't for tournaments if ($match->GetMatchType() == MatchType::TOURNAMENT) { return; } # Get tables $batting_table = $this->GetSettings()->GetTable("Batting"); $bowling_table = $this->GetSettings()->GetTable("Bowling"); $match_table = $this->GetSettings()->GetTable('Match'); $mt = $this->GetSettings()->GetTable('MatchTeam'); # Is this scorecard for the home or the away innings? $sql = "SELECT home_bat_first FROM {$match_table} WHERE match_id = " . Sql::ProtectNumeric($match->GetId()); $result = $this->GetDataConnection()->query($sql); $row = $result->fetch(); if (is_null($row->home_bat_first) or (bool) $row->home_bat_first === true) { $is_home_innings = $is_first_innings; } else { $is_home_innings = !$is_first_innings; } $result->closeCursor(); # Prepare data for query if ($is_home_innings) { $bowling_team_id = $match->GetAwayTeamId(); $batting_team_id = $match->GetHomeTeamId(); $team_bowling = $match->Result()->AwayOvers(); $team_batting = $match->Result()->HomeBatting(); } else { $bowling_team_id = $match->GetHomeTeamId(); $batting_team_id = $match->GetAwayTeamId(); $team_bowling = $match->Result()->HomeOvers(); $team_batting = $match->Result()->AwayBatting(); } # Find the match_team_id for the bowling $sql = "SELECT match_team_id FROM {$mt}\r\n\t\t\t\tWHERE match_id " . Sql::ProtectNumeric($match->GetId(), false, true) . "\r\n\t\t\t\tAND team_id " . Sql::ProtectNumeric($bowling_team_id, false, true) . "\r\n\t\t\t\tAND team_role = " . ($is_home_innings ? TeamRole::Away() : TeamRole::Home()); $result = $this->GetDataConnection()->query($sql); $row = $result->fetch(); $bowling_match_team_id = $row->match_team_id; $result->closeCursor(); # Find the match_team_id for the batting $sql = "SELECT match_team_id FROM {$mt}\r\n\t\t\t\tWHERE match_id " . Sql::ProtectNumeric($match->GetId(), false, true) . "\r\n\t\t\t\tAND team_id " . Sql::ProtectNumeric($batting_team_id, false, true) . "\r\n\t\t\t\tAND team_role = " . ($is_home_innings ? TeamRole::Home() : TeamRole::Away()); $result = $this->GetDataConnection()->query($sql); $row = $result->fetch(); $batting_match_team_id = $row->match_team_id; $result->closeCursor(); $affected_players = $this->SaveBattingScorecard($match, $is_home_innings, $batting_match_team_id, $team_batting); $affected_bowlers = $this->SaveBowlingScorecard($match, $is_home_innings, $batting_match_team_id, $bowling_match_team_id, $team_bowling); $affected_players = array_merge($affected_players, $affected_bowlers); $affected_players = array_unique($affected_players); if (count($affected_players)) { require_once 'stoolball/statistics/statistics-manager.class.php'; $statistics_manager = new StatisticsManager($this->GetSettings(), $this->GetDataConnection()); # generate player statistics from the data entered $statistics_manager->UpdateBattingStatistics($affected_players, array($batting_match_team_id)); $statistics_manager->UpdateFieldingStatistics($affected_players, array($bowling_match_team_id)); $statistics_manager->UpdateBowlingStatistics($affected_players, array($bowling_match_team_id)); $statistics_manager->DeleteObsoleteStatistics($match->GetId()); # update overall stats for players $statistics_manager->UpdatePlayerStatistics($affected_players); unset($statistics_manager); # update search engine require_once "stoolball/player-manager.class.php"; require_once "search/player-search-adapter.class.php"; $player_manager = new PlayerManager($this->GetSettings(), $this->GetDataConnection()); foreach ($affected_players as $player_id) { $player_manager->ReadPlayerById($player_id); $player = $player_manager->GetFirst(); $search->DeleteFromIndexById("player" . $player_id); if ($player instanceof Player) { $adapter = new PlayerSearchAdapter($player); $search->Index($adapter->GetSearchableItem()); } } $search->CommitChanges(); unset($player_manager); } }