/**
  * Assigns a new badge to user and notifies him, if a new badge is applicable.
  * Applicable means whether there are badges for the specified event and benchmark and whether user has
  * no higher level for this event.
  * 
  * @param WebSoccer $websoccer Application context.
  * @param DbConnection $db DB connection.
  * @param int $userId ID of user.
  * @param string $badgeEvent badge triggering event ID.
  * @param int|null $benchmark Benchmark, if applicable.
  */
 public static function awardBadgeIfApplicable(WebSoccer $websoccer, DbConnection $db, $userId, $badgeEvent, $benchmark = NULL)
 {
     // get possible badge
     $badgeTable = $websoccer->getConfig('db_prefix') . '_badge';
     $badgeUserTable = $websoccer->getConfig('db_prefix') . '_badge_user';
     $parameters = array($badgeEvent);
     $whereCondition = 'event = \'%s\'';
     if ($benchmark !== NULL) {
         $whereCondition .= ' AND event_benchmark <= %d';
         $parameters[] = $benchmark;
     }
     $whereCondition .= ' ORDER BY level DESC';
     $result = $db->querySelect('id, name, level', $badgeTable, $whereCondition, $parameters, 1);
     $badge = $result->fetch_array();
     $result->free();
     if (!$badge) {
         return;
     }
     // check whether it is better than what the user already has
     $fromTable = $badgeTable . ' INNER JOIN ' . $badgeUserTable . ' ON id = badge_id';
     $whereCondition = 'user_id = %d AND event = \'%s\' AND level >= \'%s\'';
     $result = $db->querySelect('COUNT(*) AS hits', $fromTable, $whereCondition, array($userId, $badgeEvent, $badge['level']), 1);
     $userBadges = $result->fetch_array();
     $result->free();
     if ($userBadges && $userBadges['hits']) {
         return;
     }
     self::awardBadge($websoccer, $db, $userId, $badge['id']);
 }
 /**
  * Provides teams assigned to specified cup group in their standings order.
  * 
  * @param WebSoccer $websoccer application context.
  * @param DbConnection $db DB connection.
  * @param int $roundId Cup round ID.
  * @param string $groupName Cup round group name.
  * @return array Array of teams with standings related statistics.
  */
 public static function getTeamsOfCupGroupInRankingOrder(WebSoccer $websoccer, DbConnection $db, $roundId, $groupName)
 {
     $fromTable = $websoccer->getConfig("db_prefix") . "_cup_round_group AS G";
     $fromTable .= " INNER JOIN " . $websoccer->getConfig("db_prefix") . "_verein AS T ON T.id = G.team_id";
     $fromTable .= " LEFT JOIN " . $websoccer->getConfig("db_prefix") . "_user AS U ON U.id = T.user_id";
     // where
     $whereCondition = "G.cup_round_id = %d AND G.name = '%s'";
     // order (do not use "Direktvergleich", but compare total score so far)
     $whereCondition .= "ORDER BY G.tab_points DESC, (G.tab_goals - G.tab_goalsreceived) DESC, G.tab_wins DESC, T.st_punkte DESC";
     $parameters = array($roundId, $groupName);
     // select
     $columns["T.id"] = "id";
     $columns["T.name"] = "name";
     $columns["T.user_id"] = "user_id";
     $columns["U.nick"] = "user_name";
     $columns["G.tab_points"] = "score";
     $columns["G.tab_goals"] = "goals";
     $columns["G.tab_goalsreceived"] = "goals_received";
     $columns["G.tab_wins"] = "wins";
     $columns["G.tab_draws"] = "draws";
     $columns["G.tab_losses"] = "defeats";
     $result = $db->querySelect($columns, $fromTable, $whereCondition, $parameters);
     $teams = array();
     while ($team = $result->fetch_array()) {
         $teams[] = $team;
     }
     $result->free();
     return $teams;
 }
 /**
  * Provides latest absence record for specified user.
  * 
  * @param WebSoccer $websoccer Application context.
  * @param DbConnection $db DB connection.
  * @param int $userId ID of user.
  * @return array Data record of absence or NULL if no absence record is available.
  */
 public static function getCurrentAbsenceOfUser(WebSoccer $websoccer, DbConnection $db, $userId)
 {
     $result = $db->querySelect('*', $websoccer->getConfig('db_prefix') . '_userabsence', 'user_id = %d ORDER BY from_date DESC', $userId, 1);
     $absence = $result->fetch_array();
     $result->free();
     return $absence;
 }
 public static function getCampById(WebSoccer $websoccer, DbConnection $db, $campId)
 {
     $fromTable = $websoccer->getConfig("db_prefix") . "_trainingslager";
     // where
     $whereCondition = "id = %d";
     $result = $db->querySelect(self::_getColumns(), $fromTable, $whereCondition, $campId);
     $camp = $result->fetch_array();
     $result->free();
     return $camp;
 }
 /**
  * Provide total number of leagues.
  *
  * @param WebSoccer $websoccer Application context.
  * @param DbConnection $db DB connection.
  * @return int total number of leagues.
  */
 public static function countTotalLeagues(WebSoccer $websoccer, DbConnection $db)
 {
     $result = $db->querySelect("COUNT(*) AS hits", $websoccer->getConfig("db_prefix") . "_liga", "1=1");
     $leagues = $result->fetch_array();
     $result->free();
     if (isset($leagues["hits"])) {
         return $leagues["hits"];
     }
     return 0;
 }
 /**
  * 
  * @param WebSoccer $websoccer request context.
  * @param DbConnection $db database connection.
  */
 function __construct(WebSoccer $websoccer, DbConnection $db)
 {
     $this->_availableTexts = array();
     $this->_websoccer = $websoccer;
     $this->_db = $db;
     // get available text messages
     $fromTable = $websoccer->getConfig('db_prefix') . '_spiel_text';
     $columns = 'id, aktion AS actiontype';
     $result = $db->querySelect($columns, $fromTable, '1=1');
     while ($text = $result->fetch_array()) {
         $this->_availableTexts[$text['actiontype']][] = $text['id'];
     }
     $result->free();
 }
 /**
  * 
  * @param WebSoccer $websoccer request context.
  * @param DbConnection $db database connection.
  */
 function __construct(WebSoccer $websoccer, DbConnection $db)
 {
     $this->_availableTexts = array();
     $this->_websoccer = $websoccer;
     $this->_db = $db;
     // get available text messages
     $fromTable = $websoccer->getConfig('db_prefix') . '_spiel_text';
     $columns = 'id, aktion AS actiontype';
     // only load text messages for substitutions, because this observer does not observes anything else
     $whereCondition = 'aktion = \'Auswechslung\'';
     $result = $db->querySelect($columns, $fromTable, $whereCondition);
     while ($text = $result->fetch_array()) {
         $this->_availableTexts[$text['actiontype']][] = $text['id'];
     }
     $result->free();
 }
 /**
  * Provides account statements of team.
  * 
  * @param WebSoccer $websoccer Application context.
  * @param DbConnection $db DB connection.
  * @param int $teamId ID of team
  * @param int $startIndex fetch start index.
  * @param int $entries_per_page number of items to fetch.
  * @return array list of account statements.
  */
 public static function getAccountStatementsOfTeam(WebSoccer $websoccer, DbConnection $db, $teamId, $startIndex, $entries_per_page)
 {
     $columns["absender"] = "sender";
     $columns["betrag"] = "amount";
     $columns["datum"] = "date";
     $columns["verwendung"] = "subject";
     $limit = $startIndex . "," . $entries_per_page;
     $fromTable = $websoccer->getConfig("db_prefix") . "_konto";
     $whereCondition = "verein_id = %d ORDER BY datum DESC";
     $parameters = $teamId;
     $result = $db->querySelect($columns, $fromTable, $whereCondition, $parameters, $limit);
     $statements = array();
     while ($statement = $result->fetch_array()) {
         $statements[] = $statement;
     }
     $result->free();
     return $statements;
 }
 public static function getSponsorinfoByTeamId(WebSoccer $websoccer, DbConnection $db, $clubId)
 {
     $columns["T.sponsor_spiele"] = "matchdays";
     $columns["S.id"] = "sponsor_id";
     $columns["S.name"] = "name";
     $columns["S.b_spiel"] = "amount_match";
     $columns["S.b_heimzuschlag"] = "amount_home_bonus";
     $columns["S.b_sieg"] = "amount_win";
     $columns["S.b_meisterschaft"] = "amount_championship";
     $columns["S.bild"] = "picture";
     $fromTable = $websoccer->getConfig("db_prefix") . "_sponsor AS S";
     $fromTable .= " INNER JOIN " . $websoccer->getConfig("db_prefix") . "_verein AS T ON T.sponsor_id = S.id";
     $whereCondition = "T.id = %d AND T.sponsor_spiele > 0";
     $result = $db->querySelect($columns, $fromTable, $whereCondition, $clubId, 1);
     $sponsor = $result->fetch_array();
     $result->free();
     return $sponsor;
 }
 private static function _createAndExecuteEvent(WebSoccer $websoccer, DbConnection $db, $userId, $clubId)
 {
     // get events which have not occured lately for the same user.
     // Since admin might have created a lot of events, we pick any 100 random events (ignoring weights here).
     $result = $db->querySelect('*', $websoccer->getConfig('db_prefix') . '_randomevent', 'weight > 0 AND id NOT IN (SELECT event_id FROM ' . $websoccer->getConfig('db_prefix') . '_randomevent_occurrence WHERE user_id = %d) ORDER BY RAND()', $userId, 100);
     $events = array();
     while ($event = $result->fetch_array()) {
         // add "weight" times in order to increase probability
         for ($i = 1; $i <= $event['weight']; $i++) {
             $events[] = $event;
         }
     }
     $result->free();
     if (!count($events)) {
         return;
     }
     // select and execute event
     $randomEvent = $events[array_rand($events)];
     self::_executeEvent($websoccer, $db, $userId, $clubId, $randomEvent);
     // create occurence log
     $db->queryInsert(array('user_id' => $userId, 'team_id' => $clubId, 'event_id' => $randomEvent['id'], 'occurrence_date' => $websoccer->getNowAsTimestamp()), $websoccer->getConfig('db_prefix') . '_randomevent_occurrence');
 }
 public static function getUserInactivity(WebSoccer $websoccer, DbConnection $db, $userId)
 {
     $columns["id"] = "id";
     $columns["login"] = "******";
     $columns["login_check"] = "login_check";
     $columns["aufstellung"] = "tactics";
     $columns["transfer"] = "transfer";
     $columns["transfer_check"] = "transfer_check";
     $columns["vertragsauslauf"] = "contractextensions";
     $fromTable = $websoccer->getConfig("db_prefix") . "_user_inactivity";
     $whereCondition = "user_id = %d";
     $parameters = $userId;
     $result = $db->querySelect($columns, $fromTable, $whereCondition, $parameters, 1);
     $inactivity = $result->fetch_array();
     $result->free();
     // create new entry
     if (!$inactivity) {
         $newcolumns["user_id"] = $userId;
         $db->queryInsert($newcolumns, $fromTable);
         return self::getUserInactivity($websoccer, $db, $userId);
     }
     return $inactivity;
 }
 /**
  * Provide total number of enabled users.
  *
  * @param WebSoccer $websoccer Application context.
  * @param DbConnection $db DB connection.
  * @return int total number of enabled users.
  */
 public static function countTotalUsers(WebSoccer $websoccer, DbConnection $db)
 {
     $result = $db->querySelect("COUNT(*) AS hits", $websoccer->getConfig("db_prefix") . "_user", "status = 1");
     $users = $result->fetch_array();
     $result->free();
     if (isset($users["hits"])) {
         return $users["hits"];
     }
     return 0;
 }
 /**
  * Adds players to the team model. First tries to query in a formation saved players. If not enough, then
  * creates a random formation.
  * 
  * @param WebSoccer $websoccer Application context.
  * @param DbConnection $db DB connection.
  * @param SimulationMatch $match match model.
  * @param SimulationTeam $team team model.
  */
 private static function _addPlayers(WebSoccer $websoccer, DbConnection $db, SimulationMatch $match, SimulationTeam $team)
 {
     // query set players
     $fromTable = $websoccer->getConfig('db_prefix') . '_youthmatch_player AS MP';
     $fromTable .= ' INNER JOIN ' . $websoccer->getConfig('db_prefix') . '_youthplayer AS P ON P.id = MP.player_id';
     // ensure that player still is in team in WHERE condition.
     $whereCondition = 'MP.match_id = %d AND MP.team_id = %d AND P.team_id = %d ORDER BY playernumber ASC';
     $parameters = array($match->id, $team->id, $team->id);
     $columns = array('P.id' => 'id', 'P.strength' => 'player_strength', 'P.firstname' => 'firstname', 'P.lastname' => 'lastname', 'P.position' => 'player_position', 'MP.position' => 'match_position', 'MP.position_main' => 'match_position_main', 'MP.grade' => 'grade', 'MP.state' => 'state');
     $result = $db->querySelect($columns, $fromTable, $whereCondition, $parameters);
     $addedFieldPlayers = 0;
     while ($playerinfo = $result->fetch_array()) {
         $name = $playerinfo['firstname'] . ' ' . $playerinfo['lastname'];
         // default values
         $strength = $playerinfo['player_strength'];
         $technique = $strength;
         $position = $playerinfo['player_position'];
         $mainPosition = $playerinfo['match_position_main'];
         $player = new SimulationPlayer($playerinfo['id'], $team, $position, $mainPosition, $playerinfo['grade'], DEFAULT_PLAYER_AGE, $strength, $technique, YOUTH_STRENGTH_STAMINA, YOUTH_STRENGTH_FRESHNESS, YOUTH_STRENGTH_SATISFACTION);
         $player->name = $name;
         // bench player
         if ($playerinfo['state'] == 'Ersatzbank') {
             $team->playersOnBench[$playerinfo['id']] = $player;
             // field player
         } else {
             // first player must be always goalkeeper
             if ($addedFieldPlayers == 0) {
                 $player->position = 'Torwart';
                 $player->mainPosition = 'T';
             } else {
                 $player->position = $playerinfo['match_position'];
             }
             // strength adaption required?
             if ($player->position != $playerinfo['player_position']) {
                 $player->strength = round($strength * (1 - $websoccer->getConfig('sim_strength_reduction_wrongposition') / 100));
             }
             $team->positionsAndPlayers[$player->position][] = $player;
             $addedFieldPlayers++;
         }
     }
     $result->free();
     if ($addedFieldPlayers < MIN_NUMBER_OF_PLAYERS) {
         $team->noFormationSet = TRUE;
         self::_createRandomFormation($websoccer, $db, $match, $team);
     }
 }
 /**
  * Provide latest payment log entries of specified user.
  * 
  * @param WebSoccer $websoccer Application context.
  * @param DbConnection $db DB connection.
  * @param int $userId ID of user.
  * @param int $limit number of entries to fetch.
  * @return array List of payment statements.
  */
 public static function getPaymentsOfUser(WebSoccer $websoccer, DbConnection $db, $userId, $limit)
 {
     $fromTable = $websoccer->getConfig('db_prefix') . '_premiumpayment';
     $whereCondition = 'user_id = %d ORDER BY created_date DESC';
     $result = $db->querySelect('*', $fromTable, $whereCondition, $userId, $limit);
     $statements = array();
     while ($statement = $result->fetch_array()) {
         $statement['amount'] = $statement['amount'] / 100;
         $statements[] = $statement;
     }
     $result->free();
     return $statements;
 }
 /**
  * Provides stadium construction orders which are due (i.e. deadline is in the past).
  * 
  * @param WebSoccer $websoccer Application context.
  * @param DbConnection $db DB connection.
  * @return array list of construction orders incl. builder's reliability and user ID.
  */
 public static function getDueConstructionOrders(WebSoccer $websoccer, DbConnection $db)
 {
     $fromTable = $websoccer->getConfig("db_prefix") . "_stadium_construction AS C";
     $fromTable .= " INNER JOIN " . $websoccer->getConfig("db_prefix") . "_stadium_builder AS B ON B.id = C.builder_id";
     $fromTable .= " INNER JOIN " . $websoccer->getConfig("db_prefix") . "_verein AS T ON T.id = C.team_id";
     $result = $db->querySelect("C.*, T.user_id AS user_id, B.reliability AS builder_reliability", $fromTable, "C.deadline <= %d", $websoccer->getNowAsTimestamp());
     $orders = array();
     while ($order = $result->fetch_array()) {
         $orders[] = $order;
     }
     $result->free();
     return $orders;
 }
 private static function getBonusSumFromBuildings(WebSoccer $websoccer, DbConnection $db, $attributeName, $teamId)
 {
     $dbPrefix = $websoccer->getConfig('db_prefix');
     $result = $db->querySelect('SUM(' . $attributeName . ') AS attrSum', $dbPrefix . '_buildings_of_team INNER JOIN ' . $dbPrefix . '_stadiumbuilding ON id = building_id', 'team_id = %d AND construction_deadline < %d', array($teamId, $websoccer->getNowAsTimestamp()));
     $resArray = $result->fetch_array();
     $result->free();
     if ($resArray) {
         return $resArray['attrSum'];
     }
     return 0;
 }
 /**
  * Provides open match requests.
  * 
  * @param WebSoccer $websoccer Application context.
  * @param DbConnection $db DB connection.
  * @param int $startIndex Fetch start index.
  * @param int $entries_per_page Number of items to fetch.
  * @return array list of found requests incl. team and user summary.
  */
 public static function getMatchRequests(WebSoccer $websoccer, DbConnection $db, $startIndex, $entries_per_page)
 {
     $columns = array("R.id" => "request_id", "R.matchdate" => "matchdate", "R.reward" => "reward", "C.name" => "team_name", "C.id" => "team_id", "U.id" => "user_id", "U.nick" => "user_nick", "U.email" => "user_email", "U.picture" => "user_picture");
     $fromTable = $websoccer->getConfig("db_prefix") . "_youthmatch_request AS R";
     $fromTable .= " INNER JOIN " . $websoccer->getConfig("db_prefix") . "_verein AS C ON C.id = R.team_id";
     $fromTable .= " INNER JOIN " . $websoccer->getConfig("db_prefix") . "_user AS U ON U.id = C.user_id";
     $whereCondition = "1=1 ORDER BY R.matchdate ASC";
     $requests = array();
     $limit = $startIndex . "," . $entries_per_page;
     $result = $db->querySelect($columns, $fromTable, $whereCondition, null, $limit);
     while ($request = $result->fetch_array()) {
         $request["user_picture"] = UsersDataService::getUserProfilePicture($websoccer, $request["user_picture"], $request["user_email"]);
         $requests[] = $request;
     }
     $result->free();
     return $requests;
 }
 /**
  * 
  * @param WebSoccer $websoccer
  * @param DbConnection $db
  * @param string $whereCondition
  * @param array $parameters
  * @param string $limit
  * @return array list of matches.
  */
 public static function getMatchesByCondition(WebSoccer $websoccer, DbConnection $db, $whereCondition, $parameters, $limit)
 {
     $fromTable = self::_getFromPart($websoccer);
     // select
     $columns['M.id'] = 'id';
     $columns['M.spieltyp'] = 'type';
     $columns['M.pokalname'] = 'cup_name';
     $columns['M.pokalrunde'] = 'cup_round';
     $columns['M.home_noformation'] = 'home_noformation';
     $columns['M.guest_noformation'] = 'guest_noformation';
     $columns['HOME.name'] = 'home_team';
     $columns['HOME.bild'] = 'home_team_picture';
     $columns['HOME.id'] = 'home_id';
     $columns['HOMEUSER.id'] = 'home_user_id';
     $columns['HOMEUSER.nick'] = 'home_user_nick';
     $columns['HOMEUSER.email'] = 'home_user_email';
     $columns['HOMEUSER.picture'] = 'home_user_picture';
     $columns['GUEST.name'] = 'guest_team';
     $columns['GUEST.bild'] = 'guest_team_picture';
     $columns['GUEST.id'] = 'guest_id';
     $columns['GUESTUSER.id'] = 'guest_user_id';
     $columns['GUESTUSER.nick'] = 'guest_user_nick';
     $columns['GUESTUSER.email'] = 'guest_user_email';
     $columns['GUESTUSER.picture'] = 'guest_user_picture';
     $columns['M.home_tore'] = 'home_goals';
     $columns['M.gast_tore'] = 'guest_goals';
     $columns['M.berechnet'] = 'simulated';
     $columns['M.minutes'] = 'minutes';
     $columns['M.datum'] = 'date';
     $matches = array();
     $result = $db->querySelect($columns, $fromTable, $whereCondition, $parameters, $limit);
     while ($matchinfo = $result->fetch_array()) {
         $matchinfo['home_user_picture'] = UsersDataService::getUserProfilePicture($websoccer, $matchinfo['home_user_picture'], $matchinfo['home_user_email']);
         $matchinfo['guest_user_picture'] = UsersDataService::getUserProfilePicture($websoccer, $matchinfo['guest_user_picture'], $matchinfo['guest_user_email']);
         $matches[] = $matchinfo;
     }
     $result->free();
     return $matches;
 }
 private static function _queryOffers(WebSoccer $websoccer, DbConnection $db, $startIndex, $entries_per_page, $whereCondition, $parameters)
 {
     $columns = array("O.id" => "offer_id", "O.submitted_date" => "offer_submitted_date", "O.offer_amount" => "offer_amount", "O.offer_message" => "offer_message", "O.rejected_date" => "offer_rejected_date", "O.rejected_message" => "offer_rejected_message", "O.rejected_allow_alternative" => "offer_rejected_allow_alternative", "O.admin_approval_pending" => "offer_admin_approval_pending", "P.id" => "player_id", "P.vorname" => "player_firstname", "P.nachname" => "player_lastname", "P.kunstname" => "player_pseudonym", "P.vertrag_gehalt" => "player_salary", "P.marktwert" => "player_marketvalue", "P.w_staerke" => "player_strength", "P.w_technik" => "player_strength_technique", "P.w_kondition" => "player_strength_stamina", "P.w_frische" => "player_strength_freshness", "P.w_zufriedenheit" => "player_strength_satisfaction", "P.position_main" => "player_position_main", "SU.id" => "sender_user_id", "SU.nick" => "sender_user_name", "SC.id" => "sender_club_id", "SC.name" => "sender_club_name", "RU.id" => "receiver_user_id", "RU.nick" => "receiver_user_name", "RC.id" => "receiver_club_id", "RC.name" => "receiver_club_name", "EP1.id" => "explayer1_id", "EP1.vorname" => "explayer1_firstname", "EP1.nachname" => "explayer1_lastname", "EP1.kunstname" => "explayer1_pseudonym", "EP2.id" => "explayer2_id", "EP2.vorname" => "explayer2_firstname", "EP2.nachname" => "explayer2_lastname", "EP2.kunstname" => "explayer2_pseudonym");
     $fromTable = $websoccer->getConfig("db_prefix") . "_transfer_offer AS O";
     $fromTable .= " INNER JOIN " . $websoccer->getConfig("db_prefix") . "_spieler AS P ON P.id = O.player_id";
     $fromTable .= " INNER JOIN " . $websoccer->getConfig("db_prefix") . "_user AS SU ON SU.id = O.sender_user_id";
     $fromTable .= " INNER JOIN " . $websoccer->getConfig("db_prefix") . "_verein AS SC ON SC.id = O.sender_club_id";
     $fromTable .= " INNER JOIN " . $websoccer->getConfig("db_prefix") . "_verein AS RC ON RC.id = O.receiver_club_id";
     $fromTable .= " INNER JOIN " . $websoccer->getConfig("db_prefix") . "_user AS RU ON RU.id = RC.user_id";
     $fromTable .= " LEFT JOIN " . $websoccer->getConfig("db_prefix") . "_spieler AS EP1 ON EP1.id = O.offer_player1";
     $fromTable .= " LEFT JOIN " . $websoccer->getConfig("db_prefix") . "_spieler AS EP2 ON EP2.id = O.offer_player2";
     $whereCondition .= " ORDER BY O.submitted_date DESC";
     $limit = $startIndex . "," . $entries_per_page;
     $offers = array();
     $result = $db->querySelect($columns, $fromTable, $whereCondition, $parameters, $limit);
     while ($offer = $result->fetch_array()) {
         $offer["player_marketvalue"] = PlayersDataService::getMarketValue($websoccer, $offer);
         $offers[] = $offer;
     }
     $result->free();
     return $offers;
 }
 /**
  * Provides number of simulates matches in that the specified team was involved in.
  *
  * @param WebSoccer $websoccer Application context.
  * @param DbConnection $db DB connection.
  * @param int $teamId ID of team
  * @return int number of simulated matches.
  */
 public static function countSimulatedMatches(WebSoccer $websoccer, DbConnection $db, $teamId)
 {
     $columns = "COUNT(*) AS hits";
     $fromTable = $websoccer->getConfig("db_prefix") . "_spiel";
     $result = $db->querySelect($columns, $fromTable, "(home_verein = %d OR gast_verein = %d) AND berechnet = '1'", array($teamId, $teamId));
     $matches = $result->fetch_array();
     $result->free();
     if (isset($matches["hits"])) {
         return $matches["hits"];
     }
     return 0;
 }
 public static function countOutboxMessages(WebSoccer $websoccer, DbConnection $db)
 {
     $userId = $websoccer->getUser()->id;
     $columns = "COUNT(*) AS hits";
     $fromTable = $websoccer->getConfig("db_prefix") . "_briefe AS L";
     $whereCondition = "L.absender_id = %d AND typ = 'ausgang'";
     $result = $db->querySelect($columns, $fromTable, $whereCondition, $userId);
     $letters = $result->fetch_array();
     $result->free();
     if (isset($letters["hits"])) {
         return $letters["hits"];
     }
     return 0;
 }
 private static function loadTeam(WebSoccer $websoccer, DbConnection $db, $matchId, SimulationTeam $team)
 {
     // get players
     $columns['spieler_id'] = 'player_id';
     $columns['name'] = 'name';
     $columns['note'] = 'mark';
     $columns['minuten_gespielt'] = 'minutes_played';
     $columns['karte_gelb'] = 'yellow_cards';
     $columns['karte_rot'] = 'red_cards';
     $columns['verletzt'] = 'injured';
     $columns['gesperrt'] = 'blocked';
     $columns['tore'] = 'goals';
     $columns['feld'] = 'field_area';
     $columns['position'] = 'position';
     $columns['position_main'] = 'main_position';
     $columns['age'] = 'age';
     $columns['w_staerke'] = 'strength';
     $columns['w_technik'] = 'strength_tech';
     $columns['w_kondition'] = 'strength_stamina';
     $columns['w_frische'] = 'strength_freshness';
     $columns['w_zufriedenheit'] = 'strength_satisfaction';
     $columns['ballcontacts'] = 'ballcontacts';
     $columns['wontackles'] = 'wontackles';
     $columns['losttackles'] = 'losttackles';
     $columns['shoots'] = 'shoots';
     $columns['passes_successed'] = 'passes_successed';
     $columns['passes_failed'] = 'passes_failed';
     $columns['assists'] = 'assists';
     $fromTable = $websoccer->getConfig('db_prefix') . '_spiel_berechnung';
     $whereCondition = 'spiel_id = %d AND team_id = %d ORDER BY id ASC';
     $parameters = array($matchId, $team->id);
     $result = $db->querySelect($columns, $fromTable, $whereCondition, $parameters);
     while ($playerinfo = $result->fetch_array()) {
         $player = new SimulationPlayer($playerinfo['player_id'], $team, $playerinfo['position'], $playerinfo['main_position'], $playerinfo['mark'], $playerinfo['age'], $playerinfo['strength'], $playerinfo['strength_tech'], $playerinfo['strength_stamina'], $playerinfo['strength_freshness'], $playerinfo['strength_satisfaction']);
         $player->name = $playerinfo['name'];
         $player->setBallContacts($playerinfo['ballcontacts']);
         $player->setWonTackles($playerinfo['wontackles']);
         $player->setLostTackles($playerinfo['losttackles']);
         $player->setGoals($playerinfo['goals']);
         $player->setShoots($playerinfo['shoots']);
         $player->setPassesSuccessed($playerinfo['passes_successed']);
         $player->setPassesFailed($playerinfo['passes_failed']);
         $player->setAssists($playerinfo['assists']);
         $player->setMinutesPlayed($playerinfo['minutes_played'], FALSE);
         $player->yellowCards = $playerinfo['yellow_cards'];
         $player->redCard = $playerinfo['red_cards'];
         $player->injured = $playerinfo['injured'];
         $player->blocked = $playerinfo['blocked'];
         // add player
         self::$_addedPlayers[$player->id] = $player;
         if ($playerinfo['field_area'] == 'Ausgewechselt') {
             $team->removedPlayers[$player->id] = $player;
         } else {
             if ($playerinfo['field_area'] == 'Ersatzbank') {
                 $team->playersOnBench[$player->id] = $player;
             } else {
                 $team->positionsAndPlayers[$player->position][] = $player;
             }
         }
     }
     $result->free();
 }
 /**
  * Generates a new formation for the specified team, which will be directly stored both in the database and in the internal model.
  * 
  * It is a 4-4-2 formation. It always selects the freshest players of the team.
  * 
  * @param WebSoccer $websoccer request context.
  * @param DbConnection $db database connection.
  * @param SimulationTeam $team Team that needs a new formation.
  * @param int $matchId match id.
  */
 public static function generateNewFormationForTeam(WebSoccer $websoccer, DbConnection $db, SimulationTeam $team, $matchId)
 {
     // get all players (prefer the freshest players)
     $columns['id'] = 'id';
     $columns['position'] = 'position';
     $columns['position_main'] = 'mainPosition';
     $columns['vorname'] = 'firstName';
     $columns['nachname'] = 'lastName';
     $columns['kunstname'] = 'pseudonym';
     $columns['w_staerke'] = 'strength';
     $columns['w_technik'] = 'technique';
     $columns['w_kondition'] = 'stamina';
     $columns['w_frische'] = 'freshness';
     $columns['w_zufriedenheit'] = 'satisfaction';
     if ($websoccer->getConfig('players_aging') == 'birthday') {
         $ageColumn = 'TIMESTAMPDIFF(YEAR,geburtstag,CURDATE())';
     } else {
         $ageColumn = 'age';
     }
     $columns[$ageColumn] = 'age';
     // get players from usual team
     if (!$team->isNationalTeam) {
         $fromTable = $websoccer->getConfig('db_prefix') . '_spieler';
         $whereCondition = 'verein_id = %d AND verletzt = 0 AND gesperrt = 0 AND status = 1 ORDER BY w_frische DESC';
         $parameters = $team->id;
         $result = $db->querySelect($columns, $fromTable, $whereCondition, $parameters);
     } else {
         // national team: take best players of nation
         $columnsStr = '';
         $firstColumn = TRUE;
         foreach ($columns as $dbName => $aliasName) {
             if (!$firstColumn) {
                 $columnsStr = $columnsStr . ', ';
             } else {
                 $firstColumn = FALSE;
             }
             $columnsStr = $columnsStr . $dbName . ' AS ' . $aliasName;
         }
         $nation = $db->connection->escape_string($team->name);
         $dbPrefix = $websoccer->getConfig('db_prefix');
         $queryStr = '(SELECT ' . $columnsStr . ' FROM ' . $dbPrefix . '_spieler WHERE nation = \'' . $nation . '\' AND position = \'Torwart\' ORDER BY w_staerke DESC, w_frische DESC LIMIT 1)';
         $queryStr .= ' UNION ALL (SELECT ' . $columnsStr . ' FROM ' . $dbPrefix . '_spieler WHERE nation = \'' . $nation . '\' AND position = \'Abwehr\' ORDER BY w_staerke DESC, w_frische DESC LIMIT 4)';
         $queryStr .= ' UNION ALL (SELECT ' . $columnsStr . ' FROM ' . $dbPrefix . '_spieler WHERE nation = \'' . $nation . '\' AND position = \'Mittelfeld\' ORDER BY w_staerke DESC, w_frische DESC LIMIT 4)';
         $queryStr .= ' UNION ALL (SELECT ' . $columnsStr . ' FROM ' . $dbPrefix . '_spieler WHERE nation = \'' . $nation . '\' AND position = \'Sturm\' ORDER BY w_staerke DESC, w_frische DESC LIMIT 2)';
         $result = $db->executeQuery($queryStr);
     }
     $lvExists = FALSE;
     $rvExists = FALSE;
     $lmExists = FALSE;
     $rmExists = FALSE;
     $ivPlayers = 0;
     $zmPlayers = 0;
     while ($playerinfo = $result->fetch_array()) {
         $position = $playerinfo['position'];
         // generate a 4-4-2 formation
         if ($position == PLAYER_POSITION_GOALY && isset($team->positionsAndPlayers[PLAYER_POSITION_GOALY]) && count($team->positionsAndPlayers[PLAYER_POSITION_GOALY]) == 1 || $position == PLAYER_POSITION_DEFENCE && isset($team->positionsAndPlayers[PLAYER_POSITION_DEFENCE]) && count($team->positionsAndPlayers[PLAYER_POSITION_DEFENCE]) >= 4 || $position == PLAYER_POSITION_MIDFIELD && isset($team->positionsAndPlayers[PLAYER_POSITION_MIDFIELD]) && count($team->positionsAndPlayers[PLAYER_POSITION_MIDFIELD]) >= 4 || $position == PLAYER_POSITION_STRIKER && isset($team->positionsAndPlayers[PLAYER_POSITION_STRIKER]) && count($team->positionsAndPlayers[PLAYER_POSITION_STRIKER]) >= 2) {
             continue;
         }
         $mainPosition = $playerinfo['mainPosition'];
         //prevent double LV/RV/LM/RM
         if ($mainPosition == 'LV') {
             if ($lvExists) {
                 $mainPosition = 'IV';
                 $ivPlayers++;
                 if ($ivPlayers == 3) {
                     $mainPosition = 'RV';
                     $rvExists = TRUE;
                 }
             } else {
                 $lvExists = TRUE;
             }
         } elseif ($mainPosition == 'RV') {
             if ($rvExists) {
                 $mainPosition = 'IV';
                 $ivPlayers++;
                 if ($ivPlayers == 3) {
                     $mainPosition = 'LV';
                     $lvExists = TRUE;
                 }
             } else {
                 $rvExists = TRUE;
             }
         } elseif ($mainPosition == 'IV') {
             $ivPlayers++;
             if ($ivPlayers == 3) {
                 if (!$rvExists) {
                     $mainPosition = 'RV';
                     $rvExists = TRUE;
                 } else {
                     $mainPosition = 'LV';
                     $lvExists = TRUE;
                 }
             }
         } elseif ($mainPosition == 'LM') {
             if ($lmExists) {
                 $mainPosition = 'ZM';
                 $zmPlayers++;
             } else {
                 $lmExists = TRUE;
             }
         } elseif ($mainPosition == 'RM') {
             if ($rmExists) {
                 $mainPosition = 'ZM';
                 $zmPlayers++;
             } else {
                 $rmExists = TRUE;
             }
         } elseif ($mainPosition == 'LS' || $mainPosition == 'RS') {
             $mainPosition = 'MS';
         } elseif ($mainPosition == 'ZM') {
             $zmPlayers++;
             if ($zmPlayers > 2) {
                 $mainPosition = 'DM';
             }
         }
         $player = new SimulationPlayer($playerinfo['id'], $team, $position, $mainPosition, 3.0, $playerinfo['age'], $playerinfo['strength'], $playerinfo['technique'], $playerinfo['stamina'], $playerinfo['freshness'], $playerinfo['satisfaction']);
         if (strlen($playerinfo['pseudonym'])) {
             $player->name = $playerinfo['pseudonym'];
         } else {
             $player->name = $playerinfo['firstName'] . ' ' . $playerinfo['lastName'];
         }
         $team->positionsAndPlayers[$player->position][] = $player;
         SimulationStateHelper::createSimulationRecord($websoccer, $db, $matchId, $player);
     }
     $result->free();
 }
 /**
  * Provides a proposal for a formation, considering the specified formation setup and sort column.
  * 
  * @param WebSoccer $websoccer Application Conttext
  * @param DbConnection $db DB connection
  * @param int $teamId ID of team
  * @param int $setupDefense number of players in defense
  * @param int $setupDM number of players in defensive midfield
  * @param int $setupMidfield number of players in midfield
  * @param int $setupOM number of players in offensive midfield
  * @param int $setupStriker number of players in forward area (center forward only)
  * @param int $setupOutsideforward number of outside forwards
  * @param int $sortColumn DB sort column name
  * @param string $sortDirection ASC|DESC (sort direction)
  * @param boolean $isNationalteam TRUE if team is a national team.
  * @return array array of players. Each player is an array with keys {id, position}.
  */
 public static function getFormationProposalForTeamId(WebSoccer $websoccer, DbConnection $db, $teamId, $setupDefense, $setupDM, $setupMidfield, $setupOM, $setupStriker, $setupOutsideforward, $sortColumn, $sortDirection = 'DESC', $isNationalteam = FALSE, $isCupMatch = FALSE)
 {
     $columns = 'id,position,position_main,position_second';
     if (!$isNationalteam) {
         $fromTable = $websoccer->getConfig('db_prefix') . '_spieler';
         $whereCondition = 'verein_id = %d AND gesperrt';
         if ($isCupMatch) {
             $whereCondition .= '_cups';
         }
         $whereCondition .= ' = 0 AND verletzt = 0 AND status = 1';
     } else {
         $fromTable = $websoccer->getConfig('db_prefix') . '_spieler AS P';
         $fromTable .= ' INNER JOIN ' . $websoccer->getConfig('db_prefix') . '_nationalplayer AS NP ON NP.player_id = P.id';
         $whereCondition = 'NP.team_id = %d AND gesperrt_nationalteam = 0 AND verletzt = 0 AND status = 1';
     }
     $whereCondition .= ' ORDER BY ' . $sortColumn . ' ' . $sortDirection;
     $result = $db->querySelect($columns, $fromTable, $whereCondition, $teamId);
     // determine open positions
     $openPositions['T'] = 1;
     // defense positions
     if ($setupDefense < 4) {
         $openPositions['IV'] = $setupDefense;
         $openPositions['LV'] = 0;
         $openPositions['RV'] = 0;
     } else {
         $openPositions['LV'] = 1;
         $openPositions['RV'] = 1;
         $openPositions['IV'] = $setupDefense - 2;
     }
     // defensive midfield positions
     $openPositions['DM'] = $setupDM;
     $openPositions['OM'] = $setupOM;
     // midfield positions
     if ($setupMidfield == 1) {
         $openPositions['ZM'] = 1;
     } else {
         if ($setupMidfield == 2) {
             $openPositions['LM'] = 1;
             $openPositions['RM'] = 1;
         } else {
             if ($setupMidfield == 3) {
                 $openPositions['LM'] = 1;
                 $openPositions['ZM'] = 1;
                 $openPositions['RM'] = 1;
             } else {
                 if ($setupMidfield >= 4) {
                     $openPositions['LM'] = 1;
                     $openPositions['ZM'] = $setupMidfield - 2;
                     $openPositions['RM'] = 1;
                 } else {
                     $openPositions['LM'] = 0;
                     $openPositions['ZM'] = 0;
                     $openPositions['RM'] = 0;
                 }
             }
         }
     }
     // strikers
     $openPositions['MS'] = $setupStriker;
     // outside forward
     if ($setupOutsideforward == 2) {
         $openPositions['LS'] = 1;
         $openPositions['RS'] = 1;
     } else {
         $openPositions['LS'] = 0;
         $openPositions['RS'] = 0;
     }
     $players = array();
     $unusedPlayers = array();
     while ($player = $result->fetch_array()) {
         $added = FALSE;
         // handle players without main position (all-rounder)
         if (!strlen($player['position_main'])) {
             if ($player['position'] == 'Torwart') {
                 $possiblePositions = array('T');
             } elseif ($player['position'] == 'Abwehr') {
                 $possiblePositions = array('LV', 'IV', 'RV');
             } elseif ($player['position'] == 'Mittelfeld') {
                 $possiblePositions = array('RM', 'ZM', 'LM', 'RM', 'DM', 'OM');
             } else {
                 $possiblePositions = array('LS', 'MS', 'RS');
             }
             foreach ($possiblePositions as $possiblePosition) {
                 if ($openPositions[$possiblePosition]) {
                     $openPositions[$possiblePosition] = $openPositions[$possiblePosition] - 1;
                     $players[] = array('id' => $player['id'], 'position' => $possiblePosition);
                     $added = TRUE;
                     break;
                 }
             }
             // add at main position
         } elseif (strlen($player['position_main']) && isset($openPositions[$player['position_main']]) && $openPositions[$player['position_main']]) {
             $openPositions[$player['position_main']] = $openPositions[$player['position_main']] - 1;
             $players[] = array('id' => $player['id'], 'position' => $player['position_main']);
             $added = TRUE;
         }
         // remember player for later if no space on his main position. Might be used with his secondary position, if he has any.
         if (!$added && strlen($player['position_second'])) {
             $unusedPlayers[] = $player;
         }
     }
     $result->free();
     // there might not be enough players with matching main positions, hence use players with secondary position
     foreach ($openPositions as $position => $requiredPlayers) {
         for ($i = 0; $i < $requiredPlayers; $i++) {
             for ($playerIndex = 0; $playerIndex < count($unusedPlayers); $playerIndex++) {
                 if ($unusedPlayer[$playerIndex]['position_second'] == $position) {
                     $players[] = array('id' => $unusedPlayer[$playerIndex]['id'], 'position' => $unusedPlayer[$playerIndex]['position_second']);
                     unset($unusedPlayer[$playerIndex]);
                     break;
                 }
             }
         }
     }
     return $players;
 }
 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));
     }
 }
 private static function executeFindQuery(WebSoccer $websoccer, DbConnection $db, $columns, $limit, $firstName, $lastName, $clubName, $position, $strengthMax, $lendableOnly)
 {
     $whereCondition = 'P.status = 1';
     $parameters = array();
     if ($firstName != null) {
         $firstName = ucfirst($firstName);
         $whereCondition .= ' AND P.vorname LIKE \'%s%%\'';
         $parameters[] = $firstName;
     }
     if ($lastName != null) {
         $lastName = ucfirst($lastName);
         $whereCondition .= ' AND (P.nachname LIKE \'%s%%\' OR P.kunstname LIKE \'%s%%\')';
         $parameters[] = $lastName;
         $parameters[] = $lastName;
     }
     if ($clubName != null) {
         $whereCondition .= ' AND C.name = \'%s\'';
         $parameters[] = $clubName;
     }
     if ($position != null) {
         $whereCondition .= ' AND P.position = \'%s\'';
         $parameters[] = $position;
     }
     if ($strengthMax != null && $websoccer->getConfig('hide_strength_attributes') !== '1') {
         $strengthMinValue = $strengthMax - 20;
         $strengthMaxValue = $strengthMax;
         $whereCondition .= ' AND P.w_staerke > %d AND P.w_staerke <= %d';
         $parameters[] = $strengthMinValue;
         $parameters[] = $strengthMaxValue;
     }
     if ($lendableOnly) {
         $whereCondition .= ' AND P.lending_fee > 0 AND (P.lending_owner_id IS NULL OR P.lending_owner_id = 0)';
     }
     $fromTable = $websoccer->getConfig('db_prefix') . '_spieler AS P';
     $fromTable .= ' LEFT JOIN ' . $websoccer->getConfig('db_prefix') . '_verein AS C ON C.id = P.verein_id';
     return $db->querySelect($columns, $fromTable, $whereCondition, $parameters, $limit);
 }
 /**
  * Generates new players for a specified team.
  * 
  * @param WebSoccer $websoccer Application context
  * @param DbConnection $db DB connection
  * @param int $teamId ID of team to generate players for. If 0, then players will be generated for transfer market.
  * @param int $age age of players in years.
  * @param int $ageDeviation maximum deviation of age in years.
  * @param int $salary salary per match.
  * @param int $contractDuration contract duration in number of matches.
  * @param array $strengths assoc. array of strength values. Keys are: strength, technique, stamina, freshness, satisfaction
  * @param array $positions assoc array of positions and number of players to generate for each position. Key=abbreviated positions as in DB.
  * @param int $maxDeviation maximum deviation in strength.
  * @param sring|NULL $nationality optional. Nationality of player.If not provided, it is taken from club.
  * @throws Exception if generation failed.
  */
 public static function generatePlayers(WebSoccer $websoccer, DbConnection $db, $teamId, $age, $ageDeviation, $salary, $contractDuration, $strengths, $positions, $maxDeviation, $nationality = NULL)
 {
     if (strlen($nationality)) {
         $country = $nationality;
     } else {
         // get country from team
         $fromTable = $websoccer->getConfig('db_prefix') . '_verein AS T';
         $fromTable .= ' INNER JOIN ' . $websoccer->getConfig('db_prefix') . '_liga AS L ON L.id = T.liga_id';
         $result = $db->querySelect('L.land AS country', $fromTable, 'T.id = %d', $teamId);
         $league = $result->fetch_array();
         $result->free();
         if (!$league) {
             throw new Exception('illegal team ID');
         }
         $country = $league['country'];
     }
     $firstNames = self::_getLines(FILE_FIRSTNAMES, $country);
     $lastNames = self::_getLines(FILE_LASTNAMES, $country);
     // map main position to parent position
     $mainPositions['T'] = 'Torwart';
     $mainPositions['LV'] = 'Abwehr';
     $mainPositions['IV'] = 'Abwehr';
     $mainPositions['RV'] = 'Abwehr';
     $mainPositions['LM'] = 'Mittelfeld';
     $mainPositions['ZM'] = 'Mittelfeld';
     $mainPositions['OM'] = 'Mittelfeld';
     $mainPositions['DM'] = 'Mittelfeld';
     $mainPositions['RM'] = 'Mittelfeld';
     $mainPositions['LS'] = 'Sturm';
     $mainPositions['MS'] = 'Sturm';
     $mainPositions['RS'] = 'Sturm';
     // create players for all positions
     foreach ($positions as $mainPosition => $numberOfPlayers) {
         for ($playerNo = 1; $playerNo <= $numberOfPlayers; $playerNo++) {
             $playerAge = $age + self::_getRandomDeviationValue($ageDeviation);
             $time = strtotime('-' . $playerAge . ' years', $websoccer->getNowAsTimestamp());
             $birthday = date('Y-m-d', $time);
             $firstName = self::_getItemFromArray($firstNames);
             $lastName = self::_getItemFromArray($lastNames);
             self::_createPlayer($websoccer, $db, $teamId, $firstName, $lastName, $mainPositions[$mainPosition], $mainPosition, $strengths, $country, $playerAge, $birthday, $salary, $contractDuration, $maxDeviation);
         }
     }
 }
 /**
  * Retrieves the latest notifications for the specified user.
  * 
  * @param WebSoccer $websoccer Application contex
  * @param DbConnection $db DB connection
  * @param I18n $i18n I18n context.
  * @param int $userId ID of user
  * @param int $teamId ID of user's currently selected team
  * @param int $limit maximum number of notifications to return.
  * @return array Array of assoc. arrays which represent a notification. A notification has keys id, eventdate, eventtype, seen, message, link
  */
 public static function getLatestNotifications(WebSoccer $websoccer, DbConnection $db, I18n $i18n, $userId, $teamId, $limit)
 {
     $result = $db->querySelect('*', $websoccer->getConfig('db_prefix') . '_notification', 'user_id = %d AND (team_id = %d OR team_id IS NULL) ORDER BY eventdate DESC', array($userId, $teamId), $limit);
     $notifications = array();
     while ($row = $result->fetch_array()) {
         $notification = array('id' => $row['id'], 'eventdate' => $row['eventdate'], 'eventtype' => $row['eventtype'], 'seen' => $row['seen']);
         // prepare message
         if ($i18n->hasMessage($row['message_key'])) {
             $message = $i18n->getMessage($row['message_key']);
         } else {
             $message = $row['message_key'];
         }
         // replace place holders
         if (strlen($row['message_data'])) {
             $messageData = json_decode($row['message_data'], true);
             if ($messageData) {
                 foreach ($messageData as $placeholderName => $placeholderValue) {
                     $message = str_replace('{' . $placeholderName . '}', htmlspecialchars($placeholderValue, ENT_COMPAT, 'UTF-8'), $message);
                 }
             }
         }
         $notification['message'] = $message;
         // add target link
         $link = '';
         if ($row['target_pageid']) {
             if ($row['target_querystr']) {
                 $link = $websoccer->getInternalUrl($row['target_pageid'], $row['target_querystr']);
             } else {
                 $link = $websoccer->getInternalUrl($row['target_pageid']);
             }
         }
         $notification['link'] = $link;
         $notifications[] = $notification;
     }
     return $notifications;
 }
 public static function getTrainingUnitById(WebSoccer $websoccer, DbConnection $db, $teamId, $unitId)
 {
     $columns = "*";
     $fromTable = $websoccer->getConfig("db_prefix") . "_training_unit";
     $whereCondition = "id = %d AND team_id = %d";
     $parameters = array($unitId, $teamId);
     $result = $db->querySelect($columns, $fromTable, $whereCondition, $parameters, 1);
     $unit = $result->fetch_array();
     $result->free();
     return $unit;
 }
 /**
  * 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);
     }
 }