460 lines
17 KiB
PHP
460 lines
17 KiB
PHP
<?php
|
|
require_once('./lib/db.php');
|
|
|
|
|
|
// A series of achievements
|
|
class achievementGroup{
|
|
// data from the achievements group table
|
|
// id of the group
|
|
private $id;
|
|
// name of the group
|
|
private $name;
|
|
// Achievement, that unlocks the group
|
|
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;
|
|
|
|
// pointer to the db that shall be used for queries
|
|
private static $db=null;
|
|
// name of the table
|
|
// private static $tableName = "`cwsvjudo`.`machs_achievementGroups`";
|
|
|
|
// set the dbConnection (just setting, no establishing)
|
|
public static function setDbConnection($dbConnection){
|
|
if($dbConnection instanceof PDO)
|
|
self::$db = $dbConnection;
|
|
else
|
|
self::$db = null;
|
|
return;
|
|
}
|
|
// get the db pointer
|
|
public static function getDbConnection(){
|
|
return self::$db;
|
|
}
|
|
|
|
/// Returns an array of all Achievementgroups
|
|
static function getAllAchievementGroups(){
|
|
$query = <<<SQL
|
|
SELECT * FROM `cwsvjudo`.`machs_achievementGroups`;
|
|
SQL;
|
|
$result = dbQuery(self::$db, $query);
|
|
$groups = [];
|
|
foreach($result as $r){
|
|
$gid = (int)$r['id'];
|
|
$groups[$gid] = new achievementGroup;
|
|
$groups[$gid]->setAchievementGroupData(
|
|
$r['id'],
|
|
$r['name'],
|
|
$r['unlockingAchievementId'],
|
|
$r['imageUrl'],
|
|
$r['canHaveRecords']
|
|
);
|
|
$groups[$gid]->getAchievements(['force'=>true]);
|
|
}
|
|
return $groups;
|
|
}
|
|
|
|
//getter functions for the (primitive) member variables
|
|
function getId(){return $this->id;}
|
|
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
|
|
/// - reloads them if null or forced
|
|
function getAchievements($options=[]){
|
|
// standards for Options:
|
|
$force = $options['force']??false; // load the achievements from the db even if ther already are some in the group->achievements member
|
|
if(($this->achievements == null) or ($force)){
|
|
$query = <<<SQL
|
|
SELECT * FROM `achievements`
|
|
WHERE `achievementGroupId`=:groupId;
|
|
SQL;
|
|
$params = [':groupId'=>['value'=>$this->id, 'data_type'=>PDO::PARAM_INT]];
|
|
$this->achievements = dbQuery(self::$db, $query, $params);
|
|
}
|
|
return $this->achievements;
|
|
} // end getAchievements
|
|
|
|
/// Load the achievementgroup $id from the db (into this)
|
|
function loadAchievementGroupFromDb($id){
|
|
$query = <<<SQL
|
|
SELECT * FROM `cwsvjudo`.`machs_achievementGroups` WHERE `id` = :id;
|
|
SQL;
|
|
$params = [':id'=>['value'=>$id, 'data_type'=>PDO::PARAM_INT]];
|
|
$result = dbQuery(self::$db, $query, $params);
|
|
|
|
$this->setAchievementGroupData(
|
|
$result[0]['id'],
|
|
$result[0]['name'],
|
|
$result[0]['unlockingAchievementId'],
|
|
$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, $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);
|
|
}
|
|
|
|
/// 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; // 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];
|
|
foreach($usersAchievements as $a){
|
|
$usersAchievementIds[]=(int)$a['achievementId'];
|
|
}
|
|
// 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\">";/// @todo gehört eigentlich nicht mit zur karte
|
|
$retHtml .= "<div class=\"card\">";
|
|
|
|
// image + title
|
|
if($this->imageUrl != null){
|
|
$retHtml .= "<div class=\"card-image\">";
|
|
$ext = pathinfo($this->imageUrl, PATHINFO_EXTENSION);
|
|
$ret."<div>".$this->imageUrl."</div>";
|
|
$ret."<div>".$ext."</div>";
|
|
switch($ext){
|
|
case "webm":
|
|
$retHtml .= "<video controls preload=\"none\"><source src=\"".$this->imageUrl."\" type=\"video/webm\">Video tag is not supported in this browser.</video>";
|
|
// $retHtml .= videoJsFrame(array('url'=>$this->imageUrl));
|
|
// $retHtml .= "<div>Hier sollte ein Video sein!</div>";
|
|
break;
|
|
default:
|
|
$retHtml .= "<img src=\"".$this->imageUrl."\">";
|
|
break;
|
|
};
|
|
$retHtml .= "<span class=\"card-title\">".$this->name."</span>";
|
|
$retHtml .= "</div>";
|
|
}
|
|
else
|
|
$retHtml .= "<span style=\"padding-left: 1vw;\" class=\"card-title\">".$this->name."</span>";
|
|
|
|
// content
|
|
$retHtml .= "<div class=\"card-content\">";
|
|
// - 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 .= "﹀ ";
|
|
$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 >✓ ".$a['achievementName'].": ".$a['description']."</li>";
|
|
$retHtml .= "</ul>";// end body
|
|
}
|
|
$retHtml .= "</li></ul>";// end collapsible
|
|
|
|
// show the current record
|
|
if($this->canHaveRecords()){
|
|
$retHtml .= "<div style=\"font-size:1.5rem; font-weight:200%\">Aktueller Rekord</div>";
|
|
if( validateDate($userData[0]['gebDatum'])){
|
|
$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 .= $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\" />";
|
|
//! warning for admins, that the user already had an achievement today
|
|
if( !canUserGetAchievementToday( $this->getDbConnection(), $uId) and isUserAdmin($this->getDbConnection(), $_SESSION['user']['userId']) ){
|
|
$retHtml .= "<div class=\"pink\" >Heute wurde bereits eine Achievement erreicht!</div>";
|
|
}
|
|
//! Only one achievements shall be given daily! Admins can overrule this!
|
|
if( canUserGetAchievementToday( $this->getDbConnection(), $uId) or isUserAdmin($this->getDbConnection(), $_SESSION['user']['userId']) ){
|
|
$retHtml .= "<button style=\"width:100%\" class=\"btn\" name=\"submit\" type=\"submit\" >Achievement 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;
|
|
}// end asHtmlCard
|
|
|
|
/// create html code for a for to add an achievementGroup
|
|
static function htmlAddAchievementGroupForm(){
|
|
$html = "";
|
|
$html .= "<form action=\".\" method=\"POST\">";
|
|
$html .= "<input name=\"action\" type=\"hidden\" value=\"addAchievementGroup\" />";
|
|
$html .= "<input name=\"redirectLocation\" type=\"hidden\" value=\"achievementBuilder.php\" />";
|
|
$html .= "<input name=\"name\" type=\"text\" placeholder=\"name\"/>";
|
|
$html .= "<input name=\"unlockingAchievementId\" type=\"text\" placeholder=\"unlockingAchievementId\"/>";
|
|
$html .= "<input name=\"imageUrl\" type=\"text\" placeholder=\"imageUrl\"/>";
|
|
$html .= "<input type=\"submit\"/>";
|
|
$html .= "</form>";
|
|
return $html;
|
|
}
|
|
|
|
/// create html code for a for to edit an achievementGroup
|
|
function htmlEditAchievementGroupForm(){
|
|
$html = "";
|
|
$html .= "Edit ".$this->getName();
|
|
$html .= "<form action=\".\" method=\"POST\">";
|
|
$html .= "<input name=\"action\" type=\"hidden\" value=\"editAchievementGroup\" />";
|
|
$html .= "<input name=\"redirectLocation\" type=\"hidden\" value=\"achievementBuilder.php\" />";
|
|
$html .= "<input name=\"id\" type=\"hidden\" value=\"".$this->getId()."\"/>";
|
|
$html .= "<label for\"name\">name</label>";
|
|
$html .= "<input name=\"name\" type=\"text\" value=\"".$this->getName()."\"/>";
|
|
$html .= "<label for\"name\">unlockingAchievementId</label>";
|
|
$html .= "<input name=\"unlockingAchievementId\" type=\"text\" value=\"".$this->getUnlockingAchievementId()."\"/>";
|
|
$html .= "<label for\"name\">imageUrl</label>";
|
|
$html .= "<input name=\"imageUrl\" type=\"text\" value=\"".$this->getImageUrl()."\"/>";
|
|
$html .= "<input type=\"submit\"/>";
|
|
$html .= "</form>";
|
|
return $html;
|
|
}
|
|
|
|
static function htmlAutoAddAchievementsForm($achievementGroupId, $messageTemplate=null, $from=null, $to=null, $step=null){
|
|
$html = "";
|
|
$html .= "<form action=\".\" method=\"POST\">";
|
|
|
|
$html .= "<input name=\"action\" type=\"hidden\" value=\"autoAddAchievements\" />";
|
|
$html .= "<input name=\"redirectLocation\" type=\"hidden\" value=\"achievementBuilder.php\" />";
|
|
$html .= "<input name=\"achievementGroupId\" type=\"hidden\" value=\"".$achievementGroupId."\"/>";
|
|
|
|
$html .= "<label for=\"messageTemplate\">messageTemplate ('%value%' is Placeholder for the value that goes from fromValue to toValue in step)</label>";
|
|
$html .= "<input style=\"width:100%;display:block;\" name=\"messageTemplate\" type=\"textarea\" value=\"".$messageTemplate."\"/>";
|
|
|
|
$html .= "<label for\"from\">fromValue</label>";
|
|
$html .= "<input name=\"from\" type=\"text\" value=\"".$from."\"/>";
|
|
$html .= "<label for\"to\">toValue</label>";
|
|
$html .= "<input name=\"to\" type=\"text\" value=\"".$to."\"/>";
|
|
$html .= "<label for\"step\">step</label>";
|
|
$html .= "<input name=\"step\" type=\"text\" value=\"".$step."\"/>";
|
|
|
|
$html .= "<input type=\"submit\" value=\"Auto Add Achievements\" />";
|
|
$html .= "</form>";
|
|
return $html;
|
|
}
|
|
|
|
/// auto generate the achievements for this group
|
|
/// @todo only for empty groups?
|
|
function autoAddAchievements($messageTemplate, $from, $to, $step){
|
|
if(count($this->getAchievements()) > 0){
|
|
echo("Won't auto-add Achievements to non-empty AchievementGroup!");
|
|
var_dump($this->getAchievements());
|
|
return;
|
|
}
|
|
$level = 1;
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
// adds an achievement to the group (in the db!)
|
|
function addAchievement($name, $description, $level, $rootId=null){
|
|
addAchievement(
|
|
$this->getDbConnection(),
|
|
$name,
|
|
$rootId,
|
|
$this->getId(),
|
|
$level,
|
|
$description,
|
|
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 >✓ ".$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
|
|
/// @param int $number
|
|
/// @return string
|
|
function intToRomanRepresentation($number){
|
|
$map = array('M' => 1000, 'CM' => 900, 'D' => 500, 'CD' => 400, 'C' => 100, 'XC' => 90, 'L' => 50, 'XL' => 40, 'X' => 10, 'IX' => 9, 'V' => 5, 'IV' => 4, 'I' => 1);
|
|
$returnValue = '';
|
|
while ($number > 0) {
|
|
foreach ($map as $roman => $int) {
|
|
if($number >= $int) {
|
|
$number -= $int;
|
|
$returnValue .= $roman;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
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;
|
|
}
|
|
|
|
//! create the <video>Tag for videoJs
|
|
function videoJsFrame($item){
|
|
return "<video "
|
|
."id=\"".str_replace("/", "-", $item['url'])."\" "
|
|
."class=\"video-js\" "
|
|
."controls "
|
|
."preload=\"none\" "
|
|
// ."poster=\"//vjs.zencdn.net/v/oceans.png\""
|
|
."data-setup='{}' "
|
|
.">"
|
|
."<source src=\"".$item['url']."\" type=\"video/webm\">"//</source>"
|
|
."<p class=\"vjs-no-js\">"
|
|
."To view this video please enable JavaScript, and consider upgrading to a web browser that "
|
|
."<a href=\"https://videojs.com/html5-video-support/\" target=\"_blank\">"
|
|
."supports HTML5 video"
|
|
."</a>"
|
|
."</p>"
|
|
."</video>";
|
|
}
|
|
?>
|