Files
cwsvJudo/homepage/participo/lib/participoLib/event.php
marko f28fa7b51b WIP: bring participo back - consistent use of bootstrap - formatting -
phpstan level 0 error free - fixes for kyu subpage - move mams into
participo framework - remove legacy `lib/db.php` usage - add attributer
admin function - add newsposter - fixing apiKey creation
2025-11-19 12:24:38 +01:00

501 lines
16 KiB
PHP

<?php
require_once "participoLib/participo.php";
require_once "participoLib/shiai.php";
/** Framework for a event
*/
class Event
{
// members in the db
private $id = null; //< unique id of the event in the db
private $date = null; //< date for the event (@todo ranges?)
private $shiaiId = null; //< unique id of the shiai in the db (if appropriate)
private $deadline = null; //< until when one can register for the event
private $remarks = null; //< remarks to the event (special rules) or a json object for missing data (e.g. non-shiai events)
// linked data
private $shiai = null; //< a place to load the linked shiai to (if loaded)
/** constructor
*
* @param int $id id in the database
* @param string $date date of the event as string in the format "YYYY-MM-DD"
* @param int $shiaiId id of the linked shiai or null if not appropriate
* @param string $deadline deadline for sign ins in the format "YYYY-MM-DD"
* @param string $remarks (json formatted) string with meta information
*/
public function __construct($id, $date, $shiaiId, $deadline, $remarks)
{
//! @todo InputValidation
$this->id = filterId($id);
$this->date = DateTime::createFromFormat("Y-m-d", $date);
$this->shiaiId = filterId($shiaiId);
$this->deadline = DateTime::createFromFormat("Y-m-d", $deadline);
$this->remarks = $remarks;
}
// Getter
/** Getter for the id
*
* @return (int) Id of the event
*/
public function getId()
{
return $this->id;
}
/** Getter for the date
*
* @return DateTime date of the event
*/
public function getDate()
{
return $this->date;
}
/** Getter for the shiaiId
*
* @return int>0 id for the shiai in the db
*/
public function getShiaiId()
{
return $this->shiaiId;
}
/** Getter for the deadline
*
* @return DateTime deadline for the event
*/
public function getDeadLine()
{
return $this->deadline;
}
/** Getter for the linked Shiai
*
* - lazy loading: only load if not already loaded (overridable by the $forceLoading param)
*
* @param boolean $forceLoading if true, the loading is enforced even if there already is a shiai linked
*
* @return Shiai reference to the linked Shiai
*/
public function shiai($forceLoading = false): Shiai
{
// We want to load if it isn't loaded yet or we want to enforce it. But in either case we need an id to load
if ((!isset($this->shiai) || $forceLoading) && isset($this->shiaiId)) {
$this->shiai = Shiai::loadFromDb($this->shiaiId);
}
if ($this->shiai == null) {
$this->shiai = Shiai::fromDbArray(
json_decode($this->remarks, true),
);
}
return $this->shiai;
}
/** load the Event by id from the db
*
* - Frontend function: sanitizes the input and calls the backend function
*
* @param integer>0 $id id of the Event to load from the data base
* @return Event Event from the db with this id, null in case the Event couldn't be loaded
*/
public static function loadFromDb($id)
{
$id = filterId($id);
if ($id) {
return self::loadFromDbById($id);
}
return null;
}
/**
* loads an event from the db by id
*
* - Backend function, input is supposed to be sanitized
*
* @param integer>0 $id sanitized id of the event to load
* @return Event Event from the db with this id, null in case the Event couldn't be loaded
*/
private static function loadFromDbById(int $id)
{
$query =
"SELECT * FROM `cwsvjudo_main`.`wkParticipo_Events` WHERE `id` = :id;";
$params = [":id" => ["value" => $id, "data_type" => PDO::PARAM_INT]];
$response = dbConnector::query($query, $params);
// ids are considered unique. so every other count then 1 is treated as error to prevent unprivileged access
if (count($response) != 1) {
return null;
}
return self::fromDbArray($response[0]);
}
public function htmlDate($format = "Y-m-d")
{
return $this->date->format($format);
}
public function htmlDeadLine($format = "Y-m-d")
{
return $this->deadline->format($format);
}
/** Representation of an event as (materializeCss) card
*
* @return string string with the html code of the event
*/
public function asHtmlCard()
{
$shiai = $this->shiai();
return '<div class="card blue-grey darken-1">' .
'<div class="card-content white-text">' .
'<span class="card-title">' .
$shiai->getHtmlName() .
"</span>" .
"<dl>" .
"<dt>Datum</dt>" .
"<dd>" .
$this->htmlDate() .
"</dd>" .
"<dt>Einschreibefrist</dt>" .
"<dd>" .
$this->htmlDeadLine() .
"</dd>" .
"<dt>Altersklassen</dt>" .
"<dd>" .
$this->shiai()->getHtmlDescriptiveAgeClasses() .
"</dd>" .
"</dl>" .
"</div>" .
"</div>";
}
public function getHtmlEventDetails()
{
$html = "<dl>";
$html .= "<dt>Datum</dt><dd>" . $this->htmlDate() . "</dd>";
$html .=
"<dt>Deadline zum Einschreiben:</dt><dd>" .
$this->htmlDeadLine() .
"</dd>";
$html .= "</dl>";
$html .= $this->shiai()->getHtml();
$html .= $this->getHtmlStarterStatistic();
$html .= $this->getHtmlStarterList();
}
public function htmlTableRow(): string
{
$shiai = $this->shiai();
return "<tr>" .
"<td>" .
$this->htmlDate() .
"</td>" .
'<td><a href="/participo/event?eventId=' .
$this->id .
'" >' .
$shiai->getHtmlName() .
"</a></td>" .
"<td>" .
$shiai->getHtmlDescriptiveAgeClasses() .
"</td>" .
'<td><button class="btn waves-effect waves-light" popovertarget="event-modal-' .
$this->id .
'"><i class="material-icons">zoom_in</i></button></td>' .
"</tr>";
}
public function htmlModal(): void
{
$modal =
'<div id="event-modal-' .
$this->id .
'" class="modal black-text" popover>' .
'<div class="modal-content">' .
$this->shiai->getHtml() .
"<hr />" .
$this->getHtmlStarterStatistic() .
"<hr />" .
$this->getHtmlStarterList() .
"<hr />";
$modal .= '<div class="row">';
$modal .=
'<div class="s12">Deadline zum Eintragen: ' .
$this->htmlDeadLine() .
"</div>";
$today = new DateTime();
if (
(isset($this->deadline) && $today <= $this->deadline) ||
participo::isUserAdmin()
) {
$kids = participo::getKids();
foreach ($kids as $k) {
$modal .= $this->getHtmlAddStarterForm($k, [
"returnToUrl" => "/participo/events#" . $this->id,
]);
}
} else {
$modal .=
"<div>Es ist leider zu spät noch jemanden einzutragen!</div>";
}
$modal .= "</div>";
$modal .=
"</div>" . // end modal-content
'<div class="modal-footer">' .
'<button tabindex="0" class="waves-effect btn-flat" popovertarget="event-modal-' .
$this->id .
'">Schließen</button>' .
"</div>" . // end modal-footer
"</div>";
echo $modal;
}
/** Get the list of starters as html list */
public function getHtmlStarterList()
{
$listOfStarter = $this->getStarter();
if (!isset($listOfStarter) || count($listOfStarter) == 0) {
return "";
}
$starterList = 'Bereits eingetragen: <div class="row">';
foreach ($listOfStarter as $start) {
$startingUser = $start->loadStarter();
$starterList .=
'<div class="col s12 m6"><div class="row valign-wrapper">' .
'<div class="col s6">' .
$startingUser->getName() .
", " .
$startingUser->getFirstname() .
" (" .
StartingType::$AsString[$start->getTypeId()] .
"):</div>" .
'<div class="col s6">' .
$start->getHtmlFormRemove() .
"</div>" .
"</div></div>";
}
$starterList .= "</div>";
return $starterList;
}
/** Returns the currents users starter to this event
*
* @todo docu
*/
public function getStarter()
{
$userId = $_SESSION["user"]["userId"] ?? null;
$query =
"SELECT `wkParticipo_Starter`.`id` as `starterId` FROM `wkParticipo_Starter` " .
"LEFT JOIN `vormundschaft` ON `vormundschaft`.`kidId` = `wkParticipo_Starter`.`userId` " .
" WHERE `wkParticipo_Starter`.`eventId` = :eventId AND `vormundschaft`.`userId` = :userId;";
$params = [
":eventId" => ["value" => $this->id, "data_type" => PDO::PARAM_INT],
":userId" => ["value" => $userId, "data_type" => PDO::PARAM_INT],
];
$response = dbConnector::query($query, $params);
$starter = [];
foreach ($response as $r) {
$starter[$r["starterId"]] = Starter::loadFromDb($r["starterId"]);
}
return $starter;
}
/** get number of starters of a certain type for this event
*
* @param int $startingType it representation of the StartingType to count
* @return int count of starters
*/
public function getStarterCount(int $startingType)
{
$query =
"SELECT COUNT(`wkParticipo_Starter`.`id`) AS starterCount FROM `wkParticipo_Starter` " .
" WHERE `wkParticipo_Starter`.`eventId` = :eventId AND `wkParticipo_Starter`.`type` = :typeId;";
$params = [
":eventId" => ["value" => $this->id, "data_type" => PDO::PARAM_INT],
":typeId" => [
"value" => $startingType,
"data_type" => PDO::PARAM_INT,
],
];
$response = dbConnector::query($query, $params);
return intval($response[0]["starterCount"]);
}
public function getSeatCount()
{
return self::getSeatCountOf($this->id);
}
public function getHtmlStarterStatistic()
{
$isEmpty = true;
$retHtml = "<dl>";
foreach (
[
StartingType::Fighter,
StartingType::NoParticipation,
StartingType::Audience,
]
as $type
) {
$count = $this->getStarterCount($type);
if ($count > 0) {
$isEmpty = false;
$retHtml .=
"<dt>" .
StartingType::$AsString[$type] .
"</dt><dd>" .
$count .
"</dd>";
}
}
if ($this->getSeatCount() > 0) {
$isEmpty = false;
$retHtml .=
"<dt>Mitfahrgelegenheiten</dt><dd>" .
$this->getSeatCount() .
"</dd>";
}
$retHtml .= "</dl>";
return $isEmpty ? "" : $retHtml;
}
public static function fromDbArray($member)
{
return new Event(
$member["id"] ?? null,
$member["date"] ?? null,
$member["wkId"] ?? null,
$member["meldefrist"] ?? null,
$member["bemerkungen"] ?? null,
);
}
/// Einen Starter per userId mit typeId zu einem Event per eventId hinzufügen
/// Es erfolgt keine Überprüfung der Meldeberechtigung!
public static function addStarter($dbConnection, $starter)
{
$query =
"INSERT INTO `wkParticipo_Starter` (eventId, userId, type) values (:eventId, :userId, :typeId);";
$params = [
":eventId" => [
"value" => $starter->getEventId(),
"data_type" => PDO::PARAM_INT,
],
":userId" => [
"value" => $starter->getUserId(),
"data_type" => PDO::PARAM_INT,
],
":typeId" => [
"value" => $starter->getTypeId(),
"data_type" => PDO::PARAM_INT,
],
];
return dbConnector::query($query, $params);
}
public static function getSeatCountOf(int $id)
{
$query =
"SELECT SUM(plaetze) AS sumSeats FROM `cwsvjudo_main`.`wkParticipo_Fahrten` WHERE eventId = :eventId;";
$params = [
"eventId" => ["value" => $id, "data_type" => PDO::PARAM_INT],
];
$response = dbConnector::query($query, $params);
$sumSeats = filterCount($response[0]["sumSeats"]);
return $sumSeats;
}
public function getHtmlAddStarterForm($user, $options = [])
{
$defaults = [
"formClass" => "s12 m6 xl3",
"inputClass" => "col s12",
"buttonClass" => "btn",
];
$options = array_merge($defaults, $options);
$returnToUrl = $options["returnToUrl"] ?? urlencode(getCurPagesUrl());
$key = $_SESSION["apiKey"] ?? null;
$selectId =
"form-selectType-event-" . $this->id . "-user-" . $user->getId();
$form =
'<form class="' .
$options["formClass"] .
'" action="api.starter.add.php" method="post">' .
'<input type="hidden" name="eventId" id="eventId" value="' .
$this->id .
'">' .
'<input type="hidden" name="userId" id="userId" value="' .
$user->getId() .
'">' .
'<input type="hidden" name="returnToUrl" id="returnToUrl" value="' .
$returnToUrl .
'" >' .
'<div class="' .
$options["inputClass"] .
'">' .
'<fieldset id="' .
$selectId .
">" .
'<label for="' .
$selectId .
'">' .
$user->getName() .
", " .
$user->getFirstname() .
"</label>" .
"<p>" .
'<label for="' .
$selectId .
'-asStarter">' .
'<input name="type" type="radio" id="' .
$selectId .
'-asStarter" value="1" />' .
"<span>als Starter</span>" .
"</label>" .
"</p>" .
"<p>" .
'<label for="' .
$selectId .
'-asWatcher">' .
'<input name="type" type="radio" id="' .
$selectId .
'-asWatcher" value="2" />' .
"<span>als Zuschauer</span>" .
"</label>" .
"</p>" .
"<p>" .
'<label for="' .
$selectId .
'-asNone">' .
'<input name="type" type="radio" id="' .
$selectId .
'-asNone" value="3" checked />' .
"<span>keine Teilnahme</span>" .
"</label>" .
"</p>" .
'<input class="' .
$options["buttonClass"] .
'" type="submit" name="submit" value="eintragen" />' .
"</fieldset>" .
"</div>" .
"</form>";
return $form;
}
} // end class event