Store.php 21 KB
Newer Older
1
2
3
4
5
6
7
8
<?php
/**
 * Created by PhpStorm.
 * User: crose
 * Date: 1/1/16
 * Time: 6:51 PM
 */

9
namespace qfq;
10

11
use qfq\CodeException;
12
13
use qfq\keyValueStringParser;
use qfq\OnArray;
14
use qfq;
15

16
require_once(__DIR__ . '/../../qfq/helper/KeyValueStringParser.php');
Carsten  Rose's avatar
Carsten Rose committed
17
require_once(__DIR__ . '/../../qfq/helper/Sanitize.php');
18
require_once(__DIR__ . '/../../qfq/Constants.php');
19
require_once(__DIR__ . '/../../qfq/store/Sip.php');
20
//require_once(__DIR__ . '/../../qfq/store/Session.php');
21
require_once(__DIR__ . '/../../qfq/Database.php');
22
23
24
25
26
27
28
29
30
31
32


/*
 * Stores:
 * - SIP
 * - webVar
 * - record
 * - form
 * - formElement
 */

Carsten  Rose's avatar
Carsten Rose committed
33
34
/**
 * Class Store
35
 * @package qfq
Carsten  Rose's avatar
Carsten Rose committed
36
 */
37
38
class Store {

Carsten  Rose's avatar
Carsten Rose committed
39
40
41
    /**
     * @var Store Instance of class Store. There should only be one class 'Store' at a time.
     */
42
43
    private static $instance = null;

Carsten  Rose's avatar
Carsten Rose committed
44
45
46
    /**
     * @var Sip Instance of class SIP
     */
47
48
    private static $sip = null;

49
50
51
    /**
     * @var Session Instance of class Session
     */
52
//    private static $session = null;
53

Carsten  Rose's avatar
Carsten Rose committed
54
55
56
57
58
59
60
61
62
63
    /**
     * @var array Stores all indiviudal stores with the variable raw values
     *
     * $raw['D']['id'] = 0  - Defaultvalues from Tabledefinition
     * ...
     * $raw['S']['r'] = 1234 - record ID from current SIP identifier
     * ...
     * $raw['C']['HTTP_SERVER'] = 'qfq' - Servername
     * $raw['C']['s'] = 'badcaffee1234' - recent SIP
     */
64
    private static $raw = array();
Carsten  Rose's avatar
Carsten Rose committed
65
66

    /**
Carsten  Rose's avatar
Carsten Rose committed
67
     * @var array Default sanitize classes.
Carsten  Rose's avatar
Carsten Rose committed
68
     */
Carsten  Rose's avatar
Carsten Rose committed
69
    private static $sanitizeClass = array();
Carsten  Rose's avatar
Carsten Rose committed
70
71

