Store.php 20.2 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
        try {
175
176
            //TODO: Vernuenftige Fehlermeldung falls nicht auf qfq.ini zugegriffen werden kann.
            //TODO: sinnvollen Platz fuer qfq.ini bestimmen. In der Installationsdoku erwaehnen.
177
            $config = parse_ini_file(__DIR__ . '/../../../' . CONFIG_INI, false);
178

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

182
        } catch (\Exception $e) {
183
            throw new qfq\UserFormException ("Error read file " . CONFIG_INI . ": " . $e->getMessage(), ERROR_IO_READ_FILE);
184
        }
185

186
        // Adjust config
187
        if (!isset($config['SHOW_DEBUG_INFO']) || $config['SHOW_DEBUG_INFO'] === 'auto') {
188
189
190
            $config['SHOW_DEBUG_INFO'] = (isset($GLOBALS["TSFE"]->beUserLogin) && $GLOBALS["TSFE"]->beUserLogin === true) ? 'yes' : 'no';
        }

191
192
193
194
195
196
197
        // 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);
198
199
                if ($pos === false && isset($GLOBALS['TYPO3_LOADED_EXT'][EXT_KEY]['ext_localconf.php'])) {

200
                    // Typo3 extension: probably index.php
201
                    $config[SYSTEM_PATH_EXT] = dirname($GLOBALS['TYPO3_LOADED_EXT'][EXT_KEY]['ext_localconf.php']);
202
                    $config[SYSTEM_SITE_PATH] = dirname($_SERVER['SCRIPT_FILENAME']);
203
                } else {
204
                    // API
205
                    $config[SYSTEM_PATH_EXT] = substr($_SERVER['SCRIPT_FILENAME'], 0, $pos + strlen($relExtDir));
206
                    $config[SYSTEM_SITE_PATH] = substr($_SERVER['SCRIPT_FILENAME'], 0, $pos);
207
                }
208
209
210
211
            } else {
                // No $_SERVER >>this means phpUnit.
                $config[SYSTEM_SITE_PATH] = getcwd();
                $config[SYSTEM_PATH_EXT] = getcwd();
212
213
214
            }
        }

215
216
217
        // Defaults
        Support::setIfNotSet($config, SYSTEM_DATE_FORMAT, 'yyyy-mm-dd');

218
219
220
221
222
223
        // 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];
        }


224
        self::setVarArray($config, STORE_SYSTEM, true);
225
226
    }

227
228
229
    /**
     * @param array $dataArray
     * @param $store
230
     * @param bool|false $flagOverwrite
231
     * @throws UserFormException
232
     * @throws \qfq\CodeException
233
     */
234
    public static function setVarArray(array $dataArray, $store, $flagOverwrite = false) {
235

Carsten  Rose's avatar
Carsten Rose committed
236
        // Check valid Storename
Carsten  Rose's avatar
Carsten Rose committed
237
        if (!isset(self::$sanitizeStore))
238
            throw new UserFormException("Unknown Store: $store", ERROR_UNNOWN_STORE);
Carsten  Rose's avatar
Carsten Rose committed
239

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

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

247
248
        self::$raw[$store] = $dataArray;
    }
249

250
    /**
251
252
253
     * 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.
     *
254
255
256
     * @param $bodytext
     * @throws CodeException
     */
257
    private static function fillStoreTypo3($bodytext) {
258

259
        // form=, showDebugBodyText=, 10.20..
260
        $arr = KeyValueStringParser::parse($bodytext, "=", "\n");
261

262
        if (isset($GLOBALS["TSFE"])) {
263

264
265
266
            if (isset($GLOBALS["TSFE"]->fe_user->user["username"])) {
                $arr[TYPO3_FE_USER] = $GLOBALS["TSFE"]->fe_user->user["username"];
            }
267

268
269
270
271
            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"];
            }
272

273
274
275
            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
276

277
278
279
            if (isset($GLOBALS["TSFE"]->page["uid"])) {
                $arr[TYPO3_TT_CONTENT_UID] = $GLOBALS["TSFE"]->page["uid"];
            }
280

281
282
283
284
285
286
287
            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
288

289
290
291
292
293
            if (isset($GLOBALS["TSFE"]->sys_language_uid)) {
                $arr[TYPO3_PAGE_LANGUAGE] = $GLOBALS["TSFE"]->sys_language_uid;
            }
        } else {
            // NO T3 environment (called by API): restore from SESSION
294
295
            if (isset($_SESSION[SESSION_NAME][SESSION_FE_USER])) {
                $arr[TYPO3_FE_USER] = $_SESSION[SESSION_NAME][SESSION_FE_USER];
296
            }
297
298
            if (isset($_SESSION[SESSION_NAME][SESSION_FE_USER_UID])) {
                $arr[TYPO3_FE_USER_UID] = $_SESSION[SESSION_NAME][SESSION_FE_USER_UID];
299
300
            }
        }
