Newsletter KW 30 and the weeks before

This commit is contained in:
marko
2023-07-29 16:55:49 +02:00
parent 2e7c5f86e5
commit 662830460c
42 changed files with 830 additions and 256 deletions

View File

@@ -38,7 +38,7 @@ class dbConnector
if (empty($someOptions['dontFetch'])) {
$someOptions['dontFetch'] = false;
}
$ignoreErrors = $someOptions['ignoreErrors'] ?? false;
/// @toDo: Bisher wird nur die Rückgabe konvertiert. Eigentlich muss

View File

@@ -122,7 +122,7 @@ class Event
'<dt>Einschreibefrist</dt>' .
'<dd>' . $this->deadline->format('Y-m-d') . '</dd>' .
'<dt>Altersklassen</dt>' .
'<dd>' . $this->shiai->getAgeClasses() . '</dd>' .
'<dd>' . $this->shiai()->getHtmlDescriptiveAgeClasses() . '</dd>' .
'</dl>' .
'</div>' .
'</div>';
@@ -135,7 +135,7 @@ class Event
'<tr>' .
'<td>' . $this->date->format('Y-m-d') . '</td>' .
'<td><a href="/participo/events#' . $this->id . '" >' . $shiai->getHtmlName() . '</a></td>' .
'<td>' . $shiai->getAgeClasses() . '</td>' .
'<td>' . $shiai->getHtmlDescriptiveAgeClasses() . '</td>' .
'<td><a class="waves-effect waves-light btn modal-trigger" href="#event-modal-' . $this->id . '"><i class="material-icons">zoom_in</i></a></td>' .
'</tr>';
}
@@ -148,7 +148,6 @@ class Event
. $this->shiai->getHtml()
. $this->getHtmlStarterStatistic()
. $this->getHtmlStarterList();
$kids = participo::getKids();
$modal .= '<div class="row">';
$modal .= '<div class="s12">Deadline zum Eintragen: ' . $this->deadline->format('Y-m-d') . '</div>';
@@ -157,9 +156,17 @@ class Event
(isset($this->deadline) && ($today <= $this->deadline))
|| participo::isUserAdmin($userData['id'])
) {
$kids = participo::getKids();
foreach ($kids as $k) {
$modal .= $this->getHtmlAddStarterForm($k, ['returnToUrl' => '/participo/events#' . $this->id]);
}
// foreach ($this->shiai()->ageGroups() as $ageClass => $starterList) {
// // $modal .= '<h3>' . $ageClass ?? 'keiner Altersklasse zugeordnet' . '</h3>';
// foreach ($starterList as $starter) {
// $modal .= $this->getHtmlAddStarterForm($k, ['returnToUrl' => '/participo/events#' . $this->id]);
// }
// }
} else {
$modal .= '<div>Es ist leider zu spät noch jemanden einzutragen!</div>';
}
@@ -175,6 +182,7 @@ class Event
echo($modal);
}
/** Get the list of starters as html list */
public function getHtmlStarterList()
{
$listOfStarter = $this->getStarter();

View File

@@ -10,7 +10,39 @@ class participo
{
private static $db = null;
private static $message = ['error' => null, 'success' => null, 'notice' => null];
/** id of session user
*
* Session user describes the currently logged in user
*
* @var int>0
*/
private static $userId = null;
private static $sessionUser = null;
/** get session users id
*
* if not set so far it is loaded from the session cookies
*
* @return int id of session user
*/
public static function getSessionUserId()
{
if (!isset(self::$userId)) {
self::$userId = $_SESSION['user']['userId'] ?? null;
}
self::$userId = filterId(self::$userId);
return self::$userId;
}
/** lazy loading of the session user */
public static function sessionUser(bool $forceLoading = true)
{
if (is_null($sessionUser) || $forceLoading) {
self::$sessionUser = User::loadFromDb(self::getSessionUserId());
}
return self::$sessionUser;
}
/** Returns the current login status
*
@@ -23,15 +55,6 @@ class participo
return (isset($_SESSION) && array_key_exists('login', $_SESSION) && $_SESSION['login'] == true);
}
public static function getSessionUserId()
{
$userId = null;
if (isset($_SESSION) && array_key_exists('user', $_SESSION) && array_key_exists('userId', $_SESSION['user'])) {
$userId = $_SESSION['user']['userId'];
}
return $userId;
}
/** Remove all login data from the session data
*
* @return void
@@ -175,6 +198,11 @@ class participo
return self::hasUserAttribute($userId, 'isAdmin');
}
public static function getUserId()
{
}
/** get current logged in users kids */
public static function getKids($userId = null)
{
$userId = $userId ?? $_SESSION['user']['userId'] ?? null;
@@ -412,10 +440,10 @@ function lastLoginTable($jsonFileName = 'lastLogins.json')
'<tbody>';
foreach ($lastLoginRows as $userName => $lastLogin) {
$lastLoginsTable .=
'<tr><td>' . $userName . '</td><td>' . $lastLogin . '</td></tr>';
'<tr><td>' . $userName . '</td><td>' . $lastLogin . '</td></tr>';
}
$lastLoginsTable .=
'</tbody>'.
'</tbody>' .
'</table>';
return $lastLoginsTable;
}
@@ -568,6 +596,19 @@ function getHtmlSquareDate($date = null)
. '</div>';
}
/** filter_var for a pos int
*
* check for int; null is default; only values > 0 are excepted
*
* @param [type] $id
* @retval int>0 filtered id
* @retval null sth. went wrong
* */
function filterPosInt($id)
{
return filter_var($id, FILTER_VALIDATE_INT, ['options' => ['default' => null, 'min_range' => 1]]);
}
/** filter_var for a (db)id
*
* check for valid id; null is default; only values > 0 are excepted
@@ -578,11 +619,11 @@ function getHtmlSquareDate($date = null)
*/
function filterId($id)
{
return filter_var($id, FILTER_VALIDATE_INT, ['options' => ['default' => null, 'min_range' => 1]]);
return filterPosInt($id);
}
/** filter a variable as count
*
*
* - count means a non negative integer
* - helper function to stay DRY
*
@@ -590,7 +631,7 @@ function filterId($id)
* @param integer $min
* @return integer the input variable as integer >= 0
*/
function filterCount($variable, int $min = 0){
function filterCount($variable, int $min = 0)
{
return filter_var($variable, FILTER_VALIDATE_INT, ['options' => ['default' => null, 'min_range' => 1]]);
}

View File

@@ -21,7 +21,7 @@ class Shiai
$this->id = (int) $id;
$this->date = DateTime::createFromFormat('Y-m-d', $date);
$this->name = $name;
$this->ageclasses = $ageclasses;
$this->ageclasses = $ageclasses ? self::akListString2jgArray($ageclasses) : null;
$this->place = $place;
$this->announcementUrl = $announcementUrl;
$this->routeUrl = $routeUrl;
@@ -98,12 +98,151 @@ class Shiai
$retHtml =
'<div>' .
'<h3>' . $this->getHtmlName() . '</h3>' .
'<dl>'.
'<dt>Datum:</dt><dd>' . $this->getHtmlDate() . '</dd>' .
'<dt>Altersklassen</dt><dd>' . $this->getAgeClasses() . '</dd>' .
'<dl>' .
'<dt>Datum</dt><dd>' . $this->getHtmlDate() . '</dd>' .
'<dt>Altersklassen</dt><dd>' . $this->getHtmlDescriptiveAgeClasses() . '</dd>' .
'<dt>Ort</dt><dd>' . $this->getPlace() . '</dd>' .
'</dl>' .
'</div>';
return $retHtml;
}
public function getHtmlDescriptiveAgeClasses()
{
$retList = [];
foreach ($this->ageclasses as $ageclass => $years) {
$htmlFragment = $ageclass;
$years = $years[0];
if ($years[0] || $years[1]) {
$htmlFragment .= '(';
if ($years[1]) {
$htmlFragment .= strval($years[0]) . '-' . strval($years[1]);
} else {
$htmlFragment .= '<=' . strval($years[0]);
}
$htmlFragment .= ')';
}
$retList[] = $htmlFragment;
}
return implode(', ', $retList);
}
/** convert a list of age class formatted strings into a list of intervals of years
*
* @param string $akListString
* @param int $year
* @return list[array(int,int)] list of tupels with lower/upper bound in date year of the age classes
*/
private static function akListString2jgArray(string $akListString, int $year = null)
{
$year = filterPosInt($year) ?? filterPosInt((new DateTime)->format('Y'));
$ret = [];
foreach (explode(' ', $akListString) as $ak) {
$ret[$ak] = self::akString2jgIntervall($ak, $year);
}
return $ret;
}
/** convert age class from formatted string to interval of years
*
* @param [string] $akString
* @param [type] $year
* @return array(int,int) [x,y] with x the lower bound and y the upper bound of the age class in years. Both bounds are still included in the interval.
*/
private static function akString2jgIntervall(string $akString, int $year /*= null*/)
{
// input sanitation
$year = filterPosInt($year) ?? filterPosInt((new DateTime)->format('Y'));
$ret = [null, null];
// Matching against the different age class formats
// - ..Ux
// - Jg.x-y
// Case Ux
$akUmatchString = '/(.*)U(.*)/';
$matches = [];
preg_match($akUmatchString, $akString, $matches);
// The found match should cover the whole string. Otherwise it isn't applicable.
if ($matches[0] == $akString) {
// The x in Ux should be a positive integer.
$ageLimit = filterPosInt($matches[2]);
if ($ageLimit) {
$ret[0] = $year - $ageLimit + 1;
// lowering the lower bound according to the modifiers
if ($matches[1] == '') {
$ret[1] = $year - $ageLimit + 2;
} elseif ($matches[1] == '-') {
$ret[1] = $year - $ageLimit + 3;
} elseif ($matches[1] == '--') {
$ret[1] = $year - $ageLimit + 4;
} elseif (in_array($matches[1], ['<=', '&le;', '&#x2264;', '&#8804;', '≤'])) {
$ret[1] = $year;
}
return $ret;
}
}
// Case Jg.x-y
$akUmatchString = "/Jg\.(.*)\-(.*)/";
$matches = [];
preg_match($akUmatchString, $akString, $matches);
// The found match should cover the whole string. Otherwise it isn't applicable.
if ($matches[0] == $akString) {
$ret[0] = filterPosInt($matches[1]);
$ret[1] = filterPosInt($matches[2]);
return $ret;
}
return $ret;
}
/** grouping users kids by ageGroups
*
* @return array(ageGroup => list(users in ageGroup))
*/
public function ageGroups()
{
$kids = participo::getKids();
return self::ageClassGrouping($this->ageclasses, $kids);
}
/** grouping users by given age class
*
* @param array $ageClassList as array string representation of age class => [lower year bound, upper year bound]
* @param array $starterList list of starter (User)
* @return array of string representation of age class => array of user in this class
*/
private static function ageClassGrouping(array $ageClassList, array $starterList)
{
$grouping = [];
foreach ($ageClassList as $ageClass => $yearBoundaries) {
$grouping[$ageClass] = [];
}
$grouping[null] = [];
foreach ($starterList as $starter) {
$startersAgeClass = $starter->yearOfBirth() ? self::getAgeClassFromYear($starter->yearOfBirth(), $ageClassList) : null;
array_push($grouping[$startersAgeClass], $starter);
}
return $grouping;
}
private static function getAgeClassFromYear(int $year, array $ageClassList)
{
foreach ($ageClassList as $ageClass => $yearBoundaries) {
if (($yearBoundaries[0] <= $year) && ($year <= $yearBoundaries[1])) {
return $ageClass;
}
}
return null;
}
} // end class shiai

