pmelo cleaning up

This commit is contained in:
marko
2024-02-04 19:32:30 +01:00
parent da2ccb3ba3
commit b5d2655e8c
2 changed files with 189 additions and 108 deletions

View File

@@ -15,6 +15,7 @@ $pmelo = new PmElo();
class PmElo
{
/** initialize the pmelo session */
function __construct()
{
// starting/continuing a session
@@ -75,13 +76,31 @@ class PmElo
self::saveRankings($this->rankings);
}
function __destruct()
{
// sad, the destructor is not allowed to use file_put_contents
////
// html code injection
///
/** Echo the fighterInputForm */
public function htmlFighterInputForm(){
echo($this->getFighterInputForm($this->trainees));
}
// load all active trainees into a id=>User assoc array
public static function getTrainees()
/** Echo the fighterTable */
public function htmlFighterTable(){
echo($this->getFighterTable($this->fighters, $this->rankings));
}
/** Echo logOutput */
public function htmlLogOutput(){
echo($this->getLogOutput($this->log));
}
////
// saving and loading
////
/** load all active trainees into a id=>User assoc array */
static private function getTrainees()
{
$traineeList = array_map(
"User::fromDbArray",
@@ -94,39 +113,34 @@ class PmElo
return $traineeAssocArray;
}
// load ranking from json file
public static function loadRankings()
/** load ranking from json file */
static private function loadRankings()
{
return json_decode(file_get_contents(self::$pmeloJson));
}
// save a ranking to json file
public static function saveRankings(array $rankings)
/** save a ranking to json file */
static private 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);
}
////
// member functions
////
// create the ranking for the current session (load saved ranking from file, remove old trainees, add new trainees)
public function createRankings()
/** create the ranking for the current session
*
* - load saved ranking from file
* - remove old trainees
* - add new trainees
*/
private function createRankings()
{
// load the last state of the ranking
$loadedRanking = self::loadRankings();
// 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;
@@ -186,6 +200,15 @@ class PmElo
return $updatedRanking;
}
/** promote a fighter
*
* Promotion means two fighter switch places
*
* $promoteeId (int>0) id to promote
* $promopteeRank (int>0) current rank of the one to be promoted
* $degradeeId (int>0) id to demote
* $degradeeRank (int>0) new rank of the promotee
*/
private function promote(
int $promoteeId,
int $promoteeRank,
@@ -212,17 +235,100 @@ class PmElo
// do the actual switch
$this->rankings[$promoteeRank] = $degradeeId;
$this->rankings[$degradeeRank] = $promoteeId;
$this->saveRankings($this->rankings);
}
}
}
// save the updated ranking
$this->saveRankings($this->rankings);
}
// promotion means switching the position with another user
// id-s would already be sufficient, rank is just for controlling
public static function htmlPromoteButton(
////
// helper for output generation
////
/** Assemble the Input form for the fighter selection
*
* $trainees (array(participo::user)) list of trainees that can be selected for fighting
*
* return fighterInputForm as html code
*/
static private function getFighterInputForm(array $trainees){
$style = [
'classes'=>[
'input-field' => "input-field col s12"
]
];
$retHtml =
'<form id="pmelo-form-fighters" action="pmelo" method="post">'
// selects have to be wrapped into an .input-field, limitation of materializeCss
.'<div class='.$style['classes']['input-field'].'>'
.'<select name="pmelo[fighterIds][]" id="pmelo-form-fighters-select" multiple>'
.'<option value="" disabled selected>Kämpfer auswählen</option>';
foreach ($trainees as $trainee) {
$retHtml .=
'<option value="'.$trainee->getId().'">'.
$trainee->getFirstname().' '.$trainee->getName().
'</option>';
}
$retHtml .=
'</select>'.
'<label for="pmelo-form-fighters-select">'.
'Kämpfer auswählen'.
'</label>'.
'<input type="submit" value="Liste erstellen">'.
'</div>'.
'</form>';
return $retHtml;
}
/** Assemble the ranking table of the fighters
*
* $fighters (array(id=>participo::User)) list of fighters in the active round
* $ranking (array(rank=>id)) ranking of the current selected fighters
*
* return fighter ranking table as html code
*/
static private function getFighterTable(array $fighters, array $rankings){
$retHtml =
'<table>'.
'<thead><tr><th>Platz</th><th>Name</th><th>Aufstieg</th></tr></thead>'.
'<tbody>';
if (!empty($fighters)) {
// cache the predecessor in the ranking for the promoting form
$lastOne = null;
foreach ($rankings as $rank => $id) {
if (array_key_exists($id, $fighters)) {
$fighter = $fighters[$id];
$retHtml .= '<tr>'.
'<td>'.$rank.'</td>'.
'<td>'.join(' ', [$fighter->getFirstName(), $fighter->getName()]).'</td>';
if (!is_null($lastOne)){
$retHtml .= '<td>'.self::getPromoteButton(
$fighter->getId(),$rank,
$lastOne["id"],$lastOne["rank"]
).'</td>';
}
$retHtml .= '</tr>';
$lastOne = ["id" => $fighter->getId(), "rank" => $rank];
}
}
}
$retHtml .=
'</tbody>'.
'</table>';
return $retHtml;
}
/** Assemble a Promote button
*
* $promoteeId (int>0) id to promote
* $promoteeRank (int>0) current rank of the promotee
* $degradeeId (int>0) id to demote
* $degradeeRank (int>0) rank of the to be demoted
*/
static private function getPromoteButton(
int $promoteeId,
int $promoteeRank,
int $degradeeId,
@@ -237,11 +343,60 @@ class PmElo
"</form>";
}
public $log = ["error" => [], "warning" => [], "info" => []];
/** Assemble the log Output
*
* $log (array logLevel=>array(messages)) lists of log messages per logLevel
*
* return logOutput as html code
*/
private static function getLogOutput(array $log){
$retHtml =
'<ul class="collection with-header">'.
'<li class="collection-header"><h3>Logs</h3></li>';
foreach ($log as $logLevel => $messages) {
if (!empty($messages)) {
$retHtml .=
'<li class="collection-item">'.
'<ul class="collection with-header">'.
'<li class="collection-header">'.$logLevel.'</li>';
foreach ($messages as $message) {
$retHtml .=
'<li>'.$message.'</li>';
}
$retHtml .=
'</ul>'.
'</li>';
}
}
return $retHtml;
}
/** simple logger to a logging buffer */
private 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);
}
////
// member variables
////
/** current chosen trainees for fighting [id=>participo::User] */
public $fighters = null;
/** current trainees available for fighting as [id=>participo::User] */
public $trainees = null;
// list of id-s in the order of the current ranking
/** the current ranking as [rank=>id] */
public $rankings = null;
/** a place to save log messages for later output */
public $log = ["error" => [], "warning" => [], "info" => []];
static $pmeloJson = "./pmeloRanking.json";
}

