diff --git a/src/Praktikum/Prak5/Baecker.php b/src/Praktikum/Prak5/Baecker.php new file mode 100644 index 0000000000000000000000000000000000000000..7264a27c2f3c4e8a94ca0b605bcb1a2a4a5ec35b --- /dev/null +++ b/src/Praktikum/Prak5/Baecker.php @@ -0,0 +1,224 @@ +<?php declare(strict_types=1); +// UTF-8 marker äöüÄÖÜ߀ +/** + * Class baecker for the exercises of the EWA lecture + * Demonstrates use of PHP including class and OO. + * Implements Zend coding standards. + * Generate documentation with Doxygen or phpdoc + * + * PHP Version 7.4 + * + * @file baecker.php + * @package Page Templates + * @author Bernhard Kreling, <bernhard.kreling@h-da.de> + * @author Ralf Hahn, <ralf.hahn@h-da.de> + * @version 3.1 + */ + +// to do: change name 'baecker' throughout this file +require_once './Page.php'; +require_once './DB_Classes/OrderedArticle.php'; +/** + * This is a template for top level classes, which represent + * a complete web page and which are called directly by the user. + * Usually there will only be a single instance of such a class. + * The name of the template is supposed + * to be replaced by the name of the specific HTML page e.g. baker. + * The order of methods might correspond to the order of thinking + * during implementation. + * @author Bernhard Kreling, <bernhard.kreling@h-da.de> + * @author Ralf Hahn, <ralf.hahn@h-da.de> + */ +class Baecker extends Page +{ + // to do: declare reference variables for members + // representing substructures/blocks + + /** + * Instantiates members (to be defined above). + * Calls the constructor of the parent i.e. page class. + * So, the database connection is established. + * @throws Exception + */ + protected function __construct() + { + parent::__construct(); + // to do: instantiate members representing substructures/blocks + } + + /** + * Cleans up whatever is needed. + * Calls the destructor of the parent i.e. page class. + * So, the database connection is closed. + */ + public function __destruct() + { + parent::__destruct(); + } + + /** + * Fetch all data that is necessary for later output. + * Data is returned in an array e.g. as associative array. + * @return array An array containing the requested data. + * This may be a normal array, an empty array or an associative array. + */ + protected function getViewData():array + { + $query = "SELECT * FROM ordered_article;"; + $resultSet = $this->_database->query($query); + $orderedArticleList = array(); + + while ($row = $resultSet->fetch_assoc()) { + + $orderedArticle = new OrderedArticle( + (int)$row["ordered_article_id"], (int)$row["ordering_id"], (int)$row["article_id"], (int)$row["status"] + ); + + $orderedArticleList[$orderedArticle->getOrderedArticleId()] = $orderedArticle; + } + $resultSet->free_result(); + return $orderedArticleList; + } + + /** + * First the required data is fetched and then the HTML is + * assembled for output. i.e. the header is generated, the content + * of the page ("view") is inserted and -if available- the content of + * all views contained is generated. + * Finally, the footer is added. + * @return void + */ + protected function generateView():void + { + $data = $this->getViewData(); //NOSONAR ignore unused $data + $this->generatePageHeader('Bäcker',"",true); //to do: set optional parameters + echo <<< HTML + \n<section id="baecker"> + <h2>Bestellung</h2> + + <form id="formBaecker" accept-charset="UTF-8" action="#" method="post">\n +HTML; + + $noOrders = true; + foreach ($data as $order){ + $query = "SELECT UNIQUE name FROM article, ordered_article + WHERE article.article_id = {$order->getArticleId()};"; + $resultSet = $this->_database->query($query); + $resultArray = $resultSet->fetch_assoc(); + $resultSet->free_result(); + + $pizzaName = htmlspecialchars($resultArray["name"]); + $orderedArticleId = $order->getOrderedArticleId(); + + $status = $order->getStatus(); + if ($status > 2 ) { + continue; + } + else { + $noOrders = false; + } + + $statusArray = array_fill(0, 5, ""); + $statusArray[$status] = "checked"; + + echo <<< HTML + <fieldset> + <legend>Bestellung {$order->getOrderingId()} Pizza {$pizzaName}</legend> + Status: <br> + <label> + Bestellt + <input type="radio" name="{$orderedArticleId}" value="0" {$statusArray[0]} onclick="document.forms['formBaecker'].submit();"> + </label> <br> + + <label> + Im Ofen + <input type="radio" name="{$orderedArticleId}" value="1" {$statusArray[1]} onclick="document.forms['formBaecker'].submit();"> + </label> <br> + + <label> + Fertig + <input type="radio" name="{$orderedArticleId}" value="2" {$statusArray[2]} onclick="document.forms['formBaecker'].submit();"> + </label> + </fieldset>\n +HTML; + } + + if ($noOrders) { + + echo <<< HTML + \n<p>Es gibt keine Bestellungen</p> +HTML; + } + + echo <<< HTML + </form> + </section>\n +HTML; + + $this->generatePageFooter(); + } + + /** + * Processes the data that comes via GET or POST. + * If this page is supposed to do something with submitted + * data do it here. + * @return void + */ + protected function processReceivedData():void + { + parent::processReceivedData(); + // to do: call processReceivedData() for all members + $data = $this->getViewData(); + foreach ($data as $order){ + $orderedArticleId = $order->getOrderedArticleId(); + if (isset($_POST["{$orderedArticleId}"]) && is_numeric($_POST["{$orderedArticleId}"])) { + $status = $this->_database->real_escape_string($_POST["{$orderedArticleId}"]); + $query = "UPDATE ordered_article SET status = {$status} + WHERE ordered_article.ordered_article_id = {$orderedArticleId};"; + $this->_database->query($query); + } + } + + // On Post => Reload + if (isset($_POST["save"])) { + header("HTTP/1.1 303 See Other"); + header('Location: ' . $_SERVER['REQUEST_URI']); + die; + } + } + + /** + * This main-function has the only purpose to create an instance + * of the class and to get all the things going. + * I.e. the operations of the class are called to produce + * the output of the HTML-file. + * The name "main" is no keyword for php. It is just used to + * indicate that function as the central starting point. + * To make it simpler this is a static function. That is you can simply + * call it without first creating an instance of the class. + * @return void + */ + public static function main():void + { + try { + $page = new Baecker(); + $page->processReceivedData(); + $page->generateView(); + } catch (Exception $e) { + //header("Content-type: text/plain; charset=UTF-8"); + header("Content-type: text/html; charset=UTF-8"); + echo $e->getMessage(); + } + } +} + +// This call is starting the creation of the page. +// That is input is processed and output is created. +Baecker::main(); + +// Zend standard does not like closing php-tag! +// PHP doesn't require the closing tag (it is assumed when the file ends). +// Not specifying the closing ? > helps to prevent accidents +// like additional whitespace which will cause session +// initialization to fail ("headers already sent"). +//? > diff --git a/src/Praktikum/Prak5/Bestellung.php b/src/Praktikum/Prak5/Bestellung.php new file mode 100644 index 0000000000000000000000000000000000000000..34d4745eb7e9c3dc789c104e5516bf04012c70e2 --- /dev/null +++ b/src/Praktikum/Prak5/Bestellung.php @@ -0,0 +1,213 @@ +<?php /** @noinspection PhpMultipleClassDeclarationsInspection */ +declare(strict_types=1); +// UTF-8 marker äöüÄÖÜ߀ +/** + * Class Bestellung for the exercises of the EWA lecture + * Demonstrates use of PHP including class and OO. + * Implements Zend coding standards. + * Generate documentation with Doxygen or phpdoc + * + * PHP Version 7.4 + * + * @file Bestellung.php + * @package Page Templates + * @author Bernhard Kreling, <bernhard.kreling@h-da.de> + * @author Ralf Hahn, <ralf.hahn@h-da.de> + * @version 3.1 + */ + +require_once './Page.php'; +require_once './DB_Classes/Article.php'; + +/** + * This is a template for top level classes, which represent + * a complete web page and which are called directly by the user. + * Usually there will only be a single instance of such a class. + * The name of the template is supposed + * to be replaced by the name of the specific HTML page e.g. baker. + * The order of methods might correspond to the order of thinking + * during implementation. + * @author Bernhard Kreling, <bernhard.kreling@h-da.de> + * @author Ralf Hahn, <ralf.hahn@h-da.de> + */ +class Bestellung extends Page +{ + /** + * Instantiates members (to be defined above). + * Calls the constructor of the parent i.e. page class. + * So, the database connection is established. + * @throws Exception + */ + protected function __construct() + { + parent::__construct(); + } + + /** + * Cleans up whatever is needed. + * Calls the destructor of the parent i.e. page class. + * So, the database connection is closed. + */ + public function __destruct() + { + parent::__destruct(); + } + + /** + * Fetch all data that is necessary for later output. + * Data is returned in an array e.g. as associative array. + * @return array An array containing the requested data. + * This may be a normal array, an empty array or an associative array. + */ + protected function getViewData(): array + { + // to do: fetch data for this view from the database + $query = "SELECT * FROM article;"; + $resultSet = $this->_database->query($query); + $pizzaList = array(); + + + while ($row = $resultSet->fetch_assoc()) { + + $pizza = new Article((int)$row["article_id"], $row["name"], $row["picture"], (float)$row["price"]); + + $pizzaList[$pizza->getName()] = $pizza; + } + $resultSet->free_result(); + return $pizzaList; + } + + /** + * First the required data is fetched and then the HTML is + * assembled for output. i.e. the header is generated, the content + * of the page ("view") is inserted and -if available- the content of + * all views contained is generated. + * Finally, the footer is added. + * @return void + */ + protected function generateView(): void + { + $data = $this->getViewData(); //NOSONAR ignore unused $data + $this->generatePageHeader('Bestellung', './JS/BestellScript.js', false); + + echo <<< HTML + + <section id="bestellungSection"> + <h1 id="bestellungTitle">Bestellung</h1> + <hr> + <section id="speisekarteSection"> + <h2>Speisekarte</h2> + HTML; + + foreach ($data as $pizza) { + echo <<< HTML + <label> + <img class="pizzaImage" alt="Image of Pizza {$pizza->getName()}" src="{$pizza->getPicture()}" data-articleID="{$pizza->getArticleId()}" data-name="{$pizza->getName()}" data-price="{$pizza->getPrice()}" onclick="addItem(this);"> + <br> + {$pizza->getName()}<br> + {$pizza->getPrice()}€ + </label> + <br> + HTML; + } + + echo <<< HTML + <script>getElements();</script> + </section> + <hr> + <section id="warenkorbSection"> + <h2>Warenkorb</h2> + <form accept-charset="UTF-8" action="#" method="post"> + <label for="warenkorb"></label> + <select id="warenkorb" multiple name="Pizza[]"> + </select> + + <p id="sum"></p> + + <label for="address"></label> + <input id="address" name="Adresse" placeholder="Ihre Adresse" type="text" required><br> + <input type="button" value="Alles Löschen" onclick="removeAll();"> + <input type="button" value="Auswahl Löschen" onclick="removeItem();"> + <input id="submitButton" type="submit" name="save" value="Bestellen" onclick="selectOrder();"> + </form> + </section> + </section> + HTML; + + + $this->generatePageFooter(); + } + + /** + * Processes the data that comes via GET or POST. + * If this page is supposed to do something with submitted + * data do it here. + * @return void + */ + protected function processReceivedData(): void + { + parent::processReceivedData(); + + if (isset($_POST["Pizza"]) && isset($_POST["Adresse"])) { + $pizzas = $_POST["Pizza"]; + $rawAddress = $_POST["Adresse"]; + $address = $this->_database->real_escape_string($rawAddress); + + $orderingQuery = "INSERT INTO ordering (ordering.address) VALUES ('$address');"; + $this->_database->query($orderingQuery); + $orderingID = mysqli_insert_id($this->_database); + + if(!isset($_SESSION["orders"])) { + $_SESSION["orders"] = array(); + } + + $orders = $_SESSION["orders"]; + $orders[] = $orderingID; + $orders = array_unique($orders); + $_SESSION["orders"] = $orders; + + foreach ($pizzas as $articleId) { + $safeArticleId = $this->_database->real_escape_string("$articleId"); + $orderedArticleQuery = "INSERT INTO ordered_article(ordering_id, article_id) + VALUES ($orderingID, $safeArticleId);"; + $this->_database->query($orderedArticleQuery); + } + } + + // On Post => Reload + if (isset($_POST["save"])) { + header("HTTP/1.1 303 See Other"); + header('Location: ./Kunde.php'); + die; + } + } + + /** + * This main-function has the only purpose to create an instance + * of the class and to get all the things going. + * I.e. the operations of the class are called to produce + * the output of the HTML-file. + * The name "main" is no keyword for php. It is just used to + * indicate that function as the central starting point. + * To make it simpler this is a static function. That is you can simply + * call it without first creating an instance of the class. + * @return void + */ + public static function main(): void + { + session_start(); + try { + $page = new Bestellung(); + $page->processReceivedData(); + $page->generateView(); + } catch (Exception $e) { + //header("Content-type: text/plain; charset=UTF-8"); + header("Content-type: text/html; charset=UTF-8"); + echo $e->getMessage(); + } + } +} + +// This call is starting the creation of the page. +// That is input is processed and output is created. +Bestellung::main(); diff --git a/src/Praktikum/Prak5/CSS/file.css b/src/Praktikum/Prak5/CSS/file.css new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/Praktikum/Prak5/DB_Classes/Article.php b/src/Praktikum/Prak5/DB_Classes/Article.php new file mode 100644 index 0000000000000000000000000000000000000000..8c18b60d8d43c0b86d0c78cbf17e105d7d0f99a7 --- /dev/null +++ b/src/Praktikum/Prak5/DB_Classes/Article.php @@ -0,0 +1,39 @@ +<?php declare(strict_types=1); + +class Article +{ + private int $article_id; + private string $name; + private string $picture; + private float $price; + + public function getArticleId(): int + { + return $this->article_id; + } + + public function getName(): string + { + return $this->name; + } + + public function getPicture(): string + { + return $this->picture; + } + + public function getPrice(): float + { + return $this->price; + } + + + public function __construct(int $article_id = 0, string $name="", string $picture = "", float $price = 0.0) + { + $this->name = $name; + $this->article_id = $article_id; + $this->picture = $picture; + $this->price = $price; + } + +} diff --git a/src/Praktikum/Prak5/DB_Classes/FahrerData.php b/src/Praktikum/Prak5/DB_Classes/FahrerData.php new file mode 100644 index 0000000000000000000000000000000000000000..abbae1298828b147adffb5f046b7fdb3d32e5fd7 --- /dev/null +++ b/src/Praktikum/Prak5/DB_Classes/FahrerData.php @@ -0,0 +1,46 @@ +<?php + +class FahrerData +{ + private int $orderingId; + private int $orderedArticleId ; + private string $address; + private int $status; + + + /** + * @param int $orderingId + * @param int $orderedArticleId + * @param string $address + * @param int $status + * @param string $ordering_time + */ + public function __construct(int $orderingId, int $orderedArticleId, string $address, int $status) + { + $this->orderingId = $orderingId; + $this->orderedArticleId = $orderedArticleId; + $this->address = $address; + $this->status = $status; + } + + public function getOrderingId(): int + { + return $this->orderingId; + } + + public function getOrderedArticleId(): int + { + return $this->orderedArticleId; + } + + public function getAddress(): string + { + return $this->address; + } + + public function getStatus(): int + { + return $this->status; + } + +} diff --git a/src/Praktikum/Prak5/DB_Classes/OrderedArticle.php b/src/Praktikum/Prak5/DB_Classes/OrderedArticle.php new file mode 100644 index 0000000000000000000000000000000000000000..546ff3aa261bd92481501eaeba50917eaaf9b6d9 --- /dev/null +++ b/src/Praktikum/Prak5/DB_Classes/OrderedArticle.php @@ -0,0 +1,57 @@ +<?php declare(strict_types=1); +require_once './DB_Classes/Article.php'; +class OrderedArticle +{ + private int $ordered_article_id; + private int $ordering_id; + private int $article_id; + private int $status; + private Article $article; + + public function getArticle(): Article + { + return $this->article; + } + + public function setArticle(Article $article): void + { + $this->article = $article; + } + + public function getOrderedArticleId(): int + { + return $this->ordered_article_id; + } + + public function getOrderingId(): int + { + return $this->ordering_id; + } + + public function getArticleId(): int + { + return $this->article_id; + } + + public function getStatus(): int + { + return $this->status; + } + + + /** + * @param int $ordered_article_id + * @param int $ordering_id + * @param int $article_id + * @param int $status + */ + + public function __construct(int $ordered_article_id=0, int $ordering_id=0, int $article_id=0, int $status=0) + { + $this->ordered_article_id = $ordered_article_id; + $this->ordering_id = $ordering_id; + $this->article_id = $article_id; + $this->status = $status; + } + +} diff --git a/src/Praktikum/Prak5/DB_Classes/Ordering.php b/src/Praktikum/Prak5/DB_Classes/Ordering.php new file mode 100644 index 0000000000000000000000000000000000000000..7b27ca3a897e19ed9b8ef67aa882a0e08b39ae86 --- /dev/null +++ b/src/Praktikum/Prak5/DB_Classes/Ordering.php @@ -0,0 +1,72 @@ +<?php declare(strict_types=1); + +class Ordering +{ + private int $ordering_id; + private string $address; + private string $ordering_time; + private array $orderList; + + public function getOrderList(): array + { + return $this->orderList; + } + + public function setOrderList(array $orderList) : void + { + $this->orderList = $orderList; + } + + public function addItem(OrderedArticle $article) : void + { + $this->orderList[] = $article; + } + + public function getMinStatus() : int + { + $valueArray = array(); + foreach ($this->orderList as $item) { + + $valueArray[] = $item->getStatus(); + } + return min($valueArray); + } + + public function getSum() : float + { + $valueArray = array(); + foreach ($this->orderList as $item) { + + $valueArray[] = $item->getArticle()->getPrice(); + } + return array_sum($valueArray); + } + + /** + * @param int $ordering_id + * @param string $address + * @param string $ordering_time + */ + public function __construct(int $ordering_id=0, string $address="", string $ordering_time="") + { + $this->ordering_id = $ordering_id; + $this->address = $address; + $this->ordering_time = $ordering_time; + } + + public function getOrderingId(): int + { + return $this->ordering_id; + } + + public function getAddress(): string + { + return $this->address; + } + + public function getOrderingtime(): string + { + return $this->ordering_time; + } + +} diff --git a/src/Praktikum/Prak5/Fahrer.php b/src/Praktikum/Prak5/Fahrer.php new file mode 100644 index 0000000000000000000000000000000000000000..6731a367805d99db417381a6595fcfa00cd41752 --- /dev/null +++ b/src/Praktikum/Prak5/Fahrer.php @@ -0,0 +1,237 @@ +<?php declare(strict_types=1); +// UTF-8 marker äöüÄÖÜ߀ +/** + * Class fahrer for the exercises of the EWA lecture + * Demonstrates use of PHP including class and OO. + * Implements Zend coding standards. + * Generate documentation with Doxygen or phpdoc + * + * PHP Version 7.4 + * + * @file fahrer.php + * @package Page Templates + * @author Bernhard Kreling, <bernhard.kreling@h-da.de> + * @author Ralf Hahn, <ralf.hahn@h-da.de> + * @version 3.1 + */ + +// to do: change name 'fahrer' throughout this file +require_once './Page.php'; +require_once './DB_Classes/Ordering.php'; +require_once './DB_Classes/OrderedArticle.php'; +/** + * This is a template for top level classes, which represent + * a complete web page and which are called directly by the user. + * Usually there will only be a single instance of such a class. + * The name of the template is supposed + * to be replaced by the name of the specific HTML page e.g. baker. + * The order of methods might correspond to the order of thinking + * during implementation. + * @author Bernhard Kreling, <bernhard.kreling@h-da.de> + * @author Ralf Hahn, <ralf.hahn@h-da.de> + */ +class Fahrer extends Page +{ + // to do: declare reference variables for members + // representing substructures/blocks + + /** + * Instantiates members (to be defined above). + * Calls the constructor of the parent i.e. page class. + * So, the database connection is established. + * @throws Exception + */ + protected function __construct() + { + parent::__construct(); + // to do: instantiate members representing substructures/blocks + } + + /** + * Cleans up whatever is needed. + * Calls the destructor of the parent i.e. page class. + * So, the database connection is closed. + */ + public function __destruct() + { + parent::__destruct(); + } + + /** + * Fetch all data that is necessary for later output. + * Data is returned in an array e.g. as associative array. + * @return array An array containing the requested data. + * This may be a normal array, an empty array or an associative array. + */ + + protected function getViewData():array + { + $query = "SELECT ordering.ordering_id, address, ordered_article_id, ordered_article.article_id, status, price + FROM ordering, ordered_article, article WHERE + ordering.ordering_id = ordered_article.ordering_id AND ordered_article.article_id = article.article_id;"; + $resultSet = $this->_database->query($query); + + $orderings = array(); + while ($row = $resultSet->fetch_assoc()) { + + $currentOrderingId = $row["ordering_id"]; + if (!isset($orderings[$currentOrderingId])) { + + $orderings[$currentOrderingId] = new Ordering((int)$currentOrderingId, (string)$row["address"]); + } + + $tempItem = new OrderedArticle( + (int)$row["ordered_article_id"], (int)$currentOrderingId, (int)$row["article_id"], (int)$row["status"] + ); + + $orderings[$currentOrderingId]->addItem($tempItem); + $tempItem->setArticle(new Article((int)$row["article_id"],"","",(float)$row["price"])); + } + + $resultSet->free_result(); + return $orderings; + } + + + /** + * First the required data is fetched and then the HTML is + * assembled for output. i.e. the header is generated, the content + * of the page ("view") is inserted and -if available- the content of + * all views contained is generated. + * Finally, the footer is added. + * @return void + */ + protected function generateView():void + { + $data = $this->getViewData(); + $this->generatePageHeader('Fahrer', "", true); + + echo <<< HTML + <section id="Fahrer"> + <h2>Lieferliste</h2> + + <form id="formFahrer" accept-charset="UTF-8" action="#" method="post"> +HTML; + + $noDeliveries = true; + $i = 0; + foreach ($data as $order) { + $status = $order->getMinStatus(); + if ($status < 2 || $status >= 4) { + continue; + } else { + $noDeliveries = false; + } + + $statusArray = array_fill(0, 5, ""); + $statusArray[$status] = "checked"; + + $address = htmlspecialchars( $order->getAddress() ); + echo <<< HTML + \n<fieldset> + <legend accessKey="{$i}">Bestellung {$order->getOrderingId()}</legend> + + <p>{$address}</p> + <p>Gesamtkosten: {$order->getSum()}€</p> + + <label> + <input type="radio" name="{$order->getOrderingId()}" value="2" {$statusArray[2]} onclick="document.forms['formFahrer'].submit();"> + Fertig + </label> + + <label> + <input type="radio" name="{$order->getOrderingId()}" value="3" {$statusArray[3]} onclick="document.forms['formFahrer'].submit();"> + Untwerwegs + </label> + + <label> + <input type="radio" name="{$order->getOrderingId()}" value="4" {$statusArray[4]} onclick="document.forms['formFahrer'].submit();"> + Geliefert + </label> + </fieldset>\n +HTML; + $i++; + } + + if ($noDeliveries) { + + echo <<< HTML + \n<p>Es gibt keine fertigen Bestellungen</p> +HTML; + } + + + + echo <<< HTML + </form> + </section> +HTML; + $this->generatePageFooter(); + } + + /** + * Processes the data that comes via GET or POST. + * If this page is supposed to do something with submitted + * data do it here. + * @return void + */ + protected function processReceivedData():void + { + parent::processReceivedData(); + $data = $this->getViewData(); + + foreach ($data as $order) { + $orderingId = $order->getOrderingId(); + + if (isset($_POST["{$orderingId}"]) && is_numeric($_POST["{$orderingId}"])) { + $status = $this->_database->real_escape_string($_POST["{$orderingId}"]); + + $query = "UPDATE ordered_article SET status = {$status} + WHERE ordered_article.ordering_id = {$orderingId}"; + $this->_database->query($query); + } + } + + // On Post => Reload + if (isset($_POST["save"])) { + header("HTTP/1.1 303 See Other"); + header('Location: ' . $_SERVER['REQUEST_URI']); + die; + } + } + + /** + * This main-function has the only purpose to create an instance + * of the class and to get all the things going. + * I.e. the operations of the class are called to produces + * the output of the HTML-file. + * The name "main" is no keyword for php. It is just used to + * indicate that function as the central starting point. + * To make it simpler this is a static function. That is you can simply + * call it without first creating an instance of the class. + * @return void + */ + public static function main():void + { + try { + $page = new Fahrer(); + $page->processReceivedData(); + $page->generateView(); + } catch (Exception $e) { + //header("Content-type: text/plain; charset=UTF-8"); + header("Content-type: text/html; charset=UTF-8"); + echo $e->getMessage(); + } + } +} + +// This call is starting the creation of the page. +// That is input is processed and output is created. +Fahrer::main(); + +// Zend standard does not like closing php-tag! +// PHP doesn't require the closing tag (it is assumed when the file ends). +// Not specifying the closing ? > helps to prevent accidents +// like additional whitespace which will cause session +// initialization to fail ("headers already sent"). +//? > diff --git a/src/Praktikum/Prak5/JS/BestellScript.js b/src/Praktikum/Prak5/JS/BestellScript.js new file mode 100644 index 0000000000000000000000000000000000000000..36a827ed781244c72ea92649afd78ed217129f8d --- /dev/null +++ b/src/Praktikum/Prak5/JS/BestellScript.js @@ -0,0 +1,84 @@ +let pizzaPriceMap = new Map(); +function getElements() { + "use strict"; + let pizzaImages = document.getElementsByClassName("pizzaImage"); + for (let item of pizzaImages) { + pizzaPriceMap.set( + item.getAttribute("data-articleID"), + item.getAttribute("data-price") + ); + } +} + +function addItem(pizza) { + "use strict"; + let articleID = pizza.getAttribute("data-articleID"); + let name = pizza.getAttribute("data-name"); + let select = document.getElementById("warenkorb"); + let newOption = document.createElement("option"); + newOption.text = name; + newOption.value = articleID; + select.add(newOption); + calculateSum(); + checkInputs(); +} + +function calculateSum() { + "use strict"; + let select = document.getElementById("warenkorb"); + let price = 0; + for (let item of select.options) { + price += parseFloat(pizzaPriceMap.get(item.value)); + } + document.getElementById("sum").innerText = price.toFixed(2) + " €"; +} + +function removeItem() { + "use strict"; + let select = document.getElementById("warenkorb"); + select.remove(select.selectedIndex); + calculateSum(); + checkInputs(); +} + +function removeAll() { + "use strict"; + let select = document.getElementById("warenkorb"); + select.options.length = 0; + calculateSum(); + checkInputs(); +} + +function selectOrder() { + "use strict"; + let select = document.getElementById("warenkorb"); + for (let option of select.options) { + option.selected = true; + } +} + +function checkInputs() { + "use strict"; + const selectInput = document.getElementById("warenkorb"); + const address = document.getElementById("address"); + const button = document.getElementById("submitButton"); + + // Check conditions + const selectHasOptions = selectInput.options.length > 0; + const addressHasValue = address.value.trim() !== ""; + + // Enable or disable the button + button.disabled = !(selectHasOptions && addressHasValue); +} + +//--- LISTENERS + +window.onload = function init() { + "use strict"; + document.getElementById("address").addEventListener("input", checkInputs); +}; + +document.addEventListener( + "DOMContentLoaded", + checkInputs +); // Check on page load diff --git a/src/Praktikum/Prak5/JS/DEPRECATED/OrderData.js b/src/Praktikum/Prak5/JS/DEPRECATED/OrderData.js new file mode 100644 index 0000000000000000000000000000000000000000..a8a8b68c1e82f470e8e51b1144033eadc81c496e --- /dev/null +++ b/src/Praktikum/Prak5/JS/DEPRECATED/OrderData.js @@ -0,0 +1,59 @@ +class OrderData { + + constructor(orderingID, address, pizzaObj) { + + this.orderingID = orderingID; + this.address = address; + this.pizzaObj = pizzaObj; + this.buildOrder(); + + } + + + buildOrder() { + + let orderMainNode = document.createElement("fieldset"); + orderMainNode.id = this.orderingID; + + let orderLegend = document.createElement("legend"); + orderLegend.id = this.orderingID + ".legend"; + + orderMainNode.append(orderLegend); + + this.buildPizza(orderMainNode) + } + + buildPizza(orderMainNode) { + let pizzaList = this.pizzaObj.pizzaList; + for (let pizza of pizzaList) { + let pizzaName = pizza.name; + let orderedArticleID = pizza.orderedArticleID; + let pizzaStatus = pizza.status; + let pizzaNode = document.createElement("fieldset"); + let pizzaLegend = document.createElement("legend"); + pizzaNode.id = "pizzaNode." + orderedArticleID; + pizzaLegend.innerText = "Pizza " + pizzaName; + pizzaNode.append(pizzaLegend); + this.buildInputs(pizzaNode, orderedArticleID, pizzaStatus); + orderMainNode.append(pizzaNode); + } + } + + buildInputs(pizzaNode, orderedArticleID, status) { + let statusArray = ["Bestellt", "Im Ofen", "Fertig", "Unterwegs", "Geliefert"]; + for (let value = 0; value < 5; value++) { + let inputLabel = document.createElement("label"); + pizzaNode.append(inputLabel); + inputLabel.innerText = statusArray[value]; + let inputRadio = document.createElement("input"); + inputLabel.append(inputRadio); + inputRadio.type = "radio"; + inputRadio.name = orderedArticleID; + inputRadio.value = value.toString(); + inputRadio.disabled = true; + if (value === status) { + inputRadio.checked = true; + } + } + } +} diff --git a/src/Praktikum/Prak5/JS/Kunde.js b/src/Praktikum/Prak5/JS/Kunde.js new file mode 100644 index 0000000000000000000000000000000000000000..4421843cec117177f63aef923c9f431d3bbc2af5 --- /dev/null +++ b/src/Praktikum/Prak5/JS/Kunde.js @@ -0,0 +1,149 @@ +function loadData() { + "use strict"; + var url = "./Kundenstatus.php"; + var request = new XMLHttpRequest(); + + request.open("GET", url, true); + + request.onload = function () { + + if (request.readyState === 4 && + request.status >= 200 && + request.status < 300) { + + if (request.responseText != null) { + + var responseData = JSON.parse(request.responseText); + console.log(responseData); + process(responseData); + } else { + console.error ("Dokument ist leer"); + } + } else { + console.error("Statuscode: " + request.status); + } + }; + + request.onerror = function () { + "use strict"; + console.error("Netzwerkfehler"); + }; + + //request.onreadystatechange = processData; + + request.send(); +} + +const newScript = document.createElement("script"); +newScript.src = "./JS/OrderData.js"; +newScript.type = "module"; +document.getElementsByTagName("body")[0].prepend(newScript); + + +function process(data) { + + "use strict"; + + const orderForm = document.getElementById("orderForm"); + if (orderForm != null) { + + while (orderForm.lastElementChild) { + orderForm.removeChild(orderForm.lastElementChild); + } + + + for (let [orderingID, order] of Object.entries(data)) { + + let pizzaObj = { + pizzaList: [] + }; + + //orderForm.append(testBuildOrder(orderingID)); + + let orderList = order["OrderList"] + for (let [orderedArticleID, pizza] of Object.entries(orderList)) { + + let name = pizza["Name"]; + let price = parseFloat(pizza["Price"]); + let status = parseInt(pizza["Status"]); + + let newPizza = { + orderedArticleID: orderedArticleID, + name: name, + price: price, + status: status + }; + pizzaObj.pizzaList.push(newPizza); + } + buildOrder(orderForm, orderingID, pizzaObj); + } + + } +} + + +window.onload = function () { + + "use strict"; + loadData(); +} + +window.setInterval (loadData, 2000); + + + +function buildOrder(parentNode, id, pizzaObj) { + "use strict"; + let orderMainNode = document.createElement("fieldset"); + orderMainNode.id = id; + + let orderLegend = document.createElement("legend"); + orderLegend.id = id + ".legend"; + orderLegend.innerText = "Bestellung " + id; + + orderMainNode.append(orderLegend); + buildPizza(orderMainNode, pizzaObj); + + parentNode.append(orderMainNode); +} + +function buildPizza(orderMainNode, pizzaObj) { + "use strict"; + let pizzaList = pizzaObj.pizzaList; + for (let pizza of pizzaList) { + + let pizzaName = pizza.name; + let orderedArticleID = pizza.orderedArticleID; + let pizzaStatus = pizza.status; + + let pizzaNode = document.createElement("fieldset"); + let pizzaLegend = document.createElement("legend"); + pizzaNode.id = "pizzaNode." + orderedArticleID; + pizzaLegend.innerText = "Pizza " + pizzaName; + pizzaNode.append(pizzaLegend); + buildInputs(pizzaNode, orderedArticleID, pizzaStatus); + orderMainNode.append(pizzaNode); + } +} + +function buildInputs(pizzaNode, orderedArticleID, status) { + "use strict"; + let statusArray = [ + "Bestellt", "Im Ofen", "Fertig", + "Unterwegs", "Geliefert" + ]; + for (let value = 0; value < 5; value++) { + let inputLabel = document.createElement("label"); + pizzaNode.append(inputLabel); + inputLabel.innerText = statusArray[value]; + let inputRadio = document.createElement("input"); + inputLabel.append(inputRadio); + inputRadio.type = "radio"; + inputRadio.name = orderedArticleID; + inputRadio.value = value.toString(); + inputRadio.disabled = true; + if (value === status) { + inputRadio.checked = true; + } + } +} diff --git a/src/Praktikum/Prak5/Kunde.php b/src/Praktikum/Prak5/Kunde.php new file mode 100644 index 0000000000000000000000000000000000000000..31570b23b1dc9115d98403e2c21292c8196474b9 --- /dev/null +++ b/src/Praktikum/Prak5/Kunde.php @@ -0,0 +1,211 @@ +<?php declare(strict_types=1); +// UTF-8 marker äöüÄÖÜ߀ +/** + * Class kunde for the exercises of the EWA lecture + * Demonstrates use of PHP including class and OO. + * Implements Zend coding standards. + * Generate documentation with Doxygen or phpdoc + * + * PHP Version 7.4 + * + * @file kunde.php + * @package Page Templates + * @author Bernhard Kreling, <bernhard.kreling@h-da.de> + * @author Ralf Hahn, <ralf.hahn@h-da.de> + * @version 3.1 + */ + +// to do: change name 'kunde' throughout this file +require_once './Page.php'; +require_once './DB_Classes/OrderedArticle.php'; +/** + * This is a template for top level classes, which represent + * a complete web page and which are called directly by the user. + * Usually there will only be a single instance of such a class. + * The name of the template is supposed + * to be replaced by the name of the specific HTML page e.g. baker. + * The order of methods might correspond to the order of thinking + * during implementation. + * @author Bernhard Kreling, <bernhard.kreling@h-da.de> + * @author Ralf Hahn, <ralf.hahn@h-da.de> + */ +class Kunde extends Page +{ + // to do: declare reference variables for members + // representing substructures/blocks + + /** + * Instantiates members (to be defined above). + * Calls the constructor of the parent i.e. page class. + * So, the database connection is established. + * @throws Exception + */ + protected function __construct() + { + parent::__construct(); + // to do: instantiate members representing substructures/blocks + } + + /** + * Cleans up whatever is needed. + * Calls the destructor of the parent i.e. page class. + * So, the database connection is closed. + */ + public function __destruct() + { + parent::__destruct(); + } + + /** + * Fetch all data that is necessary for later output. + * Data is returned in an array e.g. as associative array. + * @return array An array containing the requested data. + * This may be a normal array, an empty array or an associative array. + */ + protected function getViewData():array + { + + if (isset($_SESSION["orders"])) { + + $orders = $_SESSION["orders"]; + $queryString = ""; + + foreach ($orders as $orderingID) { + $queryString .= $orderingID.", "; + } + + $queryString = rtrim($queryString, ", "); + $query = "SELECT * FROM ordered_article WHERE ordering_id IN ({$queryString});"; + + + $resultSet = $this->_database->query($query); + $orderedArticleList = array(); + + while ($row = $resultSet->fetch_assoc()) { + + $orderedArticle = new OrderedArticle( + (int)$row["ordered_article_id"], (int)$row["ordering_id"], (int)$row["article_id"], + (int)$row["status"] + ); + + $orderedArticleList[$orderedArticle->getOrderedArticleId()] = $orderedArticle; + } + $resultSet->free_result(); + return $orderedArticleList; + } + + return array(); + } + + /** + * First the required data is fetched and then the HTML is + * assembled for output. i.e. the header is generated, the content + * of the page ("view") is inserted and -if available- the content of + * all views contained is generated. + * Finally, the footer is added. + * @return void + */ + protected function generateView():void + { + $data = $this->getViewData(); //NOSONAR ignore unused $data + $this->generatePageHeader('Kunde','./JS/Kunde.js', false); //to do: set optional parameters + + if (count($data) <= 0) { + echo <<< HTML + <section id="Kunde"> + <h2>Kunde</h2> + <p>No Orders!</p> + </section> +HTML; + $this->generatePageFooter(); + die(); + } + echo <<< HTML + <section id="Kunde"> + <h2>Kunde</h2> + <form id="orderForm" accept-charset="UTF-8" action="#" method="post">\n + <fieldset id="bestellung"> + <legend id="bestellung.legend">Bestellung X</legend> + <fieldset id="pizza" disabled> + <legend id="pizza.legend">Pizza Y</legend> + <label> + Bestellt + <input type="radio" name="ordArtID" value="0"> + </label> <br> + + <label> + Im Ofen + <input type="radio" name="ordArtID" value="1"> + </label> <br> + + <label> + Fertig + <input type="radio" name="ordArtID" value="2"> + </label> <br> + + <label> + Unterwegs + <input type="radio" name="ordArtID" value="3"> + </label> <br> + + <label> + Geliefert + <input type="radio" name="ordArtID" value="4"> + </label> + </fieldset>\n + </fieldset>\n + </form>\n + </section>\n +HTML; + + $this->generatePageFooter(); + } + + /** + * Processes the data that comes via GET or POST. + * If this page is supposed to do something with submitted + * data do it here. + * @return void + */ + protected function processReceivedData():void + { + parent::processReceivedData(); + // to do: call processReceivedData() for all members + } + + /** + * This main-function has the only purpose to create an instance + * of the class and to get all the things going. + * I.e. the operations of the class are called to produce + * the output of the HTML-file. + * The name "main" is no keyword for php. It is just used to + * indicate that function as the central starting point. + * To make it simpler this is a static function. That is you can simply + * call it without first creating an instance of the class. + * @return void + */ + public static function main():void + { + session_start(); + try { + $page = new Kunde(); + $page->processReceivedData(); + $page->generateView(); + } catch (Exception $e) { + //header("Content-type: text/plain; charset=UTF-8"); + header("Content-type: text/html; charset=UTF-8"); + echo $e->getMessage(); + } + } +} + +// This call is starting the creation of the page. +// That is input is processed and output is created. +Kunde::main(); + +// Zend standard does not like closing php-tag! +// PHP doesn't require the closing tag (it is assumed when the file ends). +// Not specifying the closing ? > helps to prevent accidents +// like additional whitespace which will cause session +// initialization to fail ("headers already sent"). +//? > diff --git a/src/Praktikum/Prak5/Kundenstatus.php b/src/Praktikum/Prak5/Kundenstatus.php new file mode 100644 index 0000000000000000000000000000000000000000..743f34fb91eac9470d83771d74cf1b2bfd2b75b7 --- /dev/null +++ b/src/Praktikum/Prak5/Kundenstatus.php @@ -0,0 +1,174 @@ +<?php declare(strict_types=1); +// UTF-8 marker äöüÄÖÜ߀ +/** + * Class PageTemplate for the exercises of the EWA lecture + * Demonstrates use of PHP including class and OO. + * Implements Zend coding standards. + * Generate documentation with Doxygen or phpdoc + * + * PHP Version 7.4 + * + * @file Kundenstatus.php + * @package Page Templates + * @author Bernhard Kreling, <bernhard.kreling@h-da.de> + * @author Ralf Hahn, <ralf.hahn@h-da.de> + * @version 3.1 + */ + +// to do: change name 'PageTemplate' throughout this file +require_once './Page.php'; +/** + * This is a template for top level classes, which represent + * a complete web page and which are called directly by the user. + * Usually there will only be a single instance of such a class. + * The name of the template is supposed + * to be replaced by the name of the specific HTML page e.g. baker. + * The order of methods might correspond to the order of thinking + * during implementation. + * @author Bernhard Kreling, <bernhard.kreling@h-da.de> + * @author Ralf Hahn, <ralf.hahn@h-da.de> + */ +class Kundenstatus extends Page +{ + // to do: declare reference variables for members + // representing substructures/blocks + + /** + * Instantiates members (to be defined above). + * Calls the constructor of the parent i.e. page class. + * So, the database connection is established. + * @throws Exception + */ + protected function __construct() + { + parent::__construct(); + // to do: instantiate members representing substructures/blocks + } + + /** + * Cleans up whatever is needed. + * Calls the destructor of the parent i.e. page class. + * So, the database connection is closed. + */ + public function __destruct() + { + parent::__destruct(); + } + + /** + * Fetch all data that is necessary for later output. + * Data is returned in an array e.g. as associative array. + * @return array An array containing the requested data. + * This may be a normal array, an empty array or an associative array. + */ + protected function getViewData() :array + { + if (isset($_SESSION["orders"])) { + + $customerOrders = $_SESSION["orders"]; + $queryString = ""; + + foreach ($customerOrders as $orderingID) { + $queryString .= $orderingID.", "; + } + + $queryString = rtrim($queryString, ", "); + + $query = "SELECT ordering.ordering_id, ordering.address, ordered_article_id, status, name, price + FROM ordered_article JOIN ordering ON ordered_article.ordering_id = ordering.ordering_id + JOIN article ON ordered_article.article_id = article.article_id + AND ordered_article.ordering_id IN ({$queryString});"; + + } else { + + $query = "SELECT ordering.ordering_id, ordering.address, ordered_article_id, status, name, price + FROM ordered_article JOIN ordering ON ordered_article.ordering_id = ordering.ordering_id + JOIN article ON ordered_article.article_id = article.article_id;"; + } + + $resultSet = $this->_database->query($query); + + if(mysqli_num_rows($resultSet) <= 0){ + return array(); + } + + $orders = array(); + while ($row = $resultSet->fetch_assoc()) { + + if (isset($orders[$row["ordering_id"]])) { + + $presentArray = $orders[$row["ordering_id"]]["OrderList"]; + $presentArray[] = ["Name" => $row["name"], "Price" => $row["price"], "Status" => $row["status"]]; + $orders[$row["ordering_id"]] = [ "Address" => $row["address"], "OrderList" => $presentArray]; + + } else { + + $orders[$row["ordering_id"]] = [ "Address" => $row["address"], "OrderList" => [ + $row["ordered_article_id"] => + ["Name" => $row["name"], "Price" => $row["price"], "Status" => $row["status"]] + ]]; + } + } + $resultSet->free_result(); + + return $orders; + } + + /** + * First the required data is fetched and then the HTML is + * assembled for output. i.e. the header is generated, the content + * of the page ("view") is inserted and -if available- the content of + * all views contained is generated. + * Finally, the footer is added. + * @return void + */ + protected function generateView():void + { + header("Content-Type: application/json; charset=UTF-8"); + + $data = $this->getViewData(); //NOSONAR ignore unused $data + $serializedData = json_encode($data); + echo $serializedData; + } + + protected function processReceivedData():void + { + parent::processReceivedData(); + } + + /** + * This main-function has the only purpose to create an instance + * of the class and to get all the things going. + * I.e. the operations of the class are called to produce + * the output of the HTML-file. + * The name "main" is no keyword for php. It is just used to + * indicate that function as the central starting point. + * To make it simpler this is a static function. That is you can simply + * call it without first creating an instance of the class. + * @return void + */ + public static function main():void + { + session_start(); + try { + $page = new Kundenstatus(); + $page->processReceivedData(); + $page->generateView(); + } catch (Exception $e) { + //header("Content-type: text/plain; charset=UTF-8"); + header("Content-type: text/html; charset=UTF-8"); + echo $e->getMessage(); + } + } +} + +// This call is starting the creation of the page. +// That is input is processed and output is created. +Kundenstatus::main(); + +// Zend standard does not like closing php-tag! +// PHP doesn't require the closing tag (it is assumed when the file ends). +// Not specifying the closing ? > helps to prevent accidents +// like additional whitespace which will cause session +// initialization to fail ("headers already sent"). +//? > diff --git a/src/Praktikum/Prak5/Page.php b/src/Praktikum/Prak5/Page.php new file mode 100644 index 0000000000000000000000000000000000000000..5c45859dfb0f4196b245aa46ef56d0aa33285d7d --- /dev/null +++ b/src/Praktikum/Prak5/Page.php @@ -0,0 +1,143 @@ +<?php declare(strict_types=1); +// UTF-8 marker äöüÄÖÜ߀ +/** + * Class Page for the exercises of the EWA lecture + * Demonstrates use of PHP including class and OO. + * Implements Zend coding standards. + * Generate documentation with Doxygen or phpdoc + * + * PHP Version 7.4 + * + * @file Page.php + * @package Page Templates + * @author Bernhard Kreling, <bernhard.kreling@h-da.de> + * @author Ralf Hahn, <ralf.hahn@h-da.de> + * @version 3.1 + */ + +/** + * This abstract class is a common base class for all + * HTML-pages to be created. + * It manages access to the database and provides operations + * for outputting header and footer of a page. + * Specific pages have to inherit from that class. + * Each derived class can use these operations for accessing the database + * and for creating the generic parts of a HTML-page. + * + * @author Bernhard Kreling, <bernhard.kreling@h-da.de> + * @author Ralf Hahn, <ralf.hahn@h-da.de> + */ +abstract class Page +{ + // --- ATTRIBUTES --- + + /** + * Reference to the MySQLi-Database that can be used + * by all operations of the class or inherited classes. + */ + protected MySQLi $_database; + + // --- OPERATIONS --- + + /** + * Connects to DB and stores + * the connection in member $_database. + * Needs name of DB, user, password. + */ + protected function __construct() + { + error_reporting(E_ALL); + + $host = "localhost"; + /********************************************/ + // This code switches from the the local installation (XAMPP) to the docker installation + if (gethostbyname('mariadb') != "mariadb") { // mariadb is known? + $host = "mariadb"; + } + /********************************************/ + + $this->_database = new MySQLi($host, "public", "public", "pizzaservice"); + + if ($this->_database->connect_errno) { + throw new Exception("Connect failed: " . $this->_database->connect_errno); + } + + // set charset to UTF8!! + if (!$this->_database->set_charset("utf8")) { + throw new Exception($this->_database->error); + } + } + + public function __destruct() // Closes the DB connection + { + $this->_database->close(); + } + + /** + * Generates the header section of the page. + * i.e. starting from the content type up to the body-tag. + * Takes care that all strings passed from outside + * are converted to safe HTML by htmlspecialchars. + * + * @param string $title $title is the text to be used as title of the page + * @param string $jsFile path to a java script file to be included, default is "" i.e. no java script file + * @param bool $autoreload true: auto reload the page every 5 s, false: not auto reload + * @return void + */ + protected function generatePageHeader(string $title = "", string $jsFile = "", bool $autoreload = false):void + { + $title = htmlspecialchars($title); + header("Content-type: text/html; charset=UTF-8"); + //-------------------------------- + if ($autoreload) { + header("Refresh: 10;"); + } + + //------------------------------------- + echo <<< HTML + <!DOCTYPE html> + <html lang="de"> + <head> + <meta charset="UTF-8"> + <title>{$title}</title> + </head> + <body> +HTML; + if (is_file($jsFile)) { + echo "<script type='text/javascript' src='{$jsFile}'></script>\n"; + } + + } + + /** + * Outputs the end of the HTML-file i.e. </body> etc. + * @return void + */ + protected function generatePageFooter():void + { + echo <<< HTML + </body> + </html> +HTML; + } + + /** + * Processes the data that comes in via GET or POST. + * If every derived page is supposed to do something common + * with submitted data do it here. + * E.g. checking the settings of PHP that + * influence passing the parameters (e.g. magic_quotes). + * @return void + */ + protected function processReceivedData():void + { + + } +} // end of class + +// Zend standard does not like closing php-tag! +// PHP doesn't require the closing tag (it is assumed when the file ends). +// Not specifying the closing ? > helps to prevent accidents +// like additional whitespace which will cause session +// initialization to fail ("headers already sent"). +//? > diff --git a/src/Praktikum/Prak5/img/pizzaAfterburner.png b/src/Praktikum/Prak5/img/pizzaAfterburner.png new file mode 100644 index 0000000000000000000000000000000000000000..2e1ec7b18078ec437044123e1d22f7d17f330a0e Binary files /dev/null and b/src/Praktikum/Prak5/img/pizzaAfterburner.png differ diff --git a/src/Praktikum/Prak5/img/pizzaSalami.png b/src/Praktikum/Prak5/img/pizzaSalami.png new file mode 100644 index 0000000000000000000000000000000000000000..a5e3173732265805437e6003bf8bc17158a3b192 Binary files /dev/null and b/src/Praktikum/Prak5/img/pizzaSalami.png differ diff --git a/src/Praktikum/Prak5/img/pizzaVegetaria.png b/src/Praktikum/Prak5/img/pizzaVegetaria.png new file mode 100644 index 0000000000000000000000000000000000000000..7c4185fc015831c6d40db61c9cf7d854dc4741d9 Binary files /dev/null and b/src/Praktikum/Prak5/img/pizzaVegetaria.png differ diff --git a/src/Praktikum/Prak5/index.php b/src/Praktikum/Prak5/index.php new file mode 100644 index 0000000000000000000000000000000000000000..19e65e0300b9599f3fe7378f718a8f6ecb69cea1 --- /dev/null +++ b/src/Praktikum/Prak5/index.php @@ -0,0 +1,146 @@ +<?php declare(strict_types=1); +// UTF-8 marker äöüÄÖÜ߀ +/** + * Class PageTemplate for the exercises of the EWA lecture + * Demonstrates use of PHP including class and OO. + * Implements Zend coding standards. + * Generate documentation with Doxygen or phpdoc + * + * PHP Version 7.4 + * + * @file PageTemplate.php + * @package Page Templates + * @author Bernhard Kreling, <bernhard.kreling@h-da.de> + * @author Ralf Hahn, <ralf.hahn@h-da.de> + * @version 3.1 + */ + +// to do: change name 'PageTemplate' throughout this file +require_once './Page.php'; + +/** + * This is a template for top level classes, which represent + * a complete web page and which are called directly by the user. + * Usually there will only be a single instance of such a class. + * The name of the template is supposed + * to be replaced by the name of the specific HTML page e.g. baker. + * The order of methods might correspond to the order of thinking + * during implementation. + * @author Bernhard Kreling, <bernhard.kreling@h-da.de> + * @author Ralf Hahn, <ralf.hahn@h-da.de> + */ +class Index extends Page +{ + // to do: declare reference variables for members + // representing substructures/blocks + + /** + * Instantiates members (to be defined above). + * Calls the constructor of the parent i.e. page class. + * So, the database connection is established. + * @throws Exception + */ + protected function __construct() + { + parent::__construct(); + // to do: instantiate members representing substructures/blocks + } + + /** + * Cleans up whatever is needed. + * Calls the destructor of the parent i.e. page class. + * So, the database connection is closed. + */ + public function __destruct() + { + parent::__destruct(); + } + + /** + * Fetch all data that is necessary for later output. + * Data is returned in an array e.g. as associative array. + * @return array An array containing the requested data. + * This may be a normal array, an empty array or an associative array. + */ + protected function getViewData():array + { + return array("Bestellung" => "./Bestellung.php", "Baecker" => "./Baecker.php", + "Kunde" => "./Kunde.php", "Fahrer" => "./Fahrer.php", "Kundenstatus" => "./Kundenstatus.php"); + } + + /** + * First the required data is fetched and then the HTML is + * assembled for output. i.e. the header is generated, the content + * of the page ("view") is inserted and -if available- the content of + * all views contained is generated. + * Finally, the footer is added. + * @return void + */ + protected function generateView():void + { + $data = $this->getViewData(); //NOSONAR ignore unused $data + $this->generatePageHeader('Übersicht'); //to do: set optional parameters + // to do: output view of this page + echo <<< HTML + + <header> + <h1>Übersicht</h1> + </header> + + <ul> + HTML; + foreach ($data as $linkKey => $linkElement) { + echo "\n<li> <a href='{$linkElement}' target='_blank'>$linkKey</a> </li>"; + } + echo "\n</ul>\n"; + + $this->generatePageFooter(); + } + + /** + * Processes the data that comes via GET or POST. + * If this page is supposed to do something with submitted + * data do it here. + * @return void + */ + protected function processReceivedData():void + { + parent::processReceivedData(); + // to do: call processReceivedData() for all members + } + + /** + * This main-function has the only purpose to create an instance + * of the class and to get all the things going. + * I.e. the operations of the class are called to produce + * the output of the HTML-file. + * The name "main" is no keyword for php. It is just used to + * indicate that function as the central starting point. + * To make it simpler this is a static function. That is you can simply + * call it without first creating an instance of the class. + * @return void + */ + public static function main():void + { + try { + $page = new Index(); + $page->processReceivedData(); + $page->generateView(); + } catch (Exception $e) { + //header("Content-type: text/plain; charset=UTF-8"); + header("Content-type: text/html; charset=UTF-8"); + echo $e->getMessage(); + } + } +} + +// This call is starting the creation of the page. +// That is input is processed and output is created. +Index::main(); + +// Zend standard does not like closing php-tag! +// PHP doesn't require the closing tag (it is assumed when the file ends). +// Not specifying the closing ? > helps to prevent accidents +// like additional whitespace which will cause session +// initialization to fail ("headers already sent"). +//? >