/**
  * Creates a new action log for the specified user and deletes old ones.
  * If there is already a recent log for the same action, it will onl update the timestamp.
  * 
  * @param WebSoccer $websoccer Application context.
  * @param DbConnection $db DB connection.
  * @param int $userId ID of user.
  * @param string $actionId Action name.
  */
 public static function createOrUpdateActionLog(WebSoccer $websoccer, DbConnection $db, $userId, $actionId)
 {
     $fromTable = $websoccer->getConfig('db_prefix') . '_useractionlog';
     // delete old entries of user (entries which are older than 20 days)
     $deleteTimeThreshold = $websoccer->getNowAsTimestamp() - 24 * 3600 * 20;
     $db->queryDelete($fromTable, 'user_id = %d AND created_date < %d', array($userId, $deleteTimeThreshold));
     // check if action has been triggered within the last X minutes. If so, just update timestamp rather than filling DB unnecessary.
     $timeThreshold = $websoccer->getNowAsTimestamp() - 30 * 60;
     $result = $db->querySelect('id', $fromTable, 'user_id = %d AND action_id = \'%s\' AND created_date >= %d ORDER BY created_date DESC', array($userId, $actionId, $timeThreshold), 1);
     $lastLog = $result->fetch_array();
     $result->free();
     // update last log
     if ($lastLog) {
         $db->queryUpdate(array('created_date' => $websoccer->getNowAsTimestamp()), $fromTable, 'id = %d', $lastLog['id']);
         // create new log
     } else {
         $db->queryInsert(array('user_id' => $userId, 'action_id' => $actionId, 'created_date' => $websoccer->getNowAsTimestamp()), $fromTable);
     }
 }
 /**
  * Removes open match requests which cannot be approved any more because match would start to later otherwise.
  * 
  * @param WebSoccer $websoccer Application context.
  * @param DbConnection $db DB connection.
  */
 public static function deleteInvalidOpenMatchRequests(WebSoccer $websoccer, DbConnection $db)
 {
     $timeBoundary = $websoccer->getNowAsTimestamp() + $websoccer->getConfig("youth_matchrequest_accept_hours_in_advance");
     $db->queryDelete($websoccer->getConfig("db_prefix") . "_youthmatch_request", "matchdate <= %d", $timeBoundary);
 }
 private static function createMatchForTeamAndRound(WebSoccer $websoccer, DbConnection $db, $teamId, $roundId, $firstRoundDate, $secondRoundDate, $cupName, $cupRound)
 {
     // get opponent team from pending list
     $pendingTable = $websoccer->getConfig('db_prefix') . '_cup_round_pending';
     $result = $db->querySelect('team_id', $pendingTable, 'cup_round_id = %d', $roundId, 1);
     $opponent = $result->fetch_array();
     $result->free();
     // no opponent -> add to pending list
     if (!$opponent) {
         $db->queryInsert(array('team_id' => $teamId, 'cup_round_id' => $roundId), $pendingTable);
     } else {
         $matchTable = $websoccer->getConfig('db_prefix') . '_spiel';
         $type = 'Pokalspiel';
         // determine home team of first round (choose randomly)
         if (SimulationHelper::selectItemFromProbabilities(array(1 => 50, 0 => 50))) {
             $homeTeam = $teamId;
             $guestTeam = $opponent['team_id'];
         } else {
             $homeTeam = $opponent['team_id'];
             $guestTeam = $teamId;
         }
         // create first round
         $db->queryInsert(array('spieltyp' => $type, 'pokalname' => $cupName, 'pokalrunde' => $cupRound, 'home_verein' => $homeTeam, 'gast_verein' => $guestTeam, 'datum' => $firstRoundDate), $matchTable);
         // create second round
         if ($secondRoundDate) {
             $db->queryInsert(array('spieltyp' => $type, 'pokalname' => $cupName, 'pokalrunde' => $cupRound, 'home_verein' => $guestTeam, 'gast_verein' => $homeTeam, 'datum' => $secondRoundDate), $matchTable);
         }
         // remove opponent team from pending list
         $db->queryDelete($pendingTable, 'team_id = %d AND cup_round_id = %d', array($opponent['team_id'], $roundId));
     }
 }
 /**
  * Creates a new formation for specified team.
  * Will simply take the first 11 players and place them in a 4-4-2 formation.
  * 
  * @param WebSoccer $websoccer Application context.
  * @param DbConnection $db DB connection.
  * @param SimulationMatch $match match model.
  * @param SimulationTeam $team team model.
  */
 private static function _createRandomFormation(WebSoccer $websoccer, DbConnection $db, SimulationMatch $match, SimulationTeam $team)
 {
     // better delete possible previous formation with too few players
     $db->queryDelete($websoccer->getConfig('db_prefix') . '_youthmatch_player', 'match_id = %d AND team_id = %d', array($match->id, $team->id));
     // define the exact default formation
     $formationPositions = array('T', 'LV', 'IV', 'IV', 'RV', 'LM', 'ZM', 'ZM', 'RM', 'LS', 'RS');
     $positionMapping = SimulationHelper::getPositionsMapping();
     // set players
     $players = YouthPlayersDataService::getYouthPlayersOfTeam($websoccer, $db, $team->id);
     $positionIndex = 0;
     foreach ($players as $playerinfo) {
         $mainPosition = $formationPositions[$positionIndex];
         $position = $positionMapping[$mainPosition];
         $player = new SimulationPlayer($playerinfo['id'], $team, $position, $mainPosition, 3.0, DEFAULT_PLAYER_AGE, $playerinfo['strength'], $playerinfo['strength'], YOUTH_STRENGTH_STAMINA, YOUTH_STRENGTH_FRESHNESS, YOUTH_STRENGTH_SATISFACTION);
         $player->name = $playerinfo['firstname'] . ' ' . $playerinfo['lastname'];
         // strength adaption required?
         if ($player->position != $playerinfo['position']) {
             $player->strength = round($playerinfo['strength'] * (1 - $websoccer->getConfig('sim_strength_reduction_wrongposition') / 100));
         }
         try {
             // create record
             $columns = array('match_id' => $match->id, 'team_id' => $team->id, 'player_id' => $player->id, 'playernumber' => $positionIndex + 1, 'position' => $player->position, 'position_main' => $player->mainPosition, 'name' => $player->name);
             $db->queryInsert($columns, $websoccer->getConfig('db_prefix') . '_youthmatch_player');
             $team->positionsAndPlayers[$player->position][] = $player;
         } catch (Exception $e) {
             // could not be stored. Can happen when the youth player moved from the opponent to this team.
             // then we get a PK violation. We just don't add this player then.
         }
         $positionIndex++;
         if ($positionIndex == 11) {
             break;
         }
     }
 }
 private static function createInitialMatchData(WebSoccer $websoccer, DbConnection $db, $matchinfo)
 {
     // delete any match report items, in case a previous initial simulation failed in between.
     $db->queryDelete($websoccer->getConfig('db_prefix') . '_spiel_berechnung', 'spiel_id = %d', $matchinfo['match_id']);
     $db->queryDelete($websoccer->getConfig('db_prefix') . '_matchreport', 'match_id = %d', $matchinfo['match_id']);
     // create model
     $homeOffensive = $matchinfo['home_formation_offensive'] > 0 ? $matchinfo['home_formation_offensive'] : $websoccer->getConfig('sim_createformation_without_manager_offensive');
     $guestOffensive = $matchinfo['guest_formation_offensive'] > 0 ? $matchinfo['guest_formation_offensive'] : $websoccer->getConfig('sim_createformation_without_manager_offensive');
     $homeTeam = new SimulationTeam($matchinfo['home_id'], $homeOffensive);
     $homeTeam->setup = $matchinfo['home_formation_setup'];
     $homeTeam->isNationalTeam = $matchinfo['home_nationalteam'];
     $homeTeam->isManagedByInterimManager = $matchinfo['home_interimmanager'];
     $homeTeam->name = $matchinfo['home_name'];
     $homeTeam->longPasses = $matchinfo['home_formation_longpasses'];
     $homeTeam->counterattacks = $matchinfo['home_formation_counterattacks'];
     $guestTeam = new SimulationTeam($matchinfo['guest_id'], $guestOffensive);
     $guestTeam->setup = $matchinfo['guest_formation_setup'];
     $guestTeam->isNationalTeam = $matchinfo['guest_nationalteam'];
     $guestTeam->isManagedByInterimManager = $matchinfo['guest_interimmanager'];
     $guestTeam->name = $matchinfo['guest_name'];
     $guestTeam->longPasses = $matchinfo['guest_formation_longpasses'];
     $guestTeam->counterattacks = $matchinfo['guest_formation_counterattacks'];
     $match = new SimulationMatch($matchinfo['match_id'], $homeTeam, $guestTeam, 0);
     $match->type = $matchinfo['type'];
     $match->penaltyShootingEnabled = $matchinfo['penaltyshooting'];
     $match->cupName = $matchinfo['cup_name'];
     $match->cupRoundName = $matchinfo['cup_roundname'];
     $match->cupRoundGroup = $matchinfo['cup_groupname'];
     $match->isAtForeignStadium = $matchinfo['custom_stadium_id'] ? TRUE : FALSE;
     if (!$matchinfo['home_formation_id'] && !$matchinfo['guest_formation_id']) {
         self::handleBothTeamsHaveNoFormation($websoccer, $db, $homeTeam, $guestTeam, $match);
     } else {
         if (!$matchinfo['home_formation_id']) {
             self::handleOneTeamHasNoFormation($websoccer, $db, $homeTeam, $match);
             self::addPlayers($websoccer, $db, $match->guestTeam, $matchinfo, 'guest');
             self::addSubstitution($websoccer, $db, $match->guestTeam, $matchinfo, 'guest');
         } else {
             if (!$matchinfo['guest_formation_id']) {
                 self::handleOneTeamHasNoFormation($websoccer, $db, $guestTeam, $match);
                 self::addPlayers($websoccer, $db, $match->homeTeam, $matchinfo, 'home');
                 self::addSubstitution($websoccer, $db, $match->homeTeam, $matchinfo, 'home');
             } else {
                 self::addPlayers($websoccer, $db, $match->homeTeam, $matchinfo, 'home');
                 self::addPlayers($websoccer, $db, $match->guestTeam, $matchinfo, 'guest');
                 self::addSubstitution($websoccer, $db, $match->homeTeam, $matchinfo, 'home');
                 self::addSubstitution($websoccer, $db, $match->guestTeam, $matchinfo, 'guest');
             }
         }
     }
     return $match;
 }