From 882fb9fe641b87adb2ecf9285de872164c69afa8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Johannes=20Ke=C3=9Fler?= Date: Wed, 26 Oct 2022 13:13:17 +0200 Subject: [PATCH] current work in progress --- webroot/index.php | 2 +- ...emInput.class.php => manageItem.class.php} | 48 ++++++----- webroot/lib/manageReceipt.class.php | 56 +++++++++++++ webroot/lib/market.class.php | 78 +++++++++++++++++ webroot/lib/summoner.class.php | 83 +++++++++++++++++-- webroot/view/_menu.php | 2 +- webroot/view/_message.php | 10 +-- webroot/view/asset/style.css | 21 +++++ webroot/view/item/item.html | 46 ++++------ webroot/view/item/item.php | 69 +++++++++++---- webroot/view/receipt/receipt.html | 27 ++++++ webroot/view/receipt/receipt.php | 58 +++++++++++++ 12 files changed, 420 insertions(+), 80 deletions(-) rename webroot/lib/{itemInput.class.php => manageItem.class.php} (55%) create mode 100644 webroot/lib/manageReceipt.class.php create mode 100644 webroot/lib/market.class.php create mode 100644 webroot/view/receipt/receipt.html create mode 100644 webroot/view/receipt/receipt.php diff --git a/webroot/index.php b/webroot/index.php index 6bef201..c4f2336 100644 --- a/webroot/index.php +++ b/webroot/index.php @@ -26,7 +26,7 @@ ini_set('error_reporting',-1); // E_ALL & E_STRICT date_default_timezone_set(TIMEZONE); # check request -$_urlToParse = filter_var($_SERVER['QUERY_STRING'],FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); +$_urlToParse = filter_var($_SERVER['QUERY_STRING'],FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW); if(!empty($_urlToParse)) { # see http://de2.php.net/manual/en/regexp.reference.unicode.php if(preg_match('/[\p{C}\p{M}\p{Sc}\p{Sk}\p{So}\p{Zl}\p{Zp}]/u',$_urlToParse) === 1) { diff --git a/webroot/lib/itemInput.class.php b/webroot/lib/manageItem.class.php similarity index 55% rename from webroot/lib/itemInput.class.php rename to webroot/lib/manageItem.class.php index ea84627..a80eb34 100644 --- a/webroot/lib/itemInput.class.php +++ b/webroot/lib/manageItem.class.php @@ -19,9 +19,9 @@ */ /** - * Process the input data from adding or edit an item + * Manage an item */ -class ItemInput { +class ManageItem { /** * The DB object * @@ -30,11 +30,11 @@ class ItemInput { private mysqli $_DB; /** - * The data for this item + * The validated and cleaned data from the input * * @var array */ - private array $_data; + private array $_submitData; /** * @param mysqli $databaseConnectionObject @@ -43,26 +43,34 @@ class ItemInput { $this->_DB = $databaseConnectionObject; } - /** - * Check for required fields, valid input and prepare the data - * @param array $data - * @return array + /** + * Process the validated data from validateAndPrepare */ - public function validateAndPrepare(array $data): array { - $status = true; - $error = array(); + public function create(array $data) { + + try { + $this->DB->begin_transaction(MYSQLI_TRANS_START_READ_WRITE); + // those are dependent + $_market = $this->_resolveMarket(); + //$_receipt = $this->_resolveReceipt(); + $_product = $this->_resolveProduct(); + $_list = $this->_resolveList(); - if(!empty($data)) { - if(!isset($data['receiptdate']) || empty($data['receiptdate']) || !Summoner::validate($data['receiptdate'], 'datetime')) { - $status = false; - $error[] = array('receiptdata' => ''); - } + $this->DB->commit(); + } catch (Exception $e) { + $this->DB->rollback(); } - return array( - 'status' => $status, - 'error' => $error - ); + + } + + private function _resolveReceipt() { + $_receiptDate = DateTime::createFromFormat('Y-m-d\TH:i', $this->_submitData['receiptdate']); + + $_receiptName = ''; + if(empty($this->_submitData['receipt'])) { + $_receiptName = $this->_submitData['market']; + } } } diff --git a/webroot/lib/manageReceipt.class.php b/webroot/lib/manageReceipt.class.php new file mode 100644 index 0000000..7295be2 --- /dev/null +++ b/webroot/lib/manageReceipt.class.php @@ -0,0 +1,56 @@ +. + */ + + +/** + * Manage a receipt or many receipts + */ +class ManageReceipt { + /** + * The DB object + * + * @var mysqli + */ + private mysqli $_DB; + + /** + * The validated and cleaned data from the input + * + * @var array + */ + private array $_data; + + /** + * @param mysqli $databaseConnectionObject + */ + public function __construct(mysqli $databaseConnectionObject) { + $this->_DB = $databaseConnectionObject; + } + + public function load(string $id):array { + $ret = array(); + + return $ret; + } + + public function create(array $data) { + + } +} \ No newline at end of file diff --git a/webroot/lib/market.class.php b/webroot/lib/market.class.php new file mode 100644 index 0000000..8a92712 --- /dev/null +++ b/webroot/lib/market.class.php @@ -0,0 +1,78 @@ +. + */ + +/** + * Market object + */ +class Market { + /** + * The DB object + * + * @var mysqli + */ + private mysqli $_DB; + + /** + * The ID of the marktet + * + * @var string + */ + private string $_id; + + /** + * The name of the market + * + * @var string + */ + private string $_name; + + /** + * @param mysqli $databaseConnectionObject + */ + public function __construct(mysqli $databaseConnectionObject) { + $this->_DB = $databaseConnectionObject; + } + + /** + * Load market by name. + * If not not found and create is true, create a new one + */ + public function loadByName(string $name): void { + if(DEBUG) error_log("[DEBUG] ".__METHOD__." lookup markted by name: ".var_export($name,true)); + + if(!empty($name)) { + $queryStr = "SELECT id,name FROM `".DB_PREFIX."_market` + WHERE name LIKE '".$this->_DB->real_escape_string($name)."'"; + if(QUERY_DEBUG) error_log("[QUERY] ".__METHOD__." query: ".var_export($queryStr,true)); + try { + $query = $this->_DB->query($queryStr); + if($query !== false && $query->num_rows > 0) { + if (($result = $query->fetch_assoc()) != false) { + $this->_name = $result['name']; + $this->_id = $result['id']; + } + } + } catch (Exception $e) { + error_log("[ERROR] ".__METHOD__." mysql catch: ".$e->getMessage()); + } + } + } + +} \ No newline at end of file diff --git a/webroot/lib/summoner.class.php b/webroot/lib/summoner.class.php index deeba4c..fef7393 100644 --- a/webroot/lib/summoner.class.php +++ b/webroot/lib/summoner.class.php @@ -35,7 +35,8 @@ class Summoner { * @return bool * * @see http://de.php.net/manual/en/regexp.reference.unicode.php - * http://www.sql-und-xml.de/unicode-database/#pc + * https://www.sql-und-xml.de/unicode-database/#kategorien + * https://en.wikipedia.org/wiki/Unicode_character_property * * the pattern replaces all that is allowed. the correct result after * the replace should be empty, otherwise are there chars which are not @@ -71,36 +72,45 @@ class Summoner { case 'nospace': // text without any whitespace and special chars $pattern = '/[\p{L}\p{N}]/u'; - break; + break; case 'nospaceP': // text without any whitespace and special chars // but with Punctuation other # http://www.sql-und-xml.de/unicode-database/po.html $pattern = '/[\p{L}\p{N}\p{Po}\-]/u'; - break; + break; case 'digit': // only numbers and digit // warning with negative numbers... $pattern = '/[\p{N}\-]/'; - break; + break; + + case 'float': + if(filter_var($input,FILTER_VALIDATE_FLOAT) !== false) { + return true; + } + else { + return false; + } + break; case 'pageTitle': // text with whitespace and without special chars // but with Punctuation $pattern = '/[\p{L}\p{N}\p{Po}\p{Z}\s-]/u'; - break; + break; # strange. the \p{M} is needed.. don't know why.. case 'filename': $pattern = '/[\p{L}\p{N}\p{M}\-_\.\p{Zs}]/u'; - break; + break; case 'shortlink': // special char string based on https://www.jwz.org/base64-shortlinks/ $pattern = '/[\p{L}\p{N}\-_]/u'; - break; + break; case 'datetime': // based on the format eg. 2022-09-25T22:00 @@ -209,4 +219,63 @@ class Summoner { static function ifset(array $array, string $key) { return $array[$key] ?? ''; } + + /** + * Takes the input from a form submission key=>value + * loops through every entry. Checks if key matches + * inputname_type_req + * + * inputname = the name of the input + * type = the type to validate against + * req = keyword to make it required + * + * returns an array of + * data => the cleaned up data + * status => bool + * error = array which input key has an error + * + * @param array $data + * @return array + */ + static function validateAndPrepare(array $data): array { + $status = false; + $error = array(); + $preparedData = array(); + + if(!empty($data)) { + foreach($data as $key=>$value) { + $keyData = explode("_", $key); + $type = false; + if(isset($keyData[1])) { + $type = $keyData[1]; + } + $req = false; + if(isset($keyData[2]) && !empty($keyData[2]) && $keyData[2] == 'req') { + $req = true; + } + + if($req && empty($value)) { + $error[$key][] = 'Required'; + continue; + } + + if(!empty($value) && !Summoner::validate($value, $type)) { + $error[$key][] = 'Invalid input'; + continue; + } + + $preparedData[$keyData[0]] = $value; + } + } + + if(empty($error)) { + $status = true; + } + + return array( + 'data' => $preparedData, + 'status' => $status, + 'error' => $error + ); + } } diff --git a/webroot/view/_menu.php b/webroot/view/_menu.php index f2dda07..3d497f5 100644 --- a/webroot/view/_menu.php +++ b/webroot/view/_menu.php @@ -1,5 +1,5 @@ diff --git a/webroot/view/_message.php b/webroot/view/_message.php index 08fbe1e..5739255 100644 --- a/webroot/view/_message.php +++ b/webroot/view/_message.php @@ -18,20 +18,20 @@ * along with this program. If not, see . */ if(isset($TemplateData['message']['content']) && !empty($TemplateData['message']['content'])) { - $cssClass = 'blue-168'; + $cssClass = 'blue'; $headline = 'Info'; if(isset($TemplateData['message']['status'])) { switch($TemplateData['message']['status']) { case 'error': - $cssClass = 'red-168'; + $cssClass = 'red'; $headline = 'Error'; break; case 'warning': - $cssClass = 'yellow-168'; + $cssClass = 'yellow'; $headline = 'Warning'; break; case 'success': - $cssClass = 'green-168'; + $cssClass = 'green'; $headline = 'Success'; break; @@ -41,7 +41,7 @@ if(isset($TemplateData['message']['content']) && !empty($TemplateData['message'] } } ?> -
+

