/**
  * 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;
 }
 /**
  * Parses a specified page ID and redirects to another ID if required.
  * 
  * @param WebSoccer $websoccer Website context.
  * @param I18n $i18n messages provider.
  * @param string $requestedPageId unfiltered Page ID that has been requested.
  * @return string target page ID to display.
  */
 public static function getTargetPageId(WebSoccer $websoccer, I18n $i18n, $requestedPageId)
 {
     $pageId = $requestedPageId;
     // set default page ID
     if ($pageId == NULL) {
         $pageId = DEFAULT_PAGE_ID;
     }
     // redirect to log-in form if website is generally protected
     $user = $websoccer->getUser();
     if ($websoccer->getConfig('password_protected') && $user->getRole() == ROLE_GUEST) {
         // list of page IDs that needs to be excluded.
         $freePageIds = array(LOGIN_PAGE_ID, 'register', 'register-success', 'activate-user', 'forgot-password', 'imprint', 'logout', 'termsandconditions');
         if (!$websoccer->getConfig('password_protected_startpage')) {
             $freePageIds[] = DEFAULT_PAGE_ID;
         }
         if (!in_array($pageId, $freePageIds)) {
             // create warning message
             $websoccer->addFrontMessage(new FrontMessage(MESSAGE_TYPE_WARNING, $i18n->getMessage('requireslogin_box_title'), $i18n->getMessage('requireslogin_box_message')));
             $pageId = LOGIN_PAGE_ID;
         }
     }
     // exception rule: If user clicks at breadcrumb navigation on team details, there will be no ID given, so redirect to leagues
     if ($pageId == 'team' && $websoccer->getRequestParameter('id') == null) {
         $pageId = 'leagues';
     }
     // prompt user to enter user name, after he has been created without user name (e.g. by a custom LoginMethod).
     if ($user->getRole() == ROLE_USER && !strlen($user->username)) {
         $pageId = ENTERUSERNAME_PAGE_ID;
     }
     return $pageId;
 }
 /**
  * Marks user as absent, makes his teams managable by deputy and sends deputy notification about it.
  * 
  * @param WebSoccer $websoccer Application context.
  * @param DbConnection $db DB connection.
  * @param int $userId ID of user who is absent.
  * @param int $deputyId ID of user's deputy during absence.
  * @param int $days Number of days to be absent.
  */
 public static function makeUserAbsent(WebSoccer $websoccer, DbConnection $db, $userId, $deputyId, $days)
 {
     // create absence record
     $fromDate = $websoccer->getNowAsTimestamp();
     $toDate = $fromDate + 24 * 3600 * $days;
     $db->queryInsert(array('user_id' => $userId, 'deputy_id' => $deputyId, 'from_date' => $fromDate, 'to_date' => $toDate), $websoccer->getConfig('db_prefix') . '_userabsence');
     // update manager reference of managed teams
     $db->queryUpdate(array('user_id' => $deputyId, 'user_id_actual' => $userId), $websoccer->getConfig('db_prefix') . '_verein', 'user_id = %d', $userId);
     // create notification for deputy
     $user = UsersDataService::getUserById($websoccer, $db, $userId);
     NotificationsDataService::createNotification($websoccer, $db, $deputyId, 'absence_notification', array('until' => $toDate, 'user' => $user['nick']), 'absence', 'user');
 }
 /**
  * Sends an e-mail (text format) from the system to the specified recipient.
  * 
  * @param WebSoccer $websoccer current context.
  * @param I18n $i18n messages context
  * @param string $recipient recipient e-mail address
  * @param string $subject Already translated e-mail subject.
  * @param string $content message content.
  */
 public static function sendSystemEmail(WebSoccer $websoccer, $recipient, $subject, $content)
 {
     $fromName = $websoccer->getConfig('projectname');
     $fromEmail = $websoccer->getConfig('systememail');
     $headers = array();
     $headers[] = 'Content-type: text/plain; charset = \'UTF-8\'';
     $headers[] = 'From: ' . $fromName . ' <' . $fromEmail . '>';
     $encodedsubject = '=?UTF-8?B?' . base64_encode($subject) . '?=';
     if (@mail($recipient, $encodedsubject, $content, implode("\r\n", $headers)) == FALSE) {
         throw new Exception('e-mail not sent.');
     }
 }
 /**
  * Creates badge assignment.
  *
  * @param WebSoccer $websoccer Application context.
  * @param DbConnection $db DB connection.
  * @param int $userId ID of user.
  * @param int $badgeId ID od badge.
  */
 public static function awardBadge(WebSoccer $websoccer, DbConnection $db, $userId, $badgeId)
 {
     $badgeUserTable = $websoccer->getConfig('db_prefix') . '_badge_user';
     // create assignment
     $db->queryInsert(array('user_id' => $userId, 'badge_id' => $badgeId, 'date_rewarded' => $websoccer->getNowAsTimestamp()), $badgeUserTable);
     // notify lucky user
     NotificationsDataService::createNotification($websoccer, $db, $userId, 'badge_notification', null, 'badge', 'user', 'id=' . $userId);
 }
 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;
 }
 /**
  * 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;
 }
 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;
 }
 /**
  * Initilialize new simulator.
  * 
  * @param DbConnection $db database connection.
  * @param WebSoccer $websoccer Application context.
  * @throws Exception if simulation strategy class could not be found.
  */
 public function __construct(DbConnection $db, WebSoccer $websoccer)
 {
     $strategyClass = $websoccer->getConfig('sim_strategy');
     if (!class_exists($strategyClass)) {
         throw new Exception('simulation strategy class not found: ' . $strategyClass);
     }
     $this->_websoccer = $websoccer;
     $this->_db = $db;
     $this->_simStrategy = new $strategyClass($websoccer);
     $this->_simStrategy->attachObserver(new DefaultSimulationObserver());
     $this->_observers = array();
 }
 /**
  * 
  * @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();
 }
 /**
  * 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);
     }
 }
 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;
 }
 private static function createTransaction(WebSoccer $websoccer, DbConnection $db, $team, $teamId, $amount, $subject, $sender)
 {
     // ignore transaction if team is without user and option is enabled
     if (!$team["user_id"] && $websoccer->getConfig("no_transactions_for_teams_without_user")) {
         return;
     }
     // create transaction
     $fromTable = $websoccer->getConfig("db_prefix") . "_konto";
     $columns["verein_id"] = $teamId;
     $columns["absender"] = $sender;
     $columns["betrag"] = $amount;
     $columns["datum"] = $websoccer->getNowAsTimestamp();
     $columns["verwendung"] = $subject;
     $db->queryInsert($columns, $fromTable);
     // update team budget
     $newBudget = $team["team_budget"] + $amount;
     $updateColumns["finanz_budget"] = $newBudget;
     $fromTable = $websoccer->getConfig("db_prefix") . "_verein";
     $whereCondition = "id = %d";
     $parameters = $teamId;
     $db->queryUpdate($updateColumns, $fromTable, $whereCondition, $parameters);
 }
 /**
  * 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;
 }
 /**
  * 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;
 }
 /**
  * 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;
 }
 /**
  * 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);
 }
 /**
  * Triggers a recomputation of the total strength. This might be necessary when the player's grade or freshness has changed due
  * to the match simulation.
  * 
  * @param WebSoccer $websoccer application context.
  * @param SimulationMatch $match match model.
  */
 public function recomputeTotalStrength(WebSoccer $websoccer, SimulationMatch $match)
 {
     $mainStrength = $this->strength;
     // home field advantage
     if ($match->isSoldOut && $this->team->id == $match->homeTeam->id) {
         $mainStrength += $websoccer->getConfig("sim_home_field_advantage");
     }
     // weakening of NAs
     if ($this->team->noFormationSet) {
         $mainStrength = round($mainStrength * $websoccer->getConfig("sim_createformation_strength") / 100);
     }
     $weightsSum = $websoccer->getConfig("sim_weight_strength") + $websoccer->getConfig("sim_weight_strengthTech") + $websoccer->getConfig("sim_weight_strengthStamina") + $websoccer->getConfig("sim_weight_strengthFreshness") + $websoccer->getConfig("sim_weight_strengthSatisfaction");
     // get weights from settings
     $totalStrength = $mainStrength * $websoccer->getConfig("sim_weight_strength");
     $totalStrength += $this->strengthTech * $websoccer->getConfig("sim_weight_strengthTech");
     $totalStrength += $this->strengthStamina * $websoccer->getConfig("sim_weight_strengthStamina");
     $totalStrength += $this->strengthFreshness * $websoccer->getConfig("sim_weight_strengthFreshness");
     $totalStrength += $this->strengthSatisfaction * $websoccer->getConfig("sim_weight_strengthSatisfaction");
     $totalStrength = $totalStrength / $weightsSum;
     // consider mark (1.0 -> +10%, 6.0 -> -10%)
     $totalStrength = $totalStrength * (114 - 4 * $this->mark) / 100;
     $this->totalStrength = min(100, round($totalStrength));
     $this->needsStrengthRecomputation = FALSE;
 }
 private static function _executeEvent(WebSoccer $websoccer, DbConnection $db, $userId, $clubId, $event)
 {
     $notificationType = 'randomevent';
     $subject = $event['message'];
     // debit or credit money
     if ($event['effect'] == 'money') {
         $amount = $event['effect_money_amount'];
         $sender = $websoccer->getConfig('projectname');
         if ($amount > 0) {
             BankAccountDataService::creditAmount($websoccer, $db, $clubId, $amount, $subject, $sender);
         } else {
             BankAccountDataService::debitAmount($websoccer, $db, $clubId, $amount * (0 - 1), $subject, $sender);
         }
         // notification
         NotificationsDataService::createNotification($websoccer, $db, $userId, $subject, null, $notificationType, 'finances', null, $clubId);
         // execute on random player
     } else {
         // select random player from team
         $result = $db->querySelect('id, vorname, nachname, kunstname, w_frische, w_kondition, w_zufriedenheit', $websoccer->getConfig('db_prefix') . '_spieler', 'verein_id = %d AND gesperrt = 0 AND verletzt = 0 AND status = \'1\' ORDER BY RAND()', $clubId, 1);
         $player = $result->fetch_array();
         $result->free();
         if (!$player) {
             return;
         }
         // execute (get update column)
         switch ($event['effect']) {
             case 'player_injured':
                 $columns = array('verletzt' => $event['effect_blocked_matches']);
                 break;
             case 'player_blocked':
                 $columns = array('gesperrt' => $event['effect_blocked_matches']);
                 break;
             case 'player_happiness':
                 $columns = array('w_zufriedenheit' => max(1, min(100, $player['w_zufriedenheit'] + $event['effect_skillchange'])));
                 break;
             case 'player_fitness':
                 $columns = array('w_frische' => max(1, min(100, $player['w_frische'] + $event['effect_skillchange'])));
                 break;
             case 'player_stamina':
                 $columns = array('w_kondition' => max(1, min(100, $player['w_kondition'] + $event['effect_skillchange'])));
                 break;
         }
         // update player
         if (!isset($columns)) {
             return;
         }
         $db->queryUpdate($columns, $websoccer->getConfig('db_prefix') . '_spieler', 'id = %d', $player['id']);
         // create notification
         $playerName = strlen($player['kunstname']) ? $player['kunstname'] : $player['vorname'] . ' ' . $player['nachname'];
         NotificationsDataService::createNotification($websoccer, $db, $userId, $subject, array('playername' => $playerName), $notificationType, 'player', 'id=' . $player['id'], $clubId);
     }
 }
 /**
  * Provides market value of player. Depending on settings, either value from DB table or computed value.
  * Computed value is configured value per strength point * weighted total strength of player.
  * 
  * @param WebSoccer $websoccer Application context.
  * @param array $player Player info array.
  * @param string $columnPrefix column prefix used in player array.
  * @return int market value of player.
  */
 public static function getMarketValue(WebSoccer $websoccer, $player, $columnPrefix = 'player_')
 {
     if (!$websoccer->getConfig('transfermarket_computed_marketvalue')) {
         return $player[$columnPrefix . 'marketvalue'];
     }
     // compute market value
     $totalStrength = $websoccer->getConfig('sim_weight_strength') * $player[$columnPrefix . 'strength'];
     $totalStrength += $websoccer->getConfig('sim_weight_strengthTech') * $player[$columnPrefix . 'strength_technique'];
     $totalStrength += $websoccer->getConfig('sim_weight_strengthStamina') * $player[$columnPrefix . 'strength_stamina'];
     $totalStrength += $websoccer->getConfig('sim_weight_strengthFreshness') * $player[$columnPrefix . 'strength_freshness'];
     $totalStrength += $websoccer->getConfig('sim_weight_strengthSatisfaction') * $player[$columnPrefix . 'strength_satisfaction'];
     $totalStrength /= $websoccer->getConfig('sim_weight_strength') + $websoccer->getConfig('sim_weight_strengthTech') + $websoccer->getConfig('sim_weight_strengthStamina') + $websoccer->getConfig('sim_weight_strengthFreshness') + $websoccer->getConfig('sim_weight_strengthSatisfaction');
     return $totalStrength * $websoccer->getConfig('transfermarket_value_per_strength');
 }
 private static function _getFromPart(WebSoccer $websoccer)
 {
     $tablePrefix = $websoccer->getConfig('db_prefix');
     // from
     $fromTable = $tablePrefix . '_spiel AS M';
     $fromTable .= ' INNER JOIN ' . $tablePrefix . '_verein AS HOME ON M.home_verein = HOME.id';
     $fromTable .= ' INNER JOIN ' . $tablePrefix . '_verein AS GUEST ON M.gast_verein = GUEST.id';
     $fromTable .= ' LEFT JOIN ' . $tablePrefix . '_user AS HOMEUSER ON M.home_user_id = HOMEUSER.id';
     $fromTable .= ' LEFT JOIN ' . $tablePrefix . '_user AS GUESTUSER ON M.gast_user_id = GUESTUSER.id';
     return $fromTable;
 }
 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 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 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;
 }
 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;
 }
 /**
  * Computes costs for upgrading to the next level of a maintenace item (grass, video wall, seats or VIP lounges quality).
  * 
  * @param WebSoccer $websoccer Application context.
  * @param string $type pitch|videowall|seatsquality|vipquality
  * @param array $stadium stadium data record.
  * @return int costs for upgrading to the next level.
  */
 public static function computeUpgradeCosts(WebSoccer $websoccer, $type, $stadium)
 {
     $existingLevel = $stadium["level_" . $type];
     if ($existingLevel >= 5) {
         return 0;
     }
     $baseCost = $websoccer->getConfig("stadium_" . $type . "_price");
     // costs per seat
     if ($type == "seatsquality") {
         $baseCost = $baseCost * ($stadium["places_seats"] + $stadium["places_seats_grand"]);
     } elseif ($type == "vipquality") {
         $baseCost = $baseCost * $stadium["places_vip"];
     }
     // additional charge for levels > 1
     $additionFactor = $websoccer->getConfig("stadium_maintenance_priceincrease_per_level") * $existingLevel / 100;
     return round($baseCost + $baseCost * $additionFactor);
 }
 private static function weakenPlayersDueToGrassQuality(WebSoccer $websoccer, $homeInfo, SimulationMatch $match)
 {
     $strengthChange = (5 - $homeInfo['level_pitch']) * $websoccer->getConfig('stadium_pitch_effect');
     if ($strengthChange && $match->type != 'Freundschaft') {
         $playersAndPositions = $match->homeTeam->positionsAndPlayers;
         foreach ($playersAndPositions as $positions => $players) {
             foreach ($players as $player) {
                 $player->strengthTech = max(1, $player->strengthTech - $strengthChange);
             }
         }
     }
 }
 /**
  * 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;
 }
 /**
  * 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();
 }