    /**
Carsten  Rose's avatar
Carsten Rose committed
72
73
     * $sanitizeClass['S'] = false
     * $sanitizeClass['C'] = true
Carsten  Rose's avatar
Carsten Rose committed
74
75
     * ...
     *
Carsten  Rose's avatar
Carsten Rose committed
76
     * @var array each entry with true/false - depending if store needs to be sanitized.
Carsten  Rose's avatar
Carsten Rose committed
77
     */
Carsten  Rose's avatar
Carsten Rose committed
78
    private static $sanitizeStore = array();
79

Carsten  Rose's avatar
Carsten Rose committed
80
    private static $phpUnit = false;
81

82

83
    /**
84
     * @param string $bodytext
85
     */
86
    private function __construct($bodytext = '') {
87

88
//        self::$session = Session::getInstance(self::$phpUnit);
89

Carsten  Rose's avatar
Carsten Rose committed
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
        self::$sanitizeClass = [
//            TYPO3_DEBUG_LOAD => SANITIZE_ALLOW_DIGIT,
//            TYPO3_DEBUG_SAVE => SANITIZE_ALLOW_DIGIT,
//            TYPO3_FORM => SANITIZE_ALLOW_ALNUMX,
//            TYPO3_FE_USER => SANITIZE_ALLOW_ALNUMX,
//            TYPO3_FE_USER_UID => SANITIZE_ALLOW_DIGIT,
//            TYPO3_FE_USER_GROUP => SANITIZE_ALLOW_ALNUMX,

            CLIENT_SIP => SANITIZE_ALLOW_ALNUMX,
            CLIENT_RECORD_ID => SANITIZE_ALLOW_DIGIT,
            CLIENT_KEY_SEM_ID => SANITIZE_ALLOW_DIGIT,
            CLIENT_KEY_SEM_ID_USER => SANITIZE_ALLOW_DIGIT,
            CLIENT_PAGE_ID => SANITIZE_ALLOW_DIGIT,
            CLIENT_PAGE_TYPE => SANITIZE_ALLOW_DIGIT,
            CLIENT_PAGE_LANGUAGE => SANITIZE_ALLOW_DIGIT,
            CLIENT_FORM => SANITIZE_ALLOW_ALNUMX,

            // Part of $_SERVER. Missing vars must be requested individual with the needed sanitize class.
            CLIENT_SCRIPT_URL => SANITIZE_ALLOW_ALNUMX,
            CLIENT_SCRIPT_URI => SANITIZE_ALLOW_ALNUMX,
            CLIENT_HTTP_HOST => SANITIZE_ALLOW_ALNUMX,
            CLIENT_HTTP_USER_AGENT => SANITIZE_ALLOW_ALNUMX,
            CLIENT_SERVER_NAME => SANITIZE_ALLOW_ALNUMX,
            CLIENT_SERVER_ADDRESS => SANITIZE_ALLOW_ALNUMX,
            CLIENT_SERVER_PORT => SANITIZE_ALLOW_DIGIT,
            CLIENT_REMOTE_ADDRESS => SANITIZE_ALLOW_ALNUMX,
            CLIENT_REQUEST_SCHEME => SANITIZE_ALLOW_ALNUMX,
            CLIENT_SCRIPT_FILENAME => SANITIZE_ALLOW_ALNUMX,
            CLIENT_QUERY_STRING => SANITIZE_ALLOW_ALL,
            CLIENT_REQUEST_URI => SANITIZE_ALLOW_ALL,
            CLIENT_SCRIPT_NAME => SANITIZE_ALLOW_ALNUMX,
            CLIENT_PHP_SELF => SANITIZE_ALLOW_ALNUMX,
122
            CLIENT_UPLOAD_FILENAME => SANITIZE_ALLOW_ALLBUT,
Carsten  Rose's avatar
Carsten Rose committed
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

//            SYSTEM_DBUSER => SANITIZE_ALLOW_ALNUMX,
//            SYSTEM_DBSERVER => SANITIZE_ALLOW_ALNUMX,
//            SYSTEM_DBPW => SANITIZE_ALLOW_ALL,
//            SYSTEM_DB => SANITIZE_ALLOW_ALNUMX,
//            SYSTEM_TESTDB => SANITIZE_ALLOW_ALNUMX,
//            SYSTEM_SESSIONNAME => SANITIZE_ALLOW_ALNUMX,
//            SYSTEM_DBH => SANITIZE_ALLOW_ALL,

//            SYSTEM_SQL_RAW => SANITIZE_ALLOW_ALL,
//            SYSTEM_SQL_FINAL => SANITIZE_ALLOW_ALL,
//            SYSTEM_SQL_COUNT => SANITIZE_ALLOW_DIGIT,
//            SYSTEM_SQL_PARAM_ARRAY => SANITIZE_ALLOW_ALL,

//            SIP_SIP => SANITIZE_ALLOW_ALNUMX,
//            SIP_RECORD_ID => SANITIZE_ALLOW_DIGIT,
//            SIP_FORM => SANITIZE_ALLOW_ALNUMX,
//            SIP_URLPARAM => SANITIZE_ALLOW_ALL
141

142
143
        ];

Carsten  Rose's avatar
Carsten Rose committed
144
        self::$sanitizeStore = [
145
146
147
148
            STORE_FORM => true,
            STORE_SIP => false,
            STORE_RECORD => false,
            STORE_PARENT_RECORD => false,
149
150
            STORE_TABLE_DEFAULT => false,
            STORE_TABLE_COLUMN_TYPES => false,
151
152
            STORE_CLIENT => true,
            STORE_TYPO3 => false,
153
            STORE_VAR => false,
154
            STORE_ZERO => false,
155
            STORE_EMPTY => false,
156
            STORE_SYSTEM => false,
157
            STORE_EXTRA => false
158
159
        ];

160
        self::fillSystemStore();
161
        self::fillStoreTypo3($bodytext);
162
        self::fillStoreClient();
163
        self::fillStoreSip();
Carsten  Rose's avatar
Carsten Rose committed
164
        self::fillStoreExtra();
165
166


167
    }
168

169
170
    /**
     * @throws CodeException
171
     * @throws qfq\UserFormException
172
     */
173
    private static function fillSystemStore() {
174
175
176
177
178
179
180
181
182
183
184
185

        // PHPUnit Path to CONFIG_INI
        $configIni = __DIR__ . '/../../../' . CONFIG_INI;
        if (!file_exists($configIni)) {
            // Production Path to CONFIG_INI
            $configIni = __DIR__ . '/../../../../../' . CONFIG_INI;

            if (!file_exists($configIni)) {
                throw new qfq\UserFormException ("Config not found: " . getcwd() . "/" . $configIni, ERROR_IO_READ_FILE);
            }
        }

186
        try {
187
188
            //TODO: Vernuenftige Fehlermeldung falls nicht auf qfq.ini zugegriffen werden kann.
            //TODO: sinnvollen Platz fuer qfq.ini bestimmen. In der Installationsdoku erwaehnen.
189
190
//            $config = parse_ini_file(__DIR__ . '/../../../' . CONFIG_INI, false);
            $config = parse_ini_file($configIni, false);
191

192
193
            //TODO: auskommentiert weil dann die Unittests nicht mehr laufen. Sollte eigentlich wieder aktiviert werden.
//            $config['SQLLOG'] = Support::ifRelativePathPrependExtensionPath($config['SQLLOG']);
194

195
        } catch (\Exception $e) {
196
            throw new qfq\UserFormException ("Error read file " . CONFIG_INI . ": " . $e->getMessage(), ERROR_IO_READ_FILE);
197
        }
198

199
        // Adjust config
200
        if (!isset($config['SHOW_DEBUG_INFO']) || $config['SHOW_DEBUG_INFO'] === 'auto') {
201
202
203
            $config['SHOW_DEBUG_INFO'] = (isset($GLOBALS["TSFE"]->beUserLogin) && $GLOBALS["TSFE"]->beUserLogin === true) ? 'yes' : 'no';
        }

204
205
206
207
208
209
210
        // SYSTEM_PATH_EXT: compute only if not already defined.
        if (!isset($config[SYSTEM_PATH_EXT]) || $config[SYSTEM_PATH_EXT] === '' || $config[SYSTEM_PATH_EXT][0] !== '/') {
            $relExtDir = '/typo3conf/ext/' . EXT_KEY;

            // If we are called through AJAX API (e.g. api/save.php), there is no TYPO3 environment.
            if (isset($_SERVER['SCRIPT_FILENAME'])) {
                $pos = strpos($_SERVER['SCRIPT_FILENAME'], $relExtDir);
211
212
                if ($pos === false && isset($GLOBALS['TYPO3_LOADED_EXT'][EXT_KEY]['ext_localconf.php'])) {

213
                    // Typo3 extension: probably index.php
214
                    $config[SYSTEM_PATH_EXT] = dirname($GLOBALS['TYPO3_LOADED_EXT'][EXT_KEY]['ext_localconf.php']);
215
                    $config[SYSTEM_SITE_PATH] = dirname($_SERVER['SCRIPT_FILENAME']);
216
                } else {
217
                    // API
218
                    $config[SYSTEM_PATH_EXT] = substr($_SERVER['SCRIPT_FILENAME'], 0, $pos + strlen($relExtDir));
219
                    $config[SYSTEM_SITE_PATH] = substr($_SERVER['SCRIPT_FILENAME'], 0, $pos);
220
                }
221
222
223
224
            } else {
                // No $_SERVER >>this means phpUnit.
                $config[SYSTEM_SITE_PATH] = getcwd();
                $config[SYSTEM_PATH_EXT] = getcwd();
225
226
227
            }
        }

228
229
230
        // Defaults
        Support::setIfNotSet($config, SYSTEM_DATE_FORMAT, 'yyyy-mm-dd');

231
232
233
234
235
        // make SQL PATH absolute. This is necessary to work in different directories correctly.
        if (isset($config[SYSTEM_SQL_LOG]) && $config[SYSTEM_SQL_LOG][0] !== '/') {
            $config[SYSTEM_SQL_LOG] = $config[SYSTEM_PATH_EXT] . '/' . $config[SYSTEM_SQL_LOG];
        }

236
237
238
239
240
241
242
        // Verify existence
        $names = array('DB_USER', 'DB_SERVER', 'DB_PASSWORD', 'DB_NAME', 'SQL_LOG', 'SQL_LOG_MODE');
        foreach ($names as $name) {
            if (!isset($config[$name])) {
                throw new qfq\UserFormException ("Missing configuration in `config.ini`: $name", ERROR_MISSING_CONFIG_INI_VALUE);
            }
        }
243

244
        self::setVarArray($config, STORE_SYSTEM, true);
245
246
    }

247
248
249
    /**
     * @param array $dataArray
     * @param $store
250
     * @param bool|false $flagOverwrite
251
     * @throws UserFormException
252
     * @throws \qfq\CodeException
253
     */
254
    public static function setVarArray(array $dataArray, $store, $flagOverwrite = false) {
255

Carsten  Rose's avatar
Carsten Rose committed
256
        // Check valid Storename
Carsten  Rose's avatar
Carsten Rose committed
257
        if (!isset(self::$sanitizeStore))
258
            throw new UserFormException("Unknown Store: $store", ERROR_UNNOWN_STORE);
Carsten  Rose's avatar
Carsten Rose committed
259

260
        if ($store === STORE_ZERO)
Carsten  Rose's avatar
Carsten Rose committed
261
            throw new CodeException("setVarArray() for STORE_ZERO is impossible - there are no values.", ERROR_SET_STORE_ZERO);
262

Carsten  Rose's avatar
Carsten Rose committed
263
        if (!$flagOverwrite && isset(self::$raw[$store]) && count(self::$raw[$store]) > 0) {
264
            throw new CodeException("Raw values already been copied to store '$store'. Do this only one time.", ERROR_STORE_VALUE_ALREADY_CODPIED);
265
        }
266

267
268
        self::$raw[$store] = $dataArray;
    }
269

270
    /**
271
272
273
     * Copy the BodyText as well as some T3 specific vars to STORE_TYPO3.
     * Attention: if called through API, there is no T3 environment. The only values which are available are fe_user and fe_user_uid.
     *
274
275
276
     * @param $bodytext
     * @throws CodeException
     */
277
    private static function fillStoreTypo3($bodytext) {
278

279
        // form=, showDebugBodyText=, 10.20..
280
        $arr = KeyValueStringParser::parse($bodytext, "=", "\n");
281

282
        if (isset($GLOBALS["TSFE"])) {
283

284
285
286
            if (isset($GLOBALS["TSFE"]->fe_user->user["username"])) {
                $arr[TYPO3_FE_USER] = $GLOBALS["TSFE"]->fe_user->user["username"];
            }
287

288
289
290
291
            if (isset($GLOBALS["TSFE"]->fe_user->user["uid"])) {
                $feUid = $GLOBALS["TSFE"]->fe_user->user["uid"];
                $arr[TYPO3_FE_USER_UID] = $GLOBALS["TSFE"]->fe_user->user["uid"];
            }
292

293
294
295
            if (isset($GLOBALS["TSFE"]->fe_user->user["usergroup"])) {
                $arr[TYPO3_FE_USER_GROUP] = $GLOBALS["TSFE"]->fe_user->user["usergroup"];
            }
Carsten  Rose's avatar
Carsten Rose committed
296

297
298
299
            if (isset($GLOBALS["TSFE"]->page["uid"])) {
                $arr[TYPO3_TT_CONTENT_UID] = $GLOBALS["TSFE"]->page["uid"];
            }
300

301
302
303
304
305
306
307
            if (isset($GLOBALS["TSFE"]->id)) {
                $arr[TYPO3_PAGE_ID] = $GLOBALS["TSFE"]->id;
            }

            if (isset($GLOBALS["TSFE"]->type)) {
                $arr[TYPO3_PAGE_TYPE] = $GLOBALS["TSFE"]->type;
            }
Carsten  Rose's avatar
Carsten Rose committed
308

309
310
311
            if (isset($GLOBALS["TSFE"]->sys_language_uid)) {
                $arr[TYPO3_PAGE_LANGUAGE] = $GLOBALS["TSFE"]->sys_language_uid;
            }
312

313
        } else {
314

315
            // NO T3 environment (called by API): restore from SESSION
316
317
318
319
            foreach([ SESSION_FE_USER, SESSION_FE_USER_UID, SESSION_FE_USER_GROUP ] as $key) {
                if (isset($_SESSION[SESSION_NAME][$key])) {
                    $arr[$key] = $_SESSION[SESSION_NAME][$key];
                }
320
321
            }
        }
322

323
        self::setVarArray($arr, STORE_TYPO3, true);
324
    }
325

326
327
328
    /**
     * @throws CodeException
     */
329
    private static function fillStoreClient() {
330
        // copy GET and POST and SERVER Parameter. Priority: SERVER, POST, GET
331
332
333
334
335
336
337
338
339
        $arr = array();
        if (isset($_GET))
            $arr = array_merge($arr, $_GET);

        if (isset($_POST))
            $arr = array_merge($arr, $_POST);

        if (isset($_SERVER))
            $arr = array_merge($arr, $_SERVER);
340

341
        self::setVarArray($arr, STORE_CLIENT, true);
342
    }
343

Carsten  Rose's avatar
Carsten Rose committed
344
345
    /**
     * @throws CodeException
346
     * @throws UserFormException
Carsten  Rose's avatar
Carsten Rose committed
347
     */
348
    private static function fillStoreSip() {
Carsten  Rose's avatar
Carsten Rose committed
349

350
        self::$sip = new Sip(self::$phpUnit);
351

352
353
354
355
        $s = self::getVar(CLIENT_SIP, STORE_CLIENT);
        if ($s !== false) {
            // if session is given, copy values to store
            $param = self::$sip->getVarsFromSip($s);
356
357
            $param[SIP_SIP] = $s;
            $param[SIP_URLPARAM] = self::$sip->getQueryStringFromSip($s);
358

359
//            self::setVarArray(KeyValueStringParser::parse($param, "=", "&"), STORE_SIP);
360
            self::setVarArray($param, STORE_SIP, true);
361
362
363
        }
    }

364
    /**
365
     * Cycles through all stores in $useStore.
366
     * First match will return the found value.
Carsten  Rose's avatar
Carsten Rose committed
367
     * During cycling: fill cache with requestet value and sanitize raw value.
368
     *
369
     * @param string $key
370
     * @param string $useStores f.e.: 'FSRD'
Carsten  Rose's avatar
Carsten Rose committed
371
     * @param string $sanitizeClass
Carsten  Rose's avatar
Carsten Rose committed
372
     * @param string $foundInStore Returns the name of the store where $key has been found. If $key is not found, return ''.
373
     * @return string a) if found: value, b) false
Carsten  Rose's avatar
Carsten Rose committed
374
     * @throws \qfq\CodeException
375
     */
Carsten  Rose's avatar
Carsten Rose committed
376
    public static function getVar($key, $useStores = STORE_USE_DEFAULT, $sanitizeClass = '', &$foundInStore = '') {
377
378

        // no store specifed?
379
        if ($useStores === "" || $useStores === null) {
380
            $useStores = STORE_USE_DEFAULT;
381
382
        }

383
        // no sanitizeClass specified: take predefined (if exist) or default.
384
        if ($sanitizeClass === '' || $sanitizeClass === null) {
Carsten  Rose's avatar
Carsten Rose committed
385
            $sanitizeClass = isset(self::$sanitizeClass[$key]) ? self::$sanitizeClass[$key] : SANITIZE_DEFAULT;
386
387
        }

388
389
390
        while ($useStores !== false) {

            $store = substr($useStores, 0, 1); // next store
Carsten  Rose's avatar
Carsten Rose committed
391
            $foundInStore = $store;
392
393
            $useStores = substr($useStores, 1); // shift left remaining stores

394
            if (!isset(self::$raw[$store][$key])) {
395
396
397
                switch ($store) {
                    case STORE_ZERO:
                        return 0;
398
399
                    case STORE_EMPTY:
                        return '';
400
401
                    case STORE_VAR:
                        if ($key === VAR_RANDOM) {
402
                            return Support::randomAlphaNum(RANDOM_LENGTH);
403
404
405
406
407
408
409
                        } else {
                            continue 2;  // no value provided, continue with while loop
                        }
                        break;
                    default:
                        continue 2; // no value provided, continue with while loop
                        break;
Carsten  Rose's avatar
Carsten Rose committed
410
                }
411
412
            }

413
            $rawVal = isset(self::$raw[$store][$key]) ? self::$raw[$store][$key] : null;
Carsten  Rose's avatar
Carsten Rose committed
414
            if (self::$sanitizeStore[$store] && $sanitizeClass != '') {
415
416
417
418
419
                if ($sanitizeClass == SANITIZE_ALLOW_PATTERN || $sanitizeClass == SANITIZE_ALLOW_MIN_MAX || $sanitizeClass == SANITIZE_ALLOW_MIN_MAX_DATE) {
                    // We do not have any pattern or min|max values at this point. For those who be affected, they already checked earlier. So set 'no check'
                    $sanitizeClass = SANITIZE_ALLOW_ALL;
                }
                return \qfq\Sanitize::sanitize($rawVal, $sanitizeClass, '', SANATIZE_EMPTY_STRING);
420
421
            } else {
                return $rawVal;
422
            }
423
        }
Carsten  Rose's avatar
Carsten Rose committed
424
        $foundInStore = '';
425
        return false;
426
    }
427

Carsten  Rose's avatar
Carsten Rose committed
428
429
430
431
432
    /**
     * @throws UserFormException
     * @throws \qfq\CodeException
     */
    private static function fillStoreExtra() {
433

434
        $value = Session::get(STORE_EXTRA);
435

436
        if (!isset($_SESSION[SESSION_NAME][STORE_EXTRA]) || $_SESSION[SESSION_NAME][STORE_EXTRA] === null) {
437
438
439
440
            $value = false;
        }

        if ($value === false) {
Carsten  Rose's avatar
Carsten Rose committed
441
            self::setVarArray(array(), STORE_EXTRA, true);
442
        } else {
443
            self::setVarArray($_SESSION[SESSION_NAME][STORE_EXTRA], STORE_EXTRA, true);
444
        }
Carsten  Rose's avatar
Carsten Rose committed
445
446
    }

447
448
    /**
     * @param string $bodytext
449
     * @param bool|false $phpUnit
450
     * @return null|\qfq\Store
451
     */
452
    public static function getInstance($bodytext = '', $phpUnit = false) {
453

454
        if ($phpUnit) {
455
            if (self::$instance !== null) {
456
                // fake to have a clean environment for the next test.
457
458
459
460
461
                self::unsetStore(STORE_TYPO3);
                self::fillStoreTypo3($bodytext);

                self::unsetStore(STORE_CLIENT);
                self::fillStoreClient();
462
463
464
465
466
            }
        }

        // Design Pattern: Singleton
        if (self::$instance === null) {
467
468
469
            self::$phpUnit = $phpUnit;

            self::$instance = new self($bodytext);
Carsten  Rose's avatar
Carsten Rose committed
470
471
472
473
        } else {
            // Class Store seems to be presistent over multiple QFQ instantiation. Set bodytext again, with every new request (if bodytext is given).
            if ($bodytext !== '')
                self::fillStoreTypo3($bodytext);
474
475
        }

476
477
478
479
480
481
482
        // Disable TYPO3_DEBUG_SHOW_BODY_TEXT=1 if SYSTEM_SHOW_DEBUG_INFO!='yes'
        if (self::getVar(TYPO3_DEBUG_SHOW_BODY_TEXT, STORE_TYPO3) === '1' &&
            self::getVar(SYSTEM_SHOW_DEBUG_INFO, STORE_SYSTEM) !== 'yes'
        ) {
            self::setVar(TYPO3_DEBUG_SHOW_BODY_TEXT, '0', STORE_TYPO3);
        }

483
        return self::$instance;
484
    }
485

486
487
    /**
     * @param $store
488
489
     * @throws UserFormException
     * @throws \qfq\CodeException
490
491
     */
    public static function unsetStore($store) {
Carsten  Rose's avatar
Carsten Rose committed
492
        // Check valid Storename
Carsten  Rose's avatar
Carsten Rose committed
493
        if (!isset(self::$sanitizeStore))
494
            throw new UserFormException("Unknown Store: $store", ERROR_UNNOWN_STORE);
Carsten  Rose's avatar
Carsten Rose committed
495

496
        if ($store === STORE_ZERO)
Carsten  Rose's avatar
Carsten Rose committed
497
498
            throw new CodeException("unsetStore() for STORE_ZERO is impossible - there are no values.", ERROR_SET_STORE_ZERO);

499
500
501
        if (isset(self::$raw[$store])) {
            self::$raw[$store] = array();
        }
Carsten  Rose's avatar
Carsten Rose committed
502

503
504
    }

505
    /**
Carsten  Rose's avatar
Carsten Rose committed
506
507
508
     * @param string $key
     * @param string|array $value
     * @param string $store
509
510
511
512
513
514
515
516
517
518
519
520
521
     * @param bool|true $overWrite
     * @throws UserFormException
     * @throws \qfq\CodeException
     */
    public static function setVar($key, $value, $store, $overWrite = true) {
        // Check valid Storename
        if (!isset(self::$sanitizeStore))
            throw new UserFormException("Unknown Store: $store", ERROR_UNNOWN_STORE);

        if ($store === STORE_ZERO)
            throw new CodeException("setVar() for STORE_ZERO is impossible - there are no values.", ERROR_SET_STORE_ZERO);

        if ($overWrite === false && isset(self::$raw[$store][$key])) {
522
            throw new UserFormException("Value of '$key' already set in store '$store'.", ERROR_STORE_KEY_EXIST);
523
524
525
        }

        self::$raw[$store][$key] = $value;
Carsten  Rose's avatar
Carsten Rose committed
526
527
528

        // The STORE_EXTRA saves arrays and is persistent
        if ($store === STORE_EXTRA) {
529

530
            $store = Session::get(STORE_EXTRA);
531
532

            if ($store === false) {
533
                $store = array();
534
535
            }

536
537
            $store[$key] = $value;
            Session::set(STORE_EXTRA, $store);
538

Carsten  Rose's avatar
Carsten Rose committed
539
        }
540
541
    }

542
543
544
545
    /**
     * @param $formName
     * @throws CodeException
     */
546
    public static function createSipAfterFormLoad($formName) {
547

548
        $recordId = self::getVar(CLIENT_RECORD_ID, STORE_TYPO3 . STORE_CLIENT);
549
550
551
552
553
554
555
        if ($recordId === false) {
            $recordId = 0;
        }

        $tmpParam = [SIP_RECORD_ID => $recordId, SIP_FORM => $formName];

        // Construct fake urlparam
556
        $tmpUrlparam = OnArray::toString($tmpParam);
557
558

        // Create a fake SIP which has never been passed by URL - further processing might expect this to exist.
559
        $sip = self::getSipInstance()->queryStringToSip($tmpUrlparam, RETURN_SIP);
560
        self::setVar(CLIENT_SIP, $sip, STORE_CLIENT);
561
562
563

        // Store in SIP Store (cause it's empty until now).
        $tmpParam[SIP_SIP] = $sip;
564
        self::setVarArray($tmpParam, STORE_SIP, true);
565

566
567
568
    }

