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 $o_match * @desc Save the result and player(s) of the match to the database */ public function SaveHighlights(Match $o_match) { # To add a result there must always already be a match to update if (!$o_match->GetId()) { return; } require_once "stoolball/player-manager.class.php"; $player_manager = new PlayerManager($this->GetSettings(), $this->GetDataConnection()); # build query $s_match = $this->GetSettings()->GetTable('Match'); $statistics = $this->GetSettings()->GetTable('PlayerMatch'); $i_result = $o_match->Result()->GetResultType() <= 0 ? null : $o_match->Result()->GetResultType(); $player_of_match = $player_manager->SaveOrMatchPlayer($o_match->Result()->GetPlayerOfTheMatch()); $player_of_match_home = $player_manager->SaveOrMatchPlayer($o_match->Result()->GetPlayerOfTheMatchHome()); $player_of_match_away = $player_manager->SaveOrMatchPlayer($o_match->Result()->GetPlayerOfTheMatchAway()); # Check whether anything's changed and don't re-save if not $s_sql = 'SELECT match_id FROM ' . $s_match . ' '; $s_where = $this->SqlAddCondition("", 'match_result_id' . Sql::ProtectNumeric($i_result, true, true)); $s_where = $this->SqlAddCondition($s_where, 'player_of_match_id ' . Sql::ProtectNumeric($player_of_match, true, true)); $s_where = $this->SqlAddCondition($s_where, 'player_of_match_home_id ' . Sql::ProtectNumeric($player_of_match_home, true, true)); $s_where = $this->SqlAddCondition($s_where, 'player_of_match_away_id ' . Sql::ProtectNumeric($player_of_match_away, true, true)); $s_where = $this->SqlAddCondition($s_where, 'match_id = ' . Sql::ProtectNumeric($o_match->GetId())); $s_sql = $this->SqlAddWhereClause($s_sql, $s_where); $o_result = $this->GetDataConnection()->query($s_sql); if ($o_result->fetch()) { return; } # Should the match_title be regenerated? $s_sql = "SELECT custom_title FROM {$s_match} WHERE {$s_match}.match_id = " . Sql::ProtectNumeric($o_match->GetId()); $o_result = $this->GetDataConnection()->query($s_sql); $o_row = $o_result->fetch(); if (!is_null($o_row)) { $o_match->SetUseCustomTitle($o_row->custom_title); } # Save IDs of players affected by any change $affected_players = array(); if (!is_null($player_of_match)) { $affected_players[] = $player_of_match; } if (!is_null($player_of_match_home)) { $affected_players[] = $player_of_match_home; } if (!is_null($player_of_match_away)) { $affected_players[] = $player_of_match_away; } $s_sql = "SELECT player_of_match_id, player_of_match_home_id, player_of_match_away_id FROM {$s_match} WHERE {$s_match}.match_id = " . Sql::ProtectNumeric($o_match->GetId()); $o_result = $this->GetDataConnection()->query($s_sql); $row = $o_result->fetch(); if (!is_null($row)) { if (!is_null($row->player_of_match_id)) { $affected_players[] = $row->player_of_match_id; } if (!is_null($row->player_of_match_home_id)) { $affected_players[] = $row->player_of_match_home_id; } if (!is_null($row->player_of_match_away_id)) { $affected_players[] = $row->player_of_match_away_id; } } # Update the main match record # All changes from here to master data are logged, because this method can be called from the public interface $sql = "UPDATE {$s_match} SET "; if (!$o_match->GetUseCustomTitle()) { $sql .= "match_title = " . Sql::ProtectString($this->GetDataConnection(), $o_match->GetTitle()) . ", "; } $sql .= 'match_result_id = ' . Sql::ProtectNumeric($i_result, true) . ",\r\n\t\t\tplayer_of_match_id = " . Sql::ProtectNumeric($player_of_match, true) . ', ' . "player_of_match_home_id = " . Sql::ProtectNumeric($player_of_match_home, true) . ', ' . "player_of_match_away_id = " . Sql::ProtectNumeric($player_of_match_away, true) . ', update_search = 1, date_changed = ' . gmdate('U') . ", \r\n modified_by_id = " . Sql::ProtectNumeric(AuthenticationManager::GetUser()->GetId()) . ' ' . 'WHERE match_id = ' . Sql::ProtectNumeric($o_match->GetId()); $this->LoggedQuery($sql); # Copy updated match to statistics require_once 'stoolball/statistics/statistics-manager.class.php'; $statistics_manager = new StatisticsManager($this->GetSettings(), $this->GetDataConnection()); $statistics_manager->UpdateMatchDataInStatistics($this, $o_match->GetId()); # Save IDs of players affected by any change if (count($affected_players)) { $statistics_manager->UpdatePlayerOfTheMatchStatistics($o_match->GetId()); $statistics_manager->DeleteObsoleteStatistics($o_match->GetId()); $statistics_manager->UpdatePlayerStatistics($affected_players); } unset($statistics_manager); # Match data has changed so notify moderator $this->QueueForNotification($o_match->GetId(), false); }