View File

@@ -39,83 +39,9 @@
<main>
<h2><a href="pmelo">pmElo</a></h2>
<form id="pmelo-form-fighters" action="pmelo.php" method="post">
<div class="input-field col s12">
<select name ="pmelo[fighterIds][]" id="pmelo-form-fighters-select" multiple>
<option value="" disabled selected>Kämpfer auswählen</option>
<?php foreach ($pmelo->trainees as $trainee) {
echo "<option value=\"" .
$trainee->getId() .
"\">" .
$trainee->getFirstname() .
" " .
$trainee->getName() .
"</option>" .
PHP_EOL;
} ?>
</select>
<label for="form-select-2">Kämpfer auswählen</label>
<input type="submit" value="Liste erstellen">
</div>
</form>
<table>
<thead>
<tr><th>Platz</th><th>Name</th><th>Aufstieg</th></tr>
</thead>
<tbody>
<?php if (!empty($pmelo->fighters)) {
// remember the predecessor for the promoting form
$lastOne = null;
foreach ($pmelo->rankings as $rank => $id) {
if (array_key_exists($id, $pmelo->fighters)) {
$fighter = $pmelo->fighters[$id];
echo "<tr>" .
"<td>" .
$rank .
"</td>" .
"<td>" .
$fighter->getFirstName() .
" " .
$fighter->getName() .
"</td>" .
"<td>" .
(!is_null($lastOne)
? $pmelo->htmlPromoteButton(
$fighter->getId(),
$rank,
$lastOne["id"],
$lastOne["rank"]
)
: "") .
"</td>" .
"</tr>" .
PHP_EOL;
$lastOne = ["id" => $fighter->getId(), "rank" => $rank];
}
}
} ?>
</tbody>
</table>
<ul class="collection with-header">
<li class="collection-header"><h3>Logs</h3></li>
<?php foreach ($pmelo->log as $logLevel => $messages) {
if (!empty($messages)) { ?>
<li class="collection-item">
<ul class="collection with-header">
<li class="collection-header"><?php echo $logLevel; ?></li>
<?php foreach ($messages as $message) { ?>
<li>
<?php echo $message; ?>
</li>
<?php } ?>
</ul>
</li>
<?php } ?>
<?php
} ?>
</ul>
<?php $pmelo->htmlFighterInputForm();?>
<?php $pmelo->htmlFighterTable();?>
<?php $pmelo->htmlLogOutput();?>
</main>
</body>
</html>