Files
cwsvJudo/homepage/participo/pmelo.inc.php
2024-01-23 19:49:41 +01:00

179 lines
7.3 KiB
PHP

<?php
setlocale(LC_ALL, "de_DE@euro", "de_DE", "de", "ge");
set_include_path(get_include_path() . PATH_SEPARATOR . "./lib/");
// Configs
require_once("config/participo.php");
require_once $config['basePath'] . "/config/cwsvJudo.config.php";
// Libs
require_once("participoLib/user.php");
participo::init($cwsvJudoConfig);
$pmelo = new PmElo();
class PmElo{
function __construct()
{
// $this->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";
}