diff --git a/webroot/view/asset/style.css b/webroot/view/asset/style.css index e69de29..48f862f 100644 --- a/webroot/view/asset/style.css +++ b/webroot/view/asset/style.css @@ -0,0 +1,21 @@ +.alert { + border: 1px solid #9b4dca; + padding: 1em 1em 0 1em; + margin-top: 1em; + margin-bottom: 1em; +} + +.alert.red { + border: 1px solid red; +} + +input.error { + border: 1px solid red; +} + +.inputErrorText { + display: inline-block; + position: relative; + top: -1em; + color: red; +} \ No newline at end of file diff --git a/webroot/view/item/item.html b/webroot/view/item/item.html index 2901733..c287629 100644 --- a/webroot/view/item/item.html +++ b/webroot/view/item/item.html @@ -1,62 +1,50 @@
- - + + - - - - - - - - - - - + - + - + - + - + - + - +
diff --git a/webroot/view/item/item.php b/webroot/view/item/item.php index e0d6b87..8cf62bb 100644 --- a/webroot/view/item/item.php +++ b/webroot/view/item/item.php @@ -1,11 +1,36 @@ . + */ + +require_once 'lib/manageItem.class.php'; +$ManageItem = new ManageItem($DB); $_id = false; if(isset($_GET['id']) && !empty($_GET['id'])) { $_id = trim($_GET['id']); - $_id = Summoner::validate($_id,'nospace') ? $_id : false; + $_id = Summoner::validate($_id,'digit') ? $_id : false; +} + +$_rid = false; +if(isset($_GET['rid']) && !empty($_GET['rid'])) { + $_rid = trim($_GET['rid']); + $_rid = Summoner::validate($_rid,'digit') ? $_rid : false; } $TemplateData['pageTitle'] = 'New item'; @@ -14,22 +39,32 @@ if(!empty($_id)) { } $TemplateData['editData'] = array(); +$TemplateData['errorData'] = array(); -$TemplateData['message']['content'] = ""; -$TemplateData['message']['status'] = ""; - -if(isset($_POST['fdata']) && !empty($_POST['fdata']) && isset($_POST['submitForm'])) { - $fdata = $_POST['fdata']; - if (!empty($fdata)) { +$TemplateData['message']['content'] = ''; +$TemplateData['message']['status'] = ''; +if(!empty($_rid)) { + if (isset($_POST['fdata']) && !empty($_POST['fdata']) && isset($_POST['submitForm'])) { + $fdata = $_POST['fdata']; + if (!empty($fdata)) { + $do = Summoner::validateAndPrepare($fdata); + if ($do['status'] === true) { + $do = $ManageItem->create($do['data']); - var_dump($fdata); - - $ItemInput->validateAndPrepare($fdata); - - } else { - $TemplateData['message']['content'] = "Collection could not be loaded."; - $TemplateData['message']['status'] = "error"; - } + } else { + $TemplateData['message']['status'] = 'error'; + $TemplateData['message']['content'] = 'Invalid or missing input'; + $TemplateData['errorData'] = $do['error']; + } + } else { + $TemplateData['message']['status'] = 'error'; + $TemplateData['message']['content'] = 'Empty submission data'; + } + } +} +else { + $TemplateData['message']['status'] = 'error'; + $TemplateData['message']['content'] = 'No receipt id given.'; } diff --git a/webroot/view/receipt/receipt.html b/webroot/view/receipt/receipt.html new file mode 100644 index 0000000..412ab43 --- /dev/null +++ b/webroot/view/receipt/receipt.html @@ -0,0 +1,27 @@ +
+
+ + + + + + + + + + + + + '.implode(', ', $TemplateData['errorData']['market_text_req']).''; ?> + + + + + + +
+
diff --git a/webroot/view/receipt/receipt.php b/webroot/view/receipt/receipt.php new file mode 100644 index 0000000..e3908ff --- /dev/null +++ b/webroot/view/receipt/receipt.php @@ -0,0 +1,58 @@ +. + */ +require_once 'lib/manageReceipt.class.php'; +$ManageReceipt = new ManageReceipt($DB); + + +$_id = false; +if(isset($_GET['id']) && !empty($_GET['id'])) { + $_id = trim($_GET['id']); + $_id = Summoner::validate($_id,'digit') ? $_id : false; +} + +$TemplateData['pageTitle'] = 'New receipt'; +if(!empty($_id)) { + $TemplateData['pageTitle'] = 'Edit receipt'; +} + +$TemplateData['editData'] = array(); +$TemplateData['errorData'] = array(); + +$TemplateData['message']['content'] = ''; +$TemplateData['message']['status'] = ''; + +if (isset($_POST['fdata']) && !empty($_POST['fdata']) && isset($_POST['submitForm'])) { + $fdata = $_POST['fdata']; + if (!empty($fdata)) { + + $do = Summoner::validateAndPrepare($fdata); + if ($do['status'] === true) { + $do = $ManageReceipt->create($do['data']); + + } else { + $TemplateData['message']['status'] = 'error'; + $TemplateData['message']['content'] = 'Invalid or missing input'; + $TemplateData['errorData'] = $do['error']; + } + } else { + $TemplateData['message']['status'] = 'error'; + $TemplateData['message']['content'] = 'Empty submission data'; + } +} \ No newline at end of file -- 2.39.5