Commit e1f10e56 authored by Carsten  Rose's avatar Carsten Rose

Implements #11118 STORE_VAR {{randomUniq:V}}

parent 9375f88f
Pipeline #3766 passed with stages
in 4 minutes and 5 seconds
......@@ -255,7 +255,10 @@ Store: *VARS* - V
+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
| Name | Explanation |
+=========================+============================================================================================================================================+
| random | Random string with length of 32 alphanum chars (lower & upper case). This is variable is always filled. |
| random | Random string with length of 32 alphanum chars (lower & upper case). This variable is always filled. Each access gives a new value. |
+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
| randomUniq | Like {{random:V}} but it's guaranteed that it's uniq. Optional: as *default* define an expiration time. |
| | Example: ``{{randomUniq:V}}``, ``{{randomUniq:V:::2020-12-15}}``, ``{{randomUniq:V:::+ 10 sec}}`` (Relative: sec, min, day). |
+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
| slaveId | see :ref:`slave-id` |
+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
......
......@@ -86,7 +86,7 @@ Store variables
.. note::
Syntax: {{ variable name : :ref:`store` : :ref:`sanitize-class` : :ref:`variable-escape` : :ref:`variable-default` : :ref:`variable-type-message-violate` }}
{{ *variable name* : :ref:`store` : :ref:`sanitize-class` : :ref:`variable-escape` : :ref:`variable-default` : :ref:`variable-type-message-violate` }}
Example::
......
......@@ -724,6 +724,7 @@ const SIP_EXCLUDE_XDEBUG_SESSION_START = 'XDEBUG_SESSION_START';
const ACTION_KEYWORD_SLAVE_ID = 'slaveId';
const VAR_RANDOM = 'random';
const VAR_RANDOM_UNIQ = 'randomUniq';
const VAR_FILE_DESTINATION = 'fileDestination';
const VAR_SLAVE_ID = ACTION_KEYWORD_SLAVE_ID;
const VAR_FILENAME = 'filename'; // Original filename of an uploaded file.
......
......@@ -392,7 +392,8 @@ class Evaluate {
$typeMessageViolate = ($arrToken[VAR_INDEX_MESSAGE] === null || $arrToken[VAR_INDEX_MESSAGE] === '') ? SANITIZE_TYPE_MESSAGE_VIOLATE_CLASS : $arrToken[VAR_INDEX_MESSAGE];
// search for value in stores
$value = $this->store::getVar($arrToken[VAR_INDEX_VALUE], $arrToken[VAR_INDEX_STORE], $arrToken[VAR_INDEX_SANATIZE], $foundInStore, $typeMessageViolate);
$value = $this->store::getVar($arrToken[VAR_INDEX_VALUE], $arrToken[VAR_INDEX_STORE], $arrToken[VAR_INDEX_SANATIZE],
$foundInStore, $typeMessageViolate, $arrToken[VAR_INDEX_DEFAULT]);
// escape ticks
if (is_string($value)) {
......
......@@ -9,12 +9,12 @@
namespace IMATHUZH\Qfq\Core\Store;
use IMATHUZH\Qfq\Core\Database\Database;
use IMATHUZH\Qfq\Core\Helper\HelperFile;
use IMATHUZH\Qfq\Core\Helper\KeyValueStringParser;
use IMATHUZH\Qfq\Core\Helper\Logger;
use IMATHUZH\Qfq\Core\Helper\OnArray;
use IMATHUZH\Qfq\Core\Helper\Sanitize;
use IMATHUZH\Qfq\Core\Helper\Support;
use IMATHUZH\Qfq\Core\Helper\HelperFile;
/*
* Stores:
......@@ -296,7 +296,7 @@ class Store {
$config[SYSTEM_SEND_E_MAIL] = $config[SYSTEM_EXT_PATH] . '/Classes/External/sendEmail';
// Make path absolute
foreach ([SYSTEM_MAIL_LOG, SYSTEM_QFQ_LOG, SYSTEM_SQL_LOG] AS $key) {
foreach ([SYSTEM_MAIL_LOG, SYSTEM_QFQ_LOG, SYSTEM_SQL_LOG] as $key) {
if (!empty($config[$key]) && $config[$key][0] != '/') {
$config[$key] = HelperFile::joinPathFilename($config[SYSTEM_SITE_PATH], $config[$key]);
}
......@@ -677,9 +677,11 @@ class Store {
* @return string|array a) if found: value, b) false. STORE_EXTRA returns an array for the given key.
* @throws \CodeException
* @throws \UserFormException SANITIZE_TYPE_MESSAGE_VIOLATE_ZERO | SANITIZE_TYPE_MESSAGE_VIOLATE_EMPTY | SANITIZE_TYPE_MESSAGE_VIOLATE_CLASS
* @throws \UserReportException
* @throws \DbException
*/
public static function getVar($key, $useStores = STORE_USE_DEFAULT, $sanitizeClass = '', &$foundInStore = '',
$typeMessageViolate = SANITIZE_TYPE_MESSAGE_VIOLATE_CLASS) {
$typeMessageViolate = SANITIZE_TYPE_MESSAGE_VIOLATE_CLASS, $default = '') {
// no store specified?
if ($useStores === "" || $useStores === null) {
......@@ -713,6 +715,8 @@ class Store {
case STORE_VAR:
if ($finalKey === VAR_RANDOM) {
return Support::randomAlphaNum(RANDOM_LENGTH);
} elseif ($finalKey === VAR_RANDOM_UNIQ) {
return StoreVar::randomUniq($default);
} else {
continue 2; // no value provided, continue with while loop
}
......
<?php
namespace IMATHUZH\Qfq\Core\Store;
use IMATHUZH\Qfq\Core\Database\Database;
use IMATHUZH\Qfq\Core\Helper\Support;
//use IMATHUZH\Qfq\Core\Store\Store;
/**
* Class StoreVar
* @package Classes\Core\Store
*/
class StoreVar {
/**
* @var Database - Database instantiated class
*/
private static $db = null; /* QFQ DB */
/**
* @var Store - Database instantiated class
*/
private static $store = null;
/**
* @var null
*/
private static $purged = false;
/**
* Returns a random 32 char string. Take care that it is really uniq.
*
* @param string $expire // Empty (no expiration), 'yyy-mm-dd', 'yyyy-dd-mm hh:mm:ss', '+ 1 day', '+10 sec'
* @return string
* @throws \CodeException
* @throws \DbException
* @throws \UserFormException
* @throws \UserReportException
*/
public static function randomUniq($expire = '') {
if (self::$store == null) {
self::$store = Store::getInstance();
}
if (self::$db == null) {
self::$db = new Database(self::$store->getVar(SYSTEM_DB_INDEX_QFQ, STORE_SYSTEM));
}
$expire = trim($expire);
if ($expire == '') {
$expire = '9999-12-31';
}
if ($expire[0] == '+') {
// $expire: '+1 day' >> '+ INTERVAL 1 day'
$expire = "NOW() + INTERVAL " . SUBSTR($expire, 1);
} else {
$expire = "CONVERT('$expire', DATETIME)";
}
// Purge expired records
if (!self::$purged) {
self::$db->sql("DELETE FROM Uniq WHERE expire<NOW()");
self::$purged = true;
}
$i = 100;
while ($i--) {
// Get new random string
$random = Support::randomAlphaNum(RANDOM_LENGTH);
try {
// Try to save random - if succeed, all is fine else try again.
self::$db->sql("INSERT INTO Uniq (`random`,`expire`) VALUES ( '$random', $expire)");
} catch (\DbException $e) {
$message = $e->getMessage();
// In case there was an error: check for duplicate key
// message: {"toUser":"SQL error","support":"","os":"[ mysqli: 1062 ] Duplicate entry '...' for key 'random'"}
if (strpos($message, '1062') !== false && strpos($message, "for key 'random'") !== false) {
continue; // Key already exist, new try.
} else {
throw new \DbException($message, $e->getCode()); // Something else happened: report.
}
}
return $random;
}
throw new \DbException('Too much iterations to find {{randomUniq:V}}');
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment