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) {
+++ /dev/null
-<?php
-/**
- * emere
- *
- * Copyright (C) 2022 Johannes 'Banana' Keßler
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-/**
- * Process the input data from adding or edit an item
- */
-class ItemInput {
- /**
- * The DB object
- *
- * @var mysqli
- */
- private mysqli $_DB;
-
- /**
- * The data for this item
- *
- * @var array
- */
- private array $_data;
-
- /**
- * @param mysqli $databaseConnectionObject
- */
- public function __construct(mysqli $databaseConnectionObject) {
- $this->_DB = $databaseConnectionObject;
- }
-
- /**
- * Check for required fields, valid input and prepare the data
- * @param array $data
- * @return array
- */
- public function validateAndPrepare(array $data): array {
- $status = true;
- $error = array();
-
-
- if(!empty($data)) {
- if(!isset($data['receiptdate']) || empty($data['receiptdate']) || !Summoner::validate($data['receiptdate'], 'datetime')) {
- $status = false;
- $error[] = array('receiptdata' => '');
- }
- }
-
- return array(
- 'status' => $status,
- 'error' => $error
- );
- }
-}
--- /dev/null
+<?php
+/**
+ * emere
+ *
+ * Copyright (C) 2022 Johannes 'Banana' Keßler
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * Manage an item
+ */
+class ManageItem {
+ /**
+ * The DB object
+ *
+ * @var mysqli
+ */
+ private mysqli $_DB;
+
+ /**
+ * The validated and cleaned data from the input
+ *
+ * @var array
+ */
+ private array $_submitData;
+
+ /**
+ * @param mysqli $databaseConnectionObject
+ */
+ public function __construct(mysqli $databaseConnectionObject) {
+ $this->_DB = $databaseConnectionObject;
+ }
+
+ /**
+ * Process the validated data from validateAndPrepare
+ */
+ 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();
+
+ $this->DB->commit();
+ } catch (Exception $e) {
+ $this->DB->rollback();
+ }
+
+
+ }
+
+ private function _resolveReceipt() {
+ $_receiptDate = DateTime::createFromFormat('Y-m-d\TH:i', $this->_submitData['receiptdate']);
+
+ $_receiptName = '';
+ if(empty($this->_submitData['receipt'])) {
+ $_receiptName = $this->_submitData['market'];
+ }
+ }
+}
--- /dev/null
+<?php
+/**
+ * emere
+ *
+ * Copyright (C) 2022 Johannes 'Banana' Keßler
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+
+/**
+ * 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
--- /dev/null
+<?php
+/**
+ * emere
+ *
+ * Copyright (C) 2022 Johannes 'Banana' Keßler
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+/**
+ * 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
* @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
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
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
+ );
+ }
}
<?php
?>
<nav>
- <a href="index.php">Home</a> | <a href="index.php?p=item">New</a> | <a href="index.php?p=list">Search</a>
+ <a href="index.php">Home</a> | <a href="index.php?p=receipt">New</a> | <a href="index.php?p=list">Search</a>
</nav>
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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;
}
}
?>
- <div class="<?php echo $cssClass; ?>">
+ <div class="alert <?php echo $cssClass; ?>">
<h3><?php echo $headline; ?></h3>
<p><?php echo $TemplateData['message']['content']; ?></p>
</div>
+.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
<form method="post">
<fieldset>
- <label for="receipt">Receipt <small>Just leave it blank to create a new based on date and market name.</small></label>
- <input name="fdata[receipt]" id="receipt" type="text" list="receiptList" autocomplete="off"
- value="<?php echo Summoner::ifset($TemplateData['editData'], 'receipt'); ?>" />
+ <label for="receipt">Receipt</label>
+ <input name="fdata[receipt_text]" id="receipt" type="text" list="receiptList" autocomplete="off"
+ value="<?php echo Summoner::ifset($TemplateData['editData'], 'receipt'); ?>" />
<datalist id="receiptList">
<option>Rewe</option>
<option>Lidl</option>
</datalist>
- <label for="receiptdate">Date and time*</label>
- <input name="fdata[receiptdate]" id="receiptdate" type="datetime-local" autocomplete="off" required
- value="<?php echo Summoner::ifset($TemplateData['editData'], 'receiptdate'); ?>" />
-
- <label for="market">Market*</label>
- <input name="fdata[market]" id="market" type="text" list="marketList" autocomplete="off" required
- value="<?php echo Summoner::ifset($TemplateData['editData'], 'market'); ?>" />
- <datalist id="marketList">
- <option>Rewe</option>
- <option>Lidl</option>
- </datalist>
-
<label for="product">Product*</label>
- <input name="fdata[product]" id="product" type="text" list="productList" autocomplete="off" required
- value="<?php echo Summoner::ifset($TemplateData['editData'], 'product'); ?>"/>
+ <input name="fdata[product_text_req]" id="product" type="text" list="productList" autocomplete="off" required
+ value="<?php echo Summoner::ifset($TemplateData['editData'], 'product'); ?>"/>
<datalist id="productList">
<option>Rewe</option>
<option>Lidl</option>
</datalist>
<label for="manufacturer">Manufacturer*</label>
- <input name="fdata[manufacturer]" id="manufacturer" type="text" list="manufacturerList" autocomplete="off" required
- value="<?php echo Summoner::ifset($TemplateData['editData'], 'manufacturer'); ?>"/>
+ <input name="fdata[manufacturer_text_req]" id="manufacturer" type="text" list="manufacturerList" autocomplete="off" required
+ value="<?php echo Summoner::ifset($TemplateData['editData'], 'manufacturer'); ?>"/>
<datalist id="manufacturerList">
<option>Rewe</option>
<option>Lidl</option>
</datalist>
<label for="weight">Weight(g)</label>
- <input name="fdata[weight]" id="weight" type="number" autocomplete="off" lang="<?php echo NUMBER_INPUT_LANG; ?>"
- value="<?php echo Summoner::ifset($TemplateData['editData'], 'weight'); ?>"/>
+ <input name="fdata[weight_digit]" id="weight" type="number" autocomplete="off" lang="<?php echo NUMBER_INPUT_LANG; ?>"
+ value="<?php echo Summoner::ifset($TemplateData['editData'], 'weight'); ?>"/>
<label for="itemcount">Itemcount</label>
- <input name="fdata[itemcount]" id="itemcount" type="number" autocomplete="off" lang="<?php echo NUMBER_INPUT_LANG; ?>"
- value="<?php echo Summoner::ifset($TemplateData['editData'], 'itemcount'); ?>"/>
+ <input name="fdata[itemcount_digit]" id="itemcount" type="number" autocomplete="off" lang="<?php echo NUMBER_INPUT_LANG; ?>"
+ value="<?php echo Summoner::ifset($TemplateData['editData'], 'itemcount'); ?>"/>
<label for="price">Price*</label>
- <input name="fdata[price]" id="price" type="number" autocomplete="off" required
- lang="<?php echo NUMBER_INPUT_LANG; ?>" step="0.01"
- value="<?php echo Summoner::ifset($TemplateData['editData'], 'price'); ?>"/>
+ <input name="fdata[price_float]" id="price" type="number" autocomplete="off" required
+ lang="<?php echo NUMBER_INPUT_LANG; ?>" step="0.01"
+ value="<?php echo Summoner::ifset($TemplateData['editData'], 'price'); ?>"/>
<label for="catalog">Catalog</label>
- <input name="fdata[catalog]" id="catalog" type="text" list="catalogList" autocomplete="off"
- value="<?php echo Summoner::ifset($TemplateData['editData'], 'catalog'); ?>"/>
+ <input name="fdata[catalog_text]" id="catalog" type="text" list="catalogList" autocomplete="off"
+ value="<?php echo Summoner::ifset($TemplateData['editData'], 'catalog'); ?>"/>
<datalist id="catalogList">
<option>Rewe</option>
<option>Lidl</option>
</datalist>
- <input type="submit" class="tui-button" value="Save" name="submitForm" />
+ <input type="submit" class="button" value="save" name="submitForm" />
</fieldset>
</form>
<?php
-require_once 'lib/itemInput.class.php';
-$ItemInput = new ItemInput($DB);
+/**
+ * emere
+ *
+ * Copyright (C) 2022 Johannes 'Banana' Keßler
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+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';
}
$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.';
}
--- /dev/null
+<form method="post">
+ <fieldset>
+ <label for="receipt">Receipt <small>Just leave it blank to create a new based on date and market name.</small></label>
+ <input name="fdata[receipt_text]" id="receipt" type="text" list="receiptList" autocomplete="off"
+ value="<?php echo Summoner::ifset($TemplateData['editData'], 'receipt'); ?>" />
+ <datalist id="receiptList">
+ <option>Rewe</option>
+ <option>Lidl</option>
+ </datalist>
+
+ <label for="receiptdate">Date and time*</label>
+ <input name="fdata[receiptdate_datetime_req]" id="receiptdate" type="datetime-local" autocomplete="off" required
+ value="<?php echo Summoner::ifset($TemplateData['editData'], 'receiptdate'); ?>" />
+
+ <label for="market">Market*</label>
+ <input name="fdata[market_text_req]" id="market" type="text" list="marketList" autocomplete="off"
+ value="<?php echo Summoner::ifset($TemplateData['editData'], 'market'); ?>"
+ class="<?php if(Summoner::ifset($TemplateData['errorData'], 'market_text_req')) echo 'error' ?>" />
+ <?php if(Summoner::ifset($TemplateData['errorData'], 'market_text_req')) echo '<small class="inputErrorText">'.implode(', ', $TemplateData['errorData']['market_text_req']).'</small>'; ?>
+ <datalist id="marketList">
+ <option>Rewe</option>
+ <option>Lidl</option>
+ </datalist>
+
+ <input type="submit" class="button" value="save" name="submitForm" />
+ </fieldset>
+</form>
--- /dev/null
+<?php
+/**
+ * emere
+ *
+ * Copyright (C) 2022 Johannes 'Banana' Keßler
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+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