- changes in layout of the achievementgroup cards

- accomplished/next achievement(s) now in collappsibel
  - record reporting button now hidden in collapsible
  - cards list groups that are unlocked from the group
This commit is contained in:
marko
2020-11-29 18:06:30 +01:00
parent de24498f77
commit ac7d81b136
4 changed files with 237 additions and 83 deletions

View File

@@ -91,12 +91,12 @@ function processPostData($db, $post, $redirectLocation = "."){
$u['vorname']." ".$u['name']." got ".$post['value']." in ".$g->getName(),
"[machs] Rekord eingetragen"
);
//setRecord(
//$db,
//$post['userId'],
//$post['achievementGroupId'],
//$post['value']
//);
setRecord(
$db,
$post['userId'],
$post['achievementGroupId'],
$post['value']
);
}
if($post['action']=="reportRecord"){
# $u = getUserData($db, $post['userId']);

View File

@@ -13,7 +13,9 @@ class achievementGroup{
private $unlockingAchievementId;
// an image for the group
private $imageUrl;
// flag, if the group can has records
private $canHaveRecords;
// achievements, that belong to this group
private $achievements;
@@ -49,7 +51,8 @@ SQL;
$r['id'],
$r['name'],
$r['unlockingAchievementId'],
$r['imageUrl']
$r['imageUrl'],
$r['canHaveRecords']
);
$groups[$gid]->getAchievements(['force'=>true]);
}
@@ -61,6 +64,7 @@ SQL;
function getName(){return $this->name;}
function getUnlockingAchievementId(){return $this->unlockingAchievementId;}
function getImageUrl(){return $this->imageUrl;}
function canHaveRecords(){return $this->canHaveRecords;}
/// returns list of achievements
/// - returns the previously loaded achievements
@@ -91,41 +95,87 @@ SQL;
$result[0]['id'],
$result[0]['name'],
$result[0]['unlockingAchievementId'],
$result[0]['imageUrl']
$result[0]['imageUrl'],
$result[0]['canHaveRecords']
);
$this->getAchievements(['force'=>true]);
}
/// Set the member data of the group
function setAchievementGroupData($id, $name, $unlockingAchievementId=null, $imageUrl=null){
function setAchievementGroupData($id, $name, $unlockingAchievementId=null, $imageUrl=null, $canHaveRecords=null){
$this->id = (int)$id;
$this->name = $name;
$this->unlockingAchievementId = ($unlockingAchievementId == null ? null : (int)$unlockingAchievementId);
$this->imageUrl = $imageUrl;
$this->canHaveRecords = (bool)$canHaveRecords;
# echo("bool(".$canHaveRecords.")=".$this->canHaveRecords."\n");
# var_dump($canHaveRecords, $this->canHaveRecords);
}
/// gets all achievements of that user in that group reachedd
/// get the next achievement, the user has to accomplish in that group
function getUsersNextAchievement($userId){
$groupsAchievements = $this->getAchievements();
if(count($this->getAchievements()) < 1)
return null;
$usersAchievementsIds = collectKeysValues(
$this->getUsersAchievements($userId),
'achievementId'
);
$usersNextAchievement = null;
foreach($groupsAchievements as $ga){
if(!in_array($ga['id'], $usersAchievementsIds)){
if($usersNextAchievement == null){
$usersNextAchievement = $ga;
continue;
}
if( $usersNextAchievement['level'] > $ga['level'] ){
$usersNextAchievement = $ga;
};
}
}
return $usersNextAchievement;
}
/// get all achievements, that unlock something
static function getUnlockingAchievements(){
// get all achievements
}
/// gets all achievements a user reached in that group as Array
function getUsersAchievements($userId, $options=[]){
$getAll = $options['getAll']??false;
$query = "";
$query.= "SELECT * FROM `cwsvjudo`.`achievements<=>user` ";
$query.= "WHERE `userId` = :userId";
if(!$getAll)
$query.=" AND `achievementId` = :achievementId";
$query.= ";";
$params[':userId'] = array('value'=>$userId, 'data_type'=>PDO::PARAM_INT);
if(!$getAll)
$params[':achievementId'] = array('value'=>$this->getId(), 'data_type'=>PDO::PARAM_INT);
$result = dbQuery($this->getDbConnection(), $query, $params);
return $result;
}
$getAll = $options['getAll']??false; // ignore restriction to this group
$query = <<<SQL
SELECT *, `cwsvjudo`.`achievements`.`name` AS `achievementName` FROM `cwsvjudo`.`achievements<=>user`
JOIN `cwsvjudo`.`achievements`
ON `cwsvjudo`.`achievements<=>user`.`achievementId` = `cwsvjudo`.`achievements`.`id`
JOIN `cwsvjudo`.`machs_achievementGroups`
ON `cwsvjudo`.`achievements`.`achievementGroupId` = `cwsvjudo`.`machs_achievementGroups`.`id`
WHERE `cwsvjudo`.`achievements<=>user`.`userid` = :userId
SQL;
if(!$getAll){
$query.=" AND `cwsvjudo`.`machs_achievementGroups`.`id` = :achievementGroupId ";
$query.="ORDER BY `cwsvjudo`.`achievements`.`level` DESC";
}
$query.=";";
$params[':userId'] = array('value'=>$userId, 'data_type'=>PDO::PARAM_INT);
if(!$getAll)
$params[':achievementGroupId'] = array('value'=>$this->getId(), 'data_type'=>PDO::PARAM_INT);
$result = dbQuery($this->getDbConnection(), $query, $params);
# var_dump($query);
# var_dump($result);
return $result;
}
/// returns the materialize card html code of the Achievementgroup
///
/// @param $uId id of the user the achievements should be
function asHtmlCard($uId, $options=[]){
// Setting standard options
$noForm = $options['noForm']??true; // for deactivating the give achievement form
$retHtml = "";
$userData = record::getUserData($uId);
$usersAchievements = $this->getUsersAchievements( $uId, ['getAll'=>true] );
$usersAchievementIds=[null];
@@ -135,15 +185,17 @@ return $result;
// If the user hasn't have the needed Achievement
if(!in_array($this->getUnlockingAchievementId(), $usersAchievementIds))
return "";
$records = record::getGroupsRecords(
$this->getId(),
record::birthday2ageClass($userData[0]['gebDatum'])
);
$achievements = $this->getAchievements();
$retHtml .= "<div class=\"col s12 m6 l4 xl3\">";
$retHtml .= "<div class=\"col s12 m6 l4 xl3\">";/// @todo gehört eigentlich nicht mit zur karte
$retHtml .= "<div class=\"card\">";
// image + title
if($this->imageUrl != null){
$retHtml .= "<div class=\"card-image\"><img src=\"".$this->imageUrl."\">";
$retHtml .= "<span class=\"card-title\">".$this->name."</span>";
@@ -152,50 +204,59 @@ return $result;
else
$retHtml .= "<span style=\"padding-left: 1vw;\" class=\"card-title\">".$this->name."</span>";
// content
$retHtml .= "<div class=\"card-content\">";
$retHtml .= "<ul class=\collapsible\">";
foreach($achievements as $a){
if(in_array((int)$a['id'], $usersAchievementIds)){
$retHtml .= "<li>&#10003; ".$a['name'].": ".$a['description'];
$retHtml .= "</li>";
}
else{
$retHtml .= "<li style=\"color:gray\">".$a['name'].": ".$a['description'];
break;
}
// - das nächste achievement
// - als collapsible (list): des users erreichte achievements
$usersAchievements = $this->getUsersAchievements($uId);
$usersNextAchievement = $this->getUsersNextAchievement($uId);
$retHtml .= "<div style=\"font-size:1.5rem; font-weight:200%\">Nächstes Achievement</div>";
$retHtml .= "<ul class=\"collapsible\"><li>";
$retHtml .= "<div class=\"collapsible-header\" >";
if(count($usersAchievements)>0)
$retHtml .= "&#xfe40; ";
$retHtml .= $usersNextAchievement['name'].": ".$usersNextAchievement['description']."</div>";
if(count($usersAchievements)>0){
$retHtml .= "<ul class=\"collapsible-body\" style=\"color:gray\">";
foreach($this->getUsersAchievements($uId) as $a)
$retHtml .= "<li >&#10003; ".$a['achievementName'].": ".$a['description']."</li>";
$retHtml .= "</ul>";// end body
}
$retHtml .= "</li></ul>";// end collapsible
// show the current record
if( validateDate($userData[0]['gebDatum'])){
$retHtml.=record::arrayRecord2htmlCard($records[0], $userData[0], $this->getId(), "li");
}
else{
$retHtml.="<div>Rekorde können erst angezeigt werden, wenn das <a href=./setUserData.php>Geburtsdatum korrekt gesetzt</a> wurde!</div>";
}
$retHtml .= "</ul>";
$retHtml .= "</div>";// end card-content
$retHtml .= "<div class=\"card-action\">";
if(!$noForm){
if( canUserGetAchievementToday( $this->getDbConnection(), $uId) or isUserAdmin($this->getDbConnection(), $_SESSION['user']['userId']) ){
$retHtml .= "<form action=\".\" method=\"POST\">";
$retHtml .= "<input name=\"action\" value=\"giveUserAnAchievement\" type=\"hidden\" />";
$retHtml .= "<input name=\"redirectLocation\" value=\"./#achievementList-".$uId."\" type=\"hidden\" />";
$retHtml .= "<input name=\"userId\" value=\"".$uId."\" type=\"hidden\" />";
$retHtml .= "<input name=\"achievementId\" value=\"".$a['id']."\" type=\"hidden\" />";
$retHtml .= "<input name=\"submit\" type=\"submit\" value=\"".$a['name']." geben\">";
// $retHtml .= "<button class=\"btn\" name=\"submit\" type=\"submit\" >Achievement ".$a['name']." geben</button>";
$retHtml .= "</form>";
}
if($this->canHaveRecords()){
$retHtml .= "<div style=\"font-size:1.5rem; font-weight:200%\">Aktueller Rekord</div>";
if( validateDate($userData[0]['gebDatum'])){
$retHtml.=record::arrayRecord2htmlCardAction($records[0], $userData[0], $this->getId(), "li");
$retHtml.=record::arrayRecord2collapsible($records[0], $userData[0], $this->getId(), $noForm);
}
else{
$retHtml.="<div>Rekorde können erst angezeigt werden, wenn das <a href=./setUserData.php>Geburtsdatum korrekt gesetzt</a> wurde!</div>";
}
}
$retHtml .= "</div>";
$retHtml .= $this->listUnlockableGroups();
$retHtml .= "</div>";// end card-content
if(!$noForm){
$retHtml .= "<div class=\"card-action\">";
$retHtml .= "<form action=\".\" method=\"POST\">";
$retHtml .= "<input name=\"action\" value=\"giveUserAnAchievement\" type=\"hidden\" />";
$retHtml .= "<input name=\"redirectLocation\" value=\"./#achievementList-".$uId."\" type=\"hidden\" />";
$retHtml .= "<input name=\"userId\" value=\"".$uId."\" type=\"hidden\" />";
$retHtml .= "<input name=\"achievementId\" value=\"".$usersNextAchievement['id']."\" type=\"hidden\" />";
if( canUserGetAchievementToday( $this->getDbConnection(), $uId) or isUserAdmin($this->getDbConnection(), $_SESSION['user']['userId']) ){
$retHtml .= "<button style=\"width:100%\" class=\"btn\" name=\"submit\" type=\"submit\" >Achievement ".$usersNextAchievement['name']." geben</button>";
}
else{
$retHtml .= "<button disabled style=\"width:100%\" class=\"btn\" name=\"submit\" type=\"submit\" >Heute wurde schon ein Achievement erreicht!</button>";
}
$retHtml .= "</form>";
$retHtml .= "</div>";// end card-action
}
$retHtml .= "</div>";// end card
$retHtml .= "</div>";// end col
return $retHtml;
@@ -214,6 +275,7 @@ return $result;
$html .= "</form>";
return $html;
}
/// create html code for a for to edit an achievementGroup
function htmlEditAchievementGroupForm(){
$html = "";
@@ -259,15 +321,25 @@ return $result;
/// auto generate the achievements for this group
/// @todo only for empty groups?
function autoAddAchievements($messageTemplate, $from, $to, $step){
if(!empty($this->getAchievements())){
if(count($this->getAchievements()) > 0){
echo("Won't auto-add Achievements to non-empty AchievementGroup!");
var_dump($this->getAchievements());
return;
}
$level = 1;
for ($value = (int)$from; $value <= (int)$to; $value+=(int)$step) {
$name = $this->getName()." ".intToRomanRepresentation($level++);
$description = str_replace("%value%", (string)$value, $messageTemplate);
$this->addAchievement($name, $description, $level);
if($step > 0){
for ($value = (int)$from; $value <= (int)$to; $value+=(int)$step) {
$name = $this->getName()." ".intToRomanRepresentation($level++);
$description = str_replace("%value%", (string)$value, $messageTemplate);
$this->addAchievement($name, $description, $level);
}
}
else{
for ($value = (int)$from; $value >= (int)$to; $value+=(int)$step) {
$name = $this->getName()." ".intToRomanRepresentation($level++);
$description = str_replace("%value%", (string)$value, $messageTemplate);
$this->addAchievement($name, $description, $level);
}
}
}
@@ -283,6 +355,42 @@ return $result;
null
);
}
function usersAchievementList($uId){
$usersAchievements = $this->getUsersAchievements($userId);
$retHtml .= "<ul class=\"collapsible\">";
$retHtml .= "<li>";
$body = "<ul class=\"collapsible-body\">";
foreach($achievements as $a){
if(in_array((int)$a['id'], $usersAchievementIds)){
$body .= "<li >&#10003; ".$a['name'].": ".$a['description'];
$body .= "</li>";
}
else{
$body .= "</ul>";
break;
}
}
$header = "<div class=\"collapsible-header\" style=\"color:gray\">".$a['name'].": ".$a['description']."</div>";
$retHtml .= $header.$body;
$retHtml .= "</li>";
$retHtml .= "</ul>";// end collapsible
}
function listUnlockableGroups(){
$achievementGroups = achievementGroup::getAllAchievementGroups();
$achievements = [];
foreach($this->getAchievements() as $a)
$achievements[(int)$a['id']] = $a;
$retHtml ="<div>";
foreach($achievementGroups as $g){
if(array_key_exists( $g->getUnlockingAchievementId(), $achievements)){
$retHtml .= "<div>Mit Level ".intToRomanRepresentation($achievements[(int)$g->getUnlockingAchievementId()]['level'])." wird ".$g->getName()." freigeschaltet!</div>";
}
}
$retHtml .= "</div>";
return $retHtml;
}
}
/// convert an int number to roman representation
@@ -302,4 +410,12 @@ function intToRomanRepresentation($number){
}
return $returnValue;
}
/// in an array of arrays collect all values with specific key
function collectKeysValues($array, $key){
$values = [];
foreach($array as $a)
$values[]=$a[$key];
return $values;
}
?>

View File

@@ -7,6 +7,7 @@
<?php
if(isUserAdmin($dbConnection, $_SESSION['user']['userId'])){
echo("<li><a href=\"./achievementBuilder.php\">achievementBuilder</a></li>");
echo("<li><a href=\"./playground.php\">playground</a></li>");
}
?>
</ul>

View File

@@ -55,9 +55,11 @@ SQL;
// - a value
// - an age class
public static function getGroupsRecords($groupId, $ageClass=null){
$query = "SELECT *, `cwsvjudo`.`machs_records`.`id` as `recordId` FROM `cwsvjudo`.`machs_records` ";
$query = "SELECT *, `cwsvjudo`.`machs_records`.`id` as `recordId`, `cwsvjudo`.`wkParticipo_Users`.`name` as `userName` FROM `cwsvjudo`.`machs_records` ";
$query.= " JOIN `cwsvjudo`.`wkParticipo_Users` ";
$query.= " ON `cwsvjudo`.`machs_records`.`userId` = `cwsvjudo`.`wkParticipo_Users`.`id` ";
$query.= " JOIN `cwsvjudo`.`machs_achievementGroups` ";
$query.= " ON `cwsvjudo`.`machs_achievementGroups`.`id` = `cwsvjudo`.`machs_records`.`achievementGroupId` ";
$query.= " WHERE `cwsvjudo`.`machs_records`.`achievementGroupId` = :groupId ";
$params =[
'groupId'=>[ 'value'=>$groupId, 'data_type'=>PDO::PARAM_INT ]
@@ -80,8 +82,7 @@ SQL;
}
public static function arrayRecord2htmlCardAction($r, $u, $gid){
// $retHtml.= "<div class=\"card-action\">";
$retHtml.= "<a class=\"waves-effect waves-light btn modal-trigger\" href=\"#reportRecord-user-".$u['id']."-group-".$gid."\">Rekord melden</a>";
$retHtml.= "<a style=\"width:100%;\" class=\"waves-effect waves-light btn modal-trigger\" href=\"#reportRecord-user-".$u['id']."-group-".$gid."\">Rekord melden</a>";
$retHtml.= "<div id=\"reportRecord-user-".$u['id']."-group-".$gid."\" class=\"modal\">";
$retHtml.= "<div class=\"modal-content\">";
$retHtml.= "Rekorde stellen in jeder Achievementgruppe und Altersklasse die Bestleistung unter allen Judoka dar. Rekorde können unabhänging vom eigenen, aktuellen Achievementstand aufgestellt werden.";
@@ -106,7 +107,7 @@ SQL;
$retHtml.= "<input id=\"submit\" style=\"width:100%\" name=\"submit\" type=\"submit\" value=\"Rekord eintragen\">";
}
else{
$retHtml.= "<input disabled=\"true\" id=\"submit\" style=\"width:100%\" name=\"submit\" type=\"submit\" value=\"Rekord melden\">";
$retHtml.= "<input id=\"submit\" style=\"width:100%\" name=\"submit\" type=\"submit\" value=\"Rekord melden\">";
}
$retHtml.= "</form>";
$retHtml.= "</div>";
@@ -118,27 +119,63 @@ SQL;
return $retHtml;
}
/// @param $r record joined with it's holder as associative error
/// @param $r record joined with it's holder as associative array
/// @param $u user for whom the record is shown
public static function arrayRecord2htmlCard($r, $u, $gid, $frameTag="div"){
$retHtml = "<".$frameTag." class=\"card\">";
$retHtml.= "<div class=\"card-content\">";
$retHtml.= "<span class=\"card-title\">Zu schlagender Rekord</span>";
public static function arrayRecord2collapsible($r, $u, $gid, $noForm=true){
$currentRecord = "";
if(empty($r)){
$retHtml.= "Noch kein Rekord für die Altersklasse U".record::birthday2ageClass($u['gebDatum']);
$currentRecord.= "Noch kein Rekord für die Altersklasse U".record::birthday2ageClass($u['gebDatum']);
}
else{
$retHtml.= $r['vorname']." ".$r['name']." mit ".$r['value']." in der U".$r['ageClass'];
$currentRecord.= $r['vorname']." ".$r['userName']." mit ".$r['value']." in der U".$r['ageClass'];
}
$retHtml.= "</div>";
$retHtml.= "</".$frameTag.">";
return $retHtml;
$recordRequest = record::arrayRecord2htmlCardAction($r, $u, $gid, $noForm);
return <<<COLLAPSIBLE
<ul class="collapsible">
<li>
<div class="collapsible-header">&#xfe40; $currentRecord</div>
<div class="collapsible-body"><span>$recordRequest</span></div>
</li>
</ul>
COLLAPSIBLE;
}
/// @param $r record joined with it's holder as associative array
/// @param $u user for whom the record is shown
public static function arrayRecord2htmlCard($r, $u, $gid, $noForm=true, $frameTag="div"){
$group = new achievementGroup;
$group->loadAchievementGroupFromDb($gid);
$retHtml.= "";
var_dump($group->canHaveRecords());
if($group->canHaveRecords()){
$retHtml = "<".$frameTag." class=\"card\">";
$retHtml.= "<div class=\"card-content\">";
$retHtml.= "<span class=\"card-title\">Zu schlagender Rekord</span>";
if(empty($r)){
$retHtml.= "Noch kein Rekord für die Altersklasse U".record::birthday2ageClass($u['gebDatum']);
}
else{
// $retHtml.=record::arrayRecord2collapsible($records[0], $userData[0], $this->getId(), $noForm);
$retHtml.=record::arrayRecord2collapsible($r, $u, $gid, $noForm);
//$retHtml.= $r['vorname']." ".$r['name']." mit ".$r['value']." in der U".$r['ageClass'];
}
$retHtml.= "</div>";//end card-content
// if(!$noForm){
// $retHtml.= record::arrayRecord2htmlCardAction($r, $u, $gid, $noForm);
// }
$retHtml.= "</".$frameTag.">";
}
return $retHtml;
}
public static function birthday2ageClass($birthdateString){
$birthDate = DateTime::createFromFormat("Y-m-d", $birthdateString);
$birthYear= (int)$birthDate->format("Y");