var_log($_SESSION, "session"); // starting/continuing a session session_start(); // create 'pmelo' section in the sessions data if(!array_key_exists('pmelo', $_SESSION)){ $_SESSION['pmelo'] = []; } // - data storage for id-s of chosen fighters if(!array_key_exists('fighterIds', $_SESSION['pmelo'])){ $_SESSION['pmelo']['fighterIds'] = []; } // check for action in post data if(array_key_exists('pmelo', $_POST)){ if(array_key_exists('fighterIds', $_POST['pmelo'])){ $_SESSION['pmelo']['fighterIds']=$_POST['pmelo']['fighterIds']; } // $this->var_log($_SESSION, "session"); } // load/recreate ranking data if(!is_file(self::$pmeloJson)){ $this->log['info'][] = "Couldn't find `".self::$pmeloJson."`. Create a new one!"; file_put_contents(self::$pmeloJson, json_encode([])); } // init members $this->trainees = self::getTrainees(); $this->var_log(array_map(function($user){return $user->getFirstName();},$this->trainees), "trainees from db"); $this->rankings = $this->createRankings(); $this->var_log(array_map(function($id){return $this->trainees[$id]->getFirstName();},$this->rankings), "current ranking"); $this->fighters = []; foreach($_SESSION['pmelo']['fighterIds'] as $id){ $this->fighters[$id] = $this->trainees[$id]; }; $this->var_log(array_map(function($user){return $user->getFirstName();},$this->fighters), "fighters"); // save the updated ranking // @todo should be in destructor self::saveRankings($this->rankings); } function __destruct(){ // sad, the destructor is not allowed to use file_put_contents } // load all active trainees into a id=>User assoc array public static function getTrainees(){ $traineeList = array_map('User::fromDbArray', User::dbSelectWithAttribute(4)); $traineeAssocArray = []; foreach($traineeList as $trainee){ $traineeAssocArray[$trainee->getId()] = $trainee; } return $traineeAssocArray; } // load ranking from json file public static function loadRankings(){ return json_decode(file_get_contents(self::$pmeloJson)); } // save a ranking to json file public static function saveRankings(array $rankings){ file_put_contents(self::$pmeloJson, json_encode($rankings)); } // simple logger to a logging buffer function var_log($variable, string $prefix=null, string $logChannel='info'){ if(!in_array($logChannel, ['info', 'warning', 'error'])){ $logChannel='info'; } $prefix = (!empty($prefix) ? $prefix.": " : ""); $this->log[$logChannel][]=$prefix.var_export($variable, true); } // create the ranking for the current session (load saved ranking from file, remove old trainees, add new trainees) public function createRankings(){ // load the last state of the ranking $loadedRanking = self::loadRankings(); $this->var_log(array_map(function($id){$user=$this->trainees[$id]; return $user->getFirstName();}, $loadedRanking), "loaded ranking"); // check if the ranked trainees still are in training // - the ranking with $cleanRanking = []; // - trainees that aren't currently in the ranking for later inserting $toBeInsertedTrainees = $this->trainees; foreach($loadedRanking as $id){ if(array_key_exists($id, $this->trainees)){ // userId is still in training, so append it to the cleaned up ranking $cleanRanking[] = $id; // trainees already in the ranking we won't have to insert manual unset($toBeInsertedTrainees[$id]); } } // get the ids of the to be inserted trainees sorted by the birthday $newTraineesIds = array_map(function($u){return $u->getId();},$toBeInsertedTrainees); usort( $newTraineesIds , function($lhs, $rhs){ return $this->trainees[$lhs]->getStrBirthday() < $this->trainees[$rhs]->getStrBirthday() ? -1 : ($this->trainees[$lhs]->getStrBirthday() > $this->trainees[$rhs]->getStrBirthday() ? 1 : 0); } ); // $this->var_log( // array_map( // function($id){return $this->trainees[$id]->getStrBirthday()." ".$this->trainees[$id]->getFirstName();} // , $newTraineesIds // ) // , "newTraineesBy B-Day" // ); // now we do a mergesort (step) $updatedRanking = []; $idxNewTrainees = count($newTraineesIds)-1; $idxRanking = count($cleanRanking)-1; // - while we can merge, we merge while( ($idxRanking >= 0) && ($idxNewTrainees >= 0) ){ // $this->var_log( [$idxRanking.", ".$idxNewTrainees=>$updatedRanking] ); // $this->var_log( // [$this->trainees[$cleanRanking[$idxRanking]]->getStrBirthday(), $this->trainees[$newTraineesIds[$idxRanking]]->getStrBirthday()] // ); if( $this->trainees[$cleanRanking[$idxRanking]]->getDateOfBirth() > $this->trainees[$newTraineesIds[$idxNewTrainees]]->getDateOfBirth() ){ // $this->var_log( $this->trainees[$cleanRanking[$idxRanking]]->getFirstName(), "merge ranking insert" ); array_unshift($updatedRanking, $cleanRanking[$idxRanking]); $idxRanking-=1; }else{ // $this->var_log( $this->trainees[$newTraineesIds[$idxNewTrainees]]->getFirstName(), "merge trainees insert" ); array_unshift($updatedRanking, $newTraineesIds[$idxNewTrainees]); $idxNewTrainees-=1; } } // $this->var_log( // ["idxR ".$idxRanking." idxNT ".$idxNewTrainees=>[$cleanRanking, $newTraineesIds]] // , "after merge" // ); while( $idxRanking >= 0 ){ // $this->var_log( $this->trainees[$cleanRanking[$idxRanking]]->getFirstName(), "rest ranking insert" ); array_unshift($updatedRanking, $cleanRanking[$idxRanking]); $idxRanking-=1; } while( $idxNewTrainees >= 0 ){ // $this->var_log( $this->trainees[$newTraineesIds[$idxNewTrainees]]->getFirstName(), "rest newTrainees insert" ); array_unshift($updatedRanking, $newTraineesIds[$idxNewTrainees]); $idxNewTrainees-=1; } return $updatedRanking; } public $log = ['error'=>[], 'warning'=>[], 'info'=>[]]; public $fighters = null; public $trainees = null; // list of id-s in the order of the current ranking public $rankings = null; static $pmeloJson="./pmeloRanking.json"; }