/**
  * Search for physicians.
  *
  * @return JSON
  */
 public function search(Request $request)
 {
     $physicians = null;
     $searchDistance = $request->distance ? $request->distance : 0;
     $coords = $this->getCoordinates($request);
     $orderBy = $request->has('order_by') ? $request->order_by : 'distance';
     $sort = $request->has('sort') ? $request->sort : 'asc';
     $limit = $request->has('per_page') ? $request->per_page : '25';
     // if we don't have a requested distance, we'll cycle through
     // our fallback distances until we get at least 1 result;
     // if we don't have anything by our max distance, we'll return 0.
     if (!$request->has('distance')) {
         while (!$physicians || $physicians->count() == 0) {
             $searchDistance = $this->getNextDistance($searchDistance);
             $physicians = Physician::withinDistance($coords['lat'], $coords['lon'], $searchDistance)->alias($request->alias_id)->name($request->q)->gender($request->gender);
             if ($searchDistance == $this->maxDistance) {
                 break;
             }
         }
     } else {
         $physicians = Physician::withinDistance($coords['lat'], $coords['lon'], $searchDistance)->alias($request->alias_id)->name($request->q)->gender($request->gender);
     }
     $alias = Alias::find($request->alias_id);
     $queryMeta = ['city' => Str::title(urldecode($request->city)), 'state' => mb_strtoupper($request->state), 'zip' => $request->zip ? $request->zip : $this->getZip($request->city, $request->state), 'alias' => $alias ? $alias->alias : null, 'alias_id' => $alias ? $alias->id : null, 'aggregate' => AggregateReporter::report($physicians, $request->alias_id), 'q' => $request->q, 'gender' => $request->gender, 'count' => $physicians ? $physicians->count() : 0, 'radius' => $searchDistance, 'order_by' => $request->order_by, 'sort' => $request->sort, 'center' => ['lat' => $coords['lat'], 'lon' => $coords['lon']]];
     $physicians = $physicians->orderBy($orderBy, $sort)->paginate($limit)->appends($request->query());
     return $this->response->withPaginator($physicians, new PhysicianTransformer(), null, $queryMeta);
 }
 /**
  * Convert array of [[alias_id => count]] items into 
  * an array suitable for returning in the meta entry.
  *
  * @param array
  * @return array
  */
 private static function translateAliases($aliasCounts)
 {
     $aliasesForMeta = [];
     foreach ($aliasCounts as $aliasCount) {
         $a = Alias::find($aliasCount['id']);
         $aliasesForMeta[$a->alias] = ['id' => $a->id, 'alias' => $a->alias, 'count' => $aliasCount['count']];
     }
     return $aliasesForMeta;
 }
 /**
  * @return bool
  *
  * Track all round record into Database.
  */
 public function track()
 {
     /**
      * @var Game
      */
     $game = new Game();
     $game->tag = $this->roundTag;
     $game->server_time = $this->serverTime;
     $game->round_time = $this->timePlayed;
     $game->round_index = $this->roundIndex + 1 . " / " . $this->roundLimit;
     $game->gametype = $this->gameType;
     $game->outcome = $this->roundOutcome;
     $game->map_id = $this->gameMap;
     $game->total_players = $this->totalPlayers;
     $game->swat_score = $this->swatScore;
     $game->suspects_score = $this->suspectsScore;
     $game->swat_vict = $this->swatVictory;
     $game->suspects_vict = $this->suspectsVictory;
     if (!$game->save()) {
         return false;
     }
     /**
      * Iterate over each player array
      */
     foreach ($this->players as $p) {
         /**
          * @var Player
          */
         $player = new Player();
         $player->ingame_id = $p[0];
         $player->ip_address = $p[1];
         $player->name = str_replace('(VIEW)', '', $p[5]);
         $player->name = str_replace('(SPEC)', '', $player->name);
         $player->team = array_key_exists(6, $p) ? $p[6] : 0;
         $player->is_admin = array_key_exists(3, $p) ? $p[3] : 0;
         $player->is_dropped = array_key_exists(2, $p) ? $p[2] : 0;
         $player->score = array_key_exists(8, $p) ? $p[8] : 0;
         $player->time_played = array_key_exists(7, $p) ? $p[7] : 0;
         $player->kills = array_key_exists(9, $p) ? $p[9] : 0;
         $player->team_kills = array_key_exists(10, $p) ? $p[10] : 0;
         $player->deaths = array_key_exists(11, $p) ? $p[11] : 0;
         $player->suicides = array_key_exists(12, $p) ? $p[12] : 0;
         $player->arrests = array_key_exists(13, $p) ? $p[13] : 0;
         $player->arrested = array_key_exists(14, $p) ? $p[14] : 0;
         $player->kill_streak = array_key_exists(15, $p) ? $p[15] : 0;
         $player->arrest_streak = array_key_exists(16, $p) ? $p[16] : 0;
         $player->death_streak = array_key_exists(17, $p) ? $p[17] : 0;
         $player->game_id = $game->id;
         $player_ip_trim = substr($p[1], 0, strrpos($p[1], "."));
         $player_country_id = 0;
         $geoip = App::make('geoip');
         try {
             if ($player_geoip = $geoip->city($player->ip_address)) {
                 $player_isoCode = $player_geoip->country->isoCode;
                 $country = Country::where('countryCode', 'LIKE', $player_isoCode)->first();
                 /**
                  * Country returned is not in Countrie table
                  */
                 if ($country == null) {
                     $player_country_id = 0;
                 } else {
                     $player_country_id = $country->id;
                 }
             }
         } catch (\Exception $e) {
             switch ($e) {
                 case $e instanceof \InvalidArgumentException:
                     $player_country_id = 0;
                     break;
                 case $e instanceof \GeoIp2\Exception\AddressNotFoundException:
                     $player_country_id = 0;
                     break;
                 default:
                     $player_country_id = 0;
                     break;
             }
         }
         $loadout_array = array_key_exists(39, $p) ? $p[39] : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
         /**
          * @var Loadout
          *
          * Create or find and return instance of Loadout and save to database.
          */
         $loadout = Loadout::firstOrCreate(['primary_weapon' => array_key_exists(0, $loadout_array) ? $loadout_array[0] : 0, 'primary_ammo' => array_key_exists(1, $loadout_array) ? $loadout_array[1] : 0, 'secondary_weapon' => array_key_exists(2, $loadout_array) ? $loadout_array[2] : 0, 'secondary_ammo' => array_key_exists(3, $loadout_array) ? $loadout_array[3] : 0, 'equip_one' => array_key_exists(4, $loadout_array) ? $loadout_array[4] : 0, 'equip_two' => array_key_exists(5, $loadout_array) ? $loadout_array[5] : 0, 'equip_three' => array_key_exists(6, $loadout_array) ? $loadout_array[6] : 0, 'equip_four' => array_key_exists(7, $loadout_array) ? $loadout_array[7] : 0, 'equip_five' => array_key_exists(8, $loadout_array) ? $loadout_array[8] : 0, 'breacher' => array_key_exists(9, $loadout_array) ? $loadout_array[9] : 0, 'body' => array_key_exists(10, $loadout_array) ? $loadout_array[10] : 0, 'head' => array_key_exists(11, $loadout_array) ? $loadout_array[11] : 0]);
         /**
          * Create or find and return instance of Alias.
          */
         $alias = Alias::firstOrNew(['name' => $player->name]);
         /**
          * If Alias is not present then new instance is created.
          */
         if ($alias->id == null) {
             //$profile = Profile::firstOrNew(['ip_address' => $player_ip_trim.'%']);
             $profile = Profile::where('ip_address', 'LIKE', $player_ip_trim . '%')->first();
             // If no profile present create new else ignore.
             if (!$profile) {
                 $profile = new Profile();
             }
             /**
              * Neither Alias not Profile is present.
              *
              * So it will create both new Alias and Profile.
              */
             if ($profile->id == null) {
                 $profile->name = $player->name;
                 $profile->team = $player->team;
                 $profile->country_id = $player_country_id;
                 $profile->loadout_id = $loadout->id;
                 $profile->game_first = $game->id;
                 $profile->game_last = $game->id;
                 $profile->ip_address = $player->ip_address;
                 $profile->save();
                 $alias->name = $player->name;
                 $alias->profile_id = $profile->id;
                 $alias->ip_address = $player->ip_address;
                 $alias->save();
             } else {
                 $alias->name = $player->name;
                 $alias->profile_id = $profile->id;
                 $alias->ip_address = $player->ip_address;
                 $alias->save();
                 $profile->team = $player->team;
                 $profile->game_last = $game->id;
                 $profile->loadout_id = $loadout->id;
                 $profile->ip_address = $player->ip_address;
                 $profile->country_id = $player_country_id;
                 $profile->save();
             }
         } else {
             $profile = Profile::find($alias->profile_id);
             $profile->team = $player->team;
             $profile->game_last = $game->id;
             $profile->loadout_id = $loadout->id;
             $profile->ip_address = $player->ip_address;
             $profile->country_id = $player_country_id;
             $profile->save();
             $alias->ip_address = $player->ip_address;
             $alias->save();
         }
         $player->alias_id = $alias->id;
         $player->loadout_id = $loadout->id;
         $player->country_id = $player_country_id;
         $player->save();
         /**
          * Iterate over all Weapon of each Player if exists
          */
         if (array_key_exists(40, $p)) {
             foreach ($p[40] as $w) {
                 $weapon = new Weapon();
                 $weapon->name = $w[0];
                 $weapon->player_id = $player->id;
                 $weapon->seconds_used = array_key_exists(1, $w) ? $w[1] : 0;
                 $weapon->shots_fired = array_key_exists(2, $w) ? $w[2] : 0;
                 $weapon->shots_hit = array_key_exists(3, $w) ? $w[3] : 0;
                 $weapon->shots_teamhit = array_key_exists(4, $w) ? $w[4] : 0;
                 $weapon->kills = array_key_exists(5, $w) ? $w[5] : 0;
                 $weapon->teamkills = array_key_exists(6, $w) ? $w[6] : 0;
                 $weapon->distance = array_key_exists(7, $w) ? $w[7] : 0;
                 $weapon->save();
             }
         }
     }
     //$pt = new App\Server\Repositories\PlayerTotalRepository();
     //$pt->calculate();
     //$response = Response::make("0\\nStats has been successfully tracked",200);
     printf("%s", "0\nRound report tracked.");
     exit(0);
 }
 /**
  * Deletes old player_totals table and reload everything from
  * scratches into it.
  *
  * @return string
  */
 public function calculate()
 {
     \DB::table('player_totals')->truncate();
     $aliases = Alias::with('players')->whereNotIn('name', DeletedPlayer::lists('player_name'))->get();
     $totalServerScore = Player::sum('score');
     foreach ($aliases as $alias) {
         $playerTotal = new PlayerTotal();
         $playerTotal->name = $alias->name;
         $playerTotal->alias_id = $alias->id;
         $playerTotal->profile_id = $alias->profile_id;
         /*$playerTotal->last_loadout_id = $alias->profile->loadout_id;*/
         $playerTotal->last_team = $alias->profile->team;
         //$playerTotal->first_game_id = $alias->profile->game_first;
         //$playerTotal->last_game_id = $alias->profile->game_last;
         $playerTotal->country_id = $alias->players->last()->country_id;
         $playersCollection = $alias->players;
         //Permanent Solution
         if ($alias->profile->loadout->kyaKhali()) {
             foreach ($playersCollection->reverse() as $item) {
                 if (!$item->loadout->kyaKhali()) {
                     $playerTotal->last_loadout_id = $item->loadout_id;
                     break;
                 } else {
                     $playerTotal->last_loadout_id = $item->loadout_id;
                 }
             }
         } else {
             $playerTotal->last_loadout_id = $alias->profile->loadout_id;
         }
         $playerTotal->first_game_id = $playersCollection->min('game_id');
         $playerTotal->last_game_id = $playersCollection->max('game_id');
         $playerTotal->is_admin = $playersCollection->max('is_admin');
         $playerTotal->total_score = $playersCollection->sum('score');
         $playerTotal->highest_score = $playersCollection->max('score');
         $playerTotal->total_time_played = $playersCollection->sum('time_played');
         $playerTotal->total_kills = $playersCollection->sum('kills');
         $playerTotal->total_team_kills = $playersCollection->sum('team_kills');
         $playerTotal->total_deaths = $playersCollection->sum('deaths');
         $playerTotal->total_suicides = $playersCollection->sum('suicides');
         $playerTotal->total_arrests = $playersCollection->sum('arrests');
         $playerTotal->total_arrested = $playersCollection->sum('arrested');
         $playerTotal->best_killstreak = $playersCollection->max('kill_streak');
         $playerTotal->best_deathstreak = $playersCollection->max('death_streak');
         $playerTotal->best_arreststreak = $playersCollection->max('arrest_streak');
         $playerTotal->total_round_played = $playersCollection->unique('game_id')->count('game_id');
         $playerTotal->last_ip_address = $alias->ip_address;
         $playerTotal->killdeath_ratio = $playerTotal->total_deaths == 0 ? $playerTotal->total_kills : round($playerTotal->total_kills / $playerTotal->total_deaths, 2);
         $playerTotal->arr_ratio = $playerTotal->total_arrested == 0 ? $playerTotal->total_arrests : round($playerTotal->total_arrests / $playerTotal->total_arrested, 2);
         $playerTotal->score_per_min = $playerTotal->total_time_played == 0 ? $playerTotal->total_score : round($playerTotal->total_score / $playerTotal->total_time_played * 60, 2);
         $playerTotal->score_percentile = $playerTotal->total_score == 0 || $totalServerScore == 0 ? 0 : round($playerTotal->total_score / $totalServerScore * 100, 2);
         $won = 0;
         $lost = 0;
         $draw = 0;
         foreach ($playersCollection->unique('game_id') as $player) {
             switch ($player->game->isWinner($player->team)) {
                 case 0:
                     $lost++;
                     break;
                 case 1:
                     $won++;
                     break;
                 case -1:
                     $draw++;
                     break;
                 default:
                     break;
             }
         }
         $playerTotal->game_won = $won;
         $playerTotal->game_lost = $lost;
         $playerTotal->game_draw = $draw;
         $playerTotal->total_points = max($playerTotal->total_kills * 4 + $playerTotal->total_arrests * 13 - $playerTotal->total_deaths - $playerTotal->total_arrested * 3 - $playerTotal->total_team_kills * 2, 0);
         /**
          * This give extra points to the player from PlayerPoints Model
          */
         $playerPoints = PlayerPoint::where('name', $playerTotal->name)->get();
         if (!$playerPoints->isEmpty()) {
             $pointsToGive = $playerPoints->sum('points');
             $playerTotal->total_points += $pointsToGive;
         }
         /**
          * Calculation of player_rating
          *
          * Calculate only if player with this alias has played more than 10 hours in server
          * and also is active and seen in last 7 days
          */
         $last_seen_game = Game::find($playerTotal->last_game_id);
         if ($playerTotal->total_time_played > 60 * 60 * 10 && \Carbon\Carbon::now()->timestamp - $last_seen_game->updated_at->timestamp <= 60 * 60 * 24 * 7) {
             $playerTotal->player_rating = max($playerTotal->killdeath_ratio + $playerTotal->arr_ratio + $playerTotal->score_per_min * 1.25, 0);
             $playerTotal->player_rating = min($playerTotal->player_rating, 10);
         }
         /**
          * Calculation of rank_id using total_points and Rank table
          *
          * Add this if want time played(rank_seconds) also used to calculate ranks
          * ->where('rank_seconds', '<=' ,$playerTotal->total_time_played)
          *
          * Make sure that there are ranks in ranks table if not,
          * Run php artisan db:seed
          */
         $playerTotal->rank_id = Rank::where('rank_points', '>=', $playerTotal->total_points)->orderBy('rank_points')->first()->id;
         $playerTotal->save();
     }
     /**
      * Getting all PlayerTotal and updating its position one by one.
      */
     $pTs = PlayerTotal::orderBy('player_rating', 'DESC')->orderBy('total_points', 'DESC')->orderBy('total_score', 'DESC')->get();
     $position = 0;
     foreach ($pTs as $pT) {
         $pT->position = ++$position;
         $pT->save();
     }
     // Put to Top Player so that some bugs are fixed.
     $topPlayers = PlayerTotal::with(['country', 'rank'])->orderBy('position')->limit(10)->get();
     Cache::put('top_players', $topPlayers, 31);
     return "Players total has been logged into player_total table successfully!";
 }