View File

@@ -10,51 +10,66 @@ class User
* @todo Document parameter
* @todo Input sanitation
*/
public function __construct($id, $loginName, $name, $firstName, $dateOfBirth=null, $eMail=null, $config=null, $pwHash=null)
public function __construct($id, $loginName, $name, $firstName, $dateOfBirth = null, $eMail = null, $config = null, $pwHash = null)
{
$this->id = filterId($id);
$this->loginName = $loginName;
$this->name = $name;
$this->firstName = $firstName;
$this->dateOfBirth = ($dateOfBirth != null) ? DateTime::createFromFormat('Y-m-d', $dateOfBirth) : null;
$this->eMail = ($eMail!=null) ? filter_var($eMail, FILTER_VALIDATE_EMAIL,['options'=>['default'=>null]]):null;
$this->eMail = ($eMail != null) ? filter_var($eMail, FILTER_VALIDATE_EMAIL, ['options' => ['default' => null]]) : null;
$this->config = $config;
$this->pwHash = $pwHash;
}
/** return users year of birth as int
*
* @retval int>=0 on success,
* @retval null failure
*/
public function yearOfBirth()
{
if (isset($this->dateOfBirth)) {
return filterPosInt($this->dateOfBirth->format('Y'));
}
return null;
}
////
// dbInterface
////
public function addToDb(){
public function addToDb()
{
// if the user has an Id set it has to come from the Db. Hence don't add an User that is already added.
if(isset($this->id) || !participo::isUserAdmin()){
if (isset($this->id) || !participo::isUserAdmin()) {
return;
}
$this->id = self::dbInsert(
$this->loginName
, $this->name
, $this->firstName
, (isset($this->dateOfBirth))?($this->dateOfBirth->format('Y-m-d')):null
, $this->eMail
, $this->config
, $this->pwHash
$this->loginName,
$this->name,
$this->firstName,
(isset($this->dateOfBirth)) ? ($this->dateOfBirth->format('Y-m-d')) : null,
$this->eMail,
$this->config,
$this->pwHash
);
return $this->id;
}
private static function dbInsert($loginName, $name, $firstName, $dateOfBirth=null, $eMail=null, $config=null, $pwHash=null){
$query = 'INSERT INTO `'.self::$tableName.'` '
.'(loginName, name, vorname, gebDatum, eMail, config, pwHash) '
.' VALUES (:loginName, :name, :vorname, :gebDatum, :eMail, :config, :pwHash);';
private static function dbInsert($loginName, $name, $firstName, $dateOfBirth = null, $eMail = null, $config = null, $pwHash = null)
{
$query = 'INSERT INTO `' . self::$tableName . '` '
. '(loginName, name, vorname, gebDatum, eMail, config, pwHash) '
. ' VALUES (:loginName, :name, :vorname, :gebDatum, :eMail, :config, :pwHash);';
$params = [
':loginName'=>['value'=>$loginName, 'data_type' => self::$dbColumns['loginName']],
':name'=>['value'=>$name, 'data_type' => self::$dbColumns['name']],
':vorname'=>['value'=>$firstName, 'data_type' => self::$dbColumns['vorname']],
':gebDatum'=>['value'=>$dateOfBirth, 'data_type' => self::$dbColumns['gebDatum']],
':eMail'=>['value'=>$eMail, 'data_type' => self::$dbColumns['eMail']],
':config'=>['value'=>$config, 'data_type' => self::$dbColumns['config']],
':pwHash'=>['value'=>$pwHash, 'data_type' => self::$dbColumns['pwHash']],
':loginName' => ['value' => $loginName, 'data_type' => self::$dbColumns['loginName']],
':name' => ['value' => $name, 'data_type' => self::$dbColumns['name']],
':vorname' => ['value' => $firstName, 'data_type' => self::$dbColumns['vorname']],
':gebDatum' => ['value' => $dateOfBirth, 'data_type' => self::$dbColumns['gebDatum']],
':eMail' => ['value' => $eMail, 'data_type' => self::$dbColumns['eMail']],
':config' => ['value' => $config, 'data_type' => self::$dbColumns['config']],
':pwHash' => ['value' => $pwHash, 'data_type' => self::$dbColumns['pwHash']],
];
$response = dbConnector::query($query, $params);
return dbConnector::getLastInsertId();
@@ -81,7 +96,6 @@ class User
'pwHash' => PDO::PARAM_STR
];
////
// html interface
////
@@ -89,26 +103,26 @@ class User
public static function getHtmlFormAddUser($options = [])
{
$returnToUrl = $options['returnToUrl'] ?? urlencode(getCurPagesUrl());
$formClass = isset($options['formClass']) ? 'class="'.$options['formClass'].'"' : '';
$formClass = isset($options['formClass']) ? 'class="' . $options['formClass'] . '"' : '';
$form =
'<form ' . $formClass . ' action="api.user.add.php" method="post">'
. '<input type="hidden" name="returnToUrl" id="returnToUrl" value="' . $returnToUrl . '" >'
.'<div><label for="loginName">Benutzername</label> <input type="text" name="loginName" id="loginName"></div>'
.'<div><label for="name">Nachname</label> <input type="text" name="name" id="name"></div>'
.'<div><label for="firstName">Vorname</label> <input type="text" name="firstName" id="firstName"></div>'
.'<div><label for="dateOfBirth">Geb.Datum</label> <input type="text" name="dateOfBirth" id="dateOfBirth"></div>'
.'<div><label for="eMail">eMail</label> <input type="text" name="eMail" id="eMail"></div>'
. '<div><label for="loginName">Benutzername</label> <input type="text" name="loginName" id="loginName"></div>'
. '<div><label for="name">Nachname</label> <input type="text" name="name" id="name"></div>'
. '<div><label for="firstName">Vorname</label> <input type="text" name="firstName" id="firstName"></div>'
. '<div><label for="dateOfBirth">Geb.Datum</label> <input type="text" name="dateOfBirth" id="dateOfBirth"></div>'
. '<div><label for="eMail">eMail</label> <input type="text" name="eMail" id="eMail"></div>'
. '<button class="btn" type="submit" name="submit">erstellen</button>'
. '</form>';
return $form;
}
public static function htmlFormAddUser($options = []){
public static function htmlFormAddUser($options = [])
{
echo(self::getHtmlFormAddUser($options));
}
// member variables
private $id;
private $loginName;
@@ -119,6 +133,49 @@ class User
private $config;
private $pwHash;
// database member data
/** List of ids of the users kids */
private $kidIds = null;
/** List of users kids */
private $kids = null;
public function kidIds(bool $forceLoading = false)
{
if (is_null($this->kidIds) || $forceLoading) {
$this->kidIds = self::getKidIds($id);
}
return self::$kidIds;
}
public function kids(bool $forceLoading = false)
{
if (is_null($this->kids) || $forceLoading) {
$this->kids = participo::getKids($this->id);
}
return $this->kids;
}
private static function getKidIds(int $id)
{
$response = dbConnector::query(
'SELECT * FROM `wkParticipo_Users` WHERE `' . $name . '` = :' . $name,
[$name => ['value' => $value, 'data_type' => self::$dbColumns[$name]]]
);
$query = <<<SQL
SELECT *
FROM `wkParticipo_Users`
JOIN `vormundschaft`
ON `wkParticipo_Users`.`id` = `vormundschaft`.`kidId`
WHERE `vormundschaft`.`userId` = :userId;
SQL;
$params = [
':userId' => ['value' => $userId, 'data_type' => PDO::PARAM_INT]
];
$response = dbConnector::query($query, $params);
return $response;
}
/** Export the User data into an associative array
*
* @return array associative array representing the user
@@ -192,7 +249,9 @@ class User
}
return new User(
$member[$columnMappings['id']] ?? null,
$member[
$columnMappings['id']
] ?? null,
$member[$columnMappings['loginName']] ?? null,
$member[$columnMappings['name']] ?? null,
$member[$columnMappings['vorname']] ?? null,
@@ -244,7 +303,6 @@ class User
if (count($response) != 1) {
return null;
}
return User::fromDbArray($response[0]);
}
}