    /**
569
     * @return null|Sip
570
     */
571
    public static function getSipInstance() {
572
573
        return self::$sip;
    }
574

575
576
    /**
     * @param $store
577
578
579
     * @return array
     * @throws UserFormException
     * @throws \qfq\CodeException
580
581
     */
    public static function getStore($store) {
Carsten  Rose's avatar
Carsten Rose committed
582
        // Check valid Storename
Carsten  Rose's avatar
Carsten Rose committed
583
        if (!isset(self::$sanitizeStore[$store]))
584
            throw new UserFormException("Unknown Store: $store", ERROR_UNNOWN_STORE);
Carsten  Rose's avatar
Carsten Rose committed
585

586
        if ($store === STORE_ZERO)
Carsten  Rose's avatar
Carsten Rose committed
587
588
            throw new CodeException("getStore() for STORE_ZERO is impossible - there are no values saved.", ERROR_GET_STORE_ZERO);

589
590
591
        if (isset(self::$raw[$store])) {
            return self::$raw[$store];
        }
592

593
594
        return array();
    }
595

Carsten  Rose's avatar
Carsten Rose committed
596

597
    /**
Carsten  Rose's avatar
Carsten Rose committed
598
599
     * Fills STORE_TABLE_DEFAULT and STORE_TABLE_COLUMN_TYPES
     *
600
601
602
     * @param $tableName
     * @throws CodeException
     */
603
    public static function fillStoreTableDefaultColumnType($tableName) {
604
605
606
607
        $db = new qfq\Database();

        $tableDefinition = $db->getTableDefinition($tableName);

Carsten  Rose's avatar
Carsten Rose committed
608
609
        self::setVarArray(array_column($tableDefinition, 'Default', 'Field'), STORE_TABLE_DEFAULT, true);
        self::setVarArray(array_column($tableDefinition, 'Type', 'Field'), STORE_TABLE_COLUMN_TYPES, true);
610
    }
611
612
613
614
615
}