301

302
        self::setVarArray($arr, STORE_TYPO3, true);
303
    }
304

305
306
307
    /**
     * @throws CodeException
     */
308
    private static function fillStoreClient() {
309
        // copy GET and POST and SERVER Parameter. Priority: SERVER, POST, GET
310
311
312
313
314
315
316
317
318
        $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);
319

320
        self::setVarArray($arr, STORE_CLIENT, true);
321
    }
322

Carsten  Rose's avatar
Carsten Rose committed
323
324
    /**
     * @throws CodeException
325
     * @throws UserFormException
Carsten  Rose's avatar
Carsten Rose committed
326
     */
327
    private static function fillStoreSip() {
Carsten  Rose's avatar
Carsten Rose committed
328

329
        self::$sip = new Sip(self::$phpUnit);
330

331
332
333
334
        $s = self::getVar(CLIENT_SIP, STORE_CLIENT);
        if ($s !== false) {
            // if session is given, copy values to store
            $param = self::$sip->getVarsFromSip($s);
335
336
            $param[SIP_SIP] = $s;
            $param[SIP_URLPARAM] = self::$sip->getQueryStringFromSip($s);
337

338
//            self::setVarArray(KeyValueStringParser::parse($param, "=", "&"), STORE_SIP);
339
            self::setVarArray($param, STORE_SIP, true);
340
341
342
        }
    }

343
    /**
344
     * Cycles through all stores in $useStore.
345
     * First match will return the found value.
Carsten  Rose's avatar
Carsten Rose committed
346
     * During cycling: fill cache with requestet value and sanitize raw value.
347
     *
348
     * @param string $key
349
     * @param string $useStores f.e.: 'FSRD'
Carsten  Rose's avatar
Carsten Rose committed
350
     * @param string $sanitizeClass
Carsten  Rose's avatar
Carsten Rose committed
351
     * @param string $foundInStore Returns the name of the store where $key has been found. If $key is not found, return ''.
352
     * @return string a) if found: value, b) false
Carsten  Rose's avatar
Carsten Rose committed
353
     * @throws \qfq\CodeException
354
     */
Carsten  Rose's avatar
Carsten Rose committed
355
    public static function getVar($key, $useStores = STORE_USE_DEFAULT, $sanitizeClass = '', &$foundInStore = '') {
356
357

        // no store specifed?
358
        if ($useStores === "" || $useStores === null) {
359
            $useStores = STORE_USE_DEFAULT;
360
361
        }

362
        // no sanitizeClass specified: take predefined (if exist) or default.
363
        if ($sanitizeClass === '' || $sanitizeClass === null) {
Carsten  Rose's avatar
Carsten Rose committed
364
            $sanitizeClass = isset(self::$sanitizeClass[$key]) ? self::$sanitizeClass[$key] : SANITIZE_DEFAULT;
365
366
        }

367
368
369
        while ($useStores !== false) {

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

373
            if (!isset(self::$raw[$store][$key])) {
374
375
376
                switch ($store) {
                    case STORE_ZERO:
                        return 0;
377
378
                    case STORE_EMPTY:
                        return '';
379
380
                    case STORE_VAR:
                        if ($key === VAR_RANDOM) {
381
                            return Support::randomAlphaNum(RANDOM_LENGTH);
382
383
384
385
386
387
388
                        } 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
389
                }
390
391
            }

392
            $rawVal = isset(self::$raw[$store][$key]) ? self::$raw[$store][$key] : null;
Carsten  Rose's avatar
Carsten Rose committed
393
            if (self::$sanitizeStore[$store] && $sanitizeClass != '') {
394
395
396
397
398
                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);
399
400
            } else {
                return $rawVal;
401
            }
402
        }
Carsten  Rose's avatar
Carsten Rose committed
403
        $foundInStore = '';
404
        return false;
405
    }
406

Carsten  Rose's avatar
Carsten Rose committed
407
408
409
410
411
    /**
     * @throws UserFormException
     * @throws \qfq\CodeException
     */
    private static function fillStoreExtra() {
412

413
        $value = Session::get(STORE_EXTRA);
414

415
        if (!isset($_SESSION[SESSION_NAME][STORE_EXTRA]) || $_SESSION[SESSION_NAME][STORE_EXTRA] === null) {
416
417
418
419
            $value = false;
        }

        if ($value === false) {
Carsten  Rose's avatar
Carsten Rose committed
420
            self::setVarArray(array(), STORE_EXTRA, true);
421
        } else {
422
            self::setVarArray($_SESSION[SESSION_NAME][STORE_EXTRA], STORE_EXTRA, true);
423
        }
Carsten  Rose's avatar
Carsten Rose committed
424
425
    }

426
427
    /**
     * @param string $bodytext
428
     * @param bool|false $phpUnit
429
     * @return null|\qfq\Store
430
     */
