Commit 18321a1d authored by Carsten  Rose's avatar Carsten Rose

Refs #11118 - Special variable name {{randomUniq:V}} removed again. Uniqueness...

Refs #11118 - Special variable name {{randomUniq:V}} removed again. Uniqueness is now guaranteed in {{random:V}} itnernal. Therefore it's not necessary to provide an dedicated variable.
parent 453cce90
Pipeline #3787 passed with stages
in 4 minutes and 23 seconds
......@@ -54,7 +54,6 @@ Features
* #10979 / Report: do SIP protected AJAX calls to typo3conf/ext/qfq/Classes/Api/dataReport.php.
* #11076 / Report: trigger call to websockets.
* #11118 / Retrieve random string which is guaranteed to be uniq: {{randomUniq:V}}.
* #11119 / Report: REST Client calls - incl. processing of answer.
* Add CodingGuideline.rst.
......
......@@ -256,9 +256,7 @@ Store: *VARS* - V
| Name | Explanation |
+=========================+============================================================================================================================================+
| 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}}`` (sec, min, day, ... - MySQL notation DATE_ADD() ). |
| | Remember: QFQ variables will be replaced **before** a SQL statement is fired. Uniqueness is given via PHP function *uniqid()*. |
+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
| slaveId | see :ref:`slave-id` |
+-------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
......
......@@ -724,7 +724,6 @@ 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.
......
......@@ -194,9 +194,6 @@ $UPDATE_ARRAY = array(
"ALTER TABLE `FormElement` CHANGE `label` `label` VARCHAR(1023) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '';",
],
'20.9.0' => [
"CREATE TABLE `Uniq` (`id` int(11) NOT NULL AUTO_INCREMENT, `random` char(32) NOT NULL, `expire` datetime NOT NULL, `modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `random` (`random`) USING BTREE, KEY `expire` (`id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;);",
],
);
......
......@@ -733,15 +733,23 @@ class Support {
}
/**
* Creates a random string, starting with uniq microseconds timestamp.
* After a discussion of ME & CR, the uniqid() should be sufficient to guarantee uniqness.
*
* @param int $length Length of the required hash string
*
* @return string A random alphanumeric hash
*/
public static function randomAlphaNum($length) {
$possible_characters = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$string = "";
while (strlen($string) < $length) {
$string .= substr($possible_characters, rand() % (strlen($possible_characters)), 1);
$allChars = strlen($possible_characters);
$string = uniqid();
$ii = $length - strlen($string);
while ($ii-- > 0) {
$string .= substr($possible_characters, rand() % ($allChars), 1);
}
return ($string);
......
......@@ -715,8 +715,6 @@ 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
......@@ -681,16 +681,3 @@ CREATE TABLE IF NOT EXISTS `Setting`
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;
CREATE TABLE `Uniq`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`random` char(32) NOT NULL,
`expire` datetime NOT NULL,
`modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `random` (`random`) USING BTREE,
KEY `expire` (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;
......@@ -35,7 +35,7 @@ class DatabaseUpdateTest extends AbstractDatabaseTest {
public function testCheckNupdate() {
// $countQfqTables = 9;
$countQfqTables = 11;
$countQfqTables = 10;
$store = Store::getInstance();
......
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