StoreVar.php 2.7 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<?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}}');
    }
}