431
    public static function getInstance($bodytext = '', $phpUnit = false) {
432

433
        if ($phpUnit) {
434
            if (self::$instance !== null) {
435
                // fake to have a clean environment for the next test.
436
437
438
439
440
                self::unsetStore(STORE_TYPO3);
                self::fillStoreTypo3($bodytext);

                self::unsetStore(STORE_CLIENT);
                self::fillStoreClient();
441
442
443
444
445
            }
        }

        // Design Pattern: Singleton
        if (self::$instance === null) {
446
447
448
            self::$phpUnit = $phpUnit;

            self::$instance = new self($bodytext);
Carsten  Rose's avatar
Carsten Rose committed
449
450
451
452
        } 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);
453
454
        }

455
456
457
458
459
460
461
        // 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);
        }

462
        return self::$instance;
463
    }
464

465
466
    /**
     * @param $store
467
468
     * @throws UserFormException
     * @throws \qfq\CodeException
469
470
     */
    public static function unsetStore($store) {
Carsten  Rose's avatar
Carsten Rose committed
471
        // Check valid Storename
Carsten  Rose's avatar
Carsten Rose committed
472
        if (!isset(self::$sanitizeStore))
473
            throw new UserFormException("Unknown Store: $store", ERROR_UNNOWN_STORE);
Carsten  Rose's avatar
Carsten Rose committed
474

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

478
479
480
        if (isset(self::$raw[$store])) {
            self::$raw[$store] = array();
        }
Carsten  Rose's avatar
Carsten Rose committed
481

482
483
    }

484
    /**
Carsten  Rose's avatar
Carsten Rose committed
485
486
487
     * @param string $key
     * @param string|array $value
     * @param string $store
488
489
490
491
492
493
494
495
496
497
498
499
500
     * @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])) {
501
            throw new UserFormException("Value of '$key' already set in store '$store'.", ERROR_STORE_KEY_EXIST);
502
503
504
        }

        self::$raw[$store][$key] = $value;
Carsten  Rose's avatar
Carsten Rose committed
505
506
507

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

509
            $store = Session::get(STORE_EXTRA);
510
511

            if ($store === false) {
512
                $store = array();
513
514
            }

515
516
            $store[$key] = $value;
            Session::set(STORE_EXTRA, $store);
517

Carsten  Rose's avatar
Carsten Rose committed
518
        }
519
520
    }

521
522
523
524
    /**
     * @param $formName
     * @throws CodeException
     */
525
    public static function createSipAfterFormLoad($formName) {
526

527
        $recordId = self::getVar(CLIENT_RECORD_ID, STORE_TYPO3 . STORE_CLIENT);
528
529
530
531
532
533
534
        if ($recordId === false) {
            $recordId = 0;
        }

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

        // Construct fake urlparam
535
        $tmpUrlparam = OnArray::toString($tmpParam);
536
537

        // Create a fake SIP which has never been passed by URL - further processing might expect this to exist.
538
        $sip = self::getSipInstance()->queryStringToSip($tmpUrlparam, RETURN_SIP);
539
        self::setVar(CLIENT_SIP, $sip, STORE_CLIENT);
540
541
542

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

545
546
547
    }

    /**
548
     * @return null|Sip
549
     */
550
    public static function getSipInstance() {
551
552
        return self::$sip;
    }
553

554
555
    /**
     * @param $store
556
557
558
     * @return array
     * @throws UserFormException
     * @throws \qfq\CodeException
559
560
     */
    public static function getStore($store) {
Carsten  Rose's avatar
Carsten Rose committed
561
        // Check valid Storename
Carsten  Rose's avatar
Carsten Rose committed
562
        if (!isset(self::$sanitizeStore[$store]))
563
            throw new UserFormException("Unknown Store: $store", ERROR_UNNOWN_STORE);
Carsten  Rose's avatar
Carsten Rose committed
564

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

568
569
570
        if (isset(self::$raw[$store])) {
            return self::$raw[$store];
        }
571

572
573
        return array();
    }
574

Carsten  Rose's avatar
Carsten Rose committed
575

576
    /**
Carsten  Rose's avatar
Carsten Rose committed
577
578
     * Fills STORE_TABLE_DEFAULT and STORE_TABLE_COLUMN_TYPES
     *
579
580
581
     * @param $tableName
     * @throws CodeException
     */
582
    public static function fillStoreTableDefaultColumnType($tableName) {
583
584
585
586
        $db = new qfq\Database();

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

Carsten  Rose's avatar
Carsten Rose committed
587
588
        self::setVarArray(array_column($tableDefinition, 'Default', 'Field'), STORE_TABLE_DEFAULT, true);
        self::setVarArray(array_column($tableDefinition, 'Type', 'Field'), STORE_TABLE_COLUMN_TYPES, true);
589
    }
590
591
592
593
594
}