Store.php 18.9 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/Database.php');
21
22
23
24
25
26
27
28
29
30
31


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

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

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

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

Carsten  Rose's avatar
Carsten Rose committed
48
49
50
51
52
53
54
55
56
57
    /**
     * @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
     */
58
    private static $raw = array();
Carsten  Rose's avatar
Carsten Rose committed
59
60

    /**
Carsten  Rose's avatar
Carsten Rose committed
61
     * @var array Default sanitize classes.
Carsten  Rose's avatar
Carsten Rose committed
62
     */
Carsten  Rose's avatar
Carsten Rose committed
63
    private static $sanitizeClass = array();
Carsten  Rose's avatar
Carsten Rose committed
64
65

    /**
Carsten  Rose's avatar
Carsten Rose committed
66
67
     * $sanitizeClass['S'] = false
     * $sanitizeClass['C'] = true
Carsten  Rose's avatar
Carsten Rose committed
68
69
     * ...
     *
Carsten  Rose's avatar
Carsten Rose committed
70
     * @var array each entry with true/false - depending if store needs to be sanitized.
Carsten  Rose's avatar
Carsten Rose committed
71
     */
Carsten  Rose's avatar
Carsten Rose committed
72
    private static $sanitizeStore = array();
73

Carsten  Rose's avatar
Carsten Rose committed
74
    private static $phpUnit = false;
75

76
    /**
77
     * @param string $bodytext
78
     */
79
    private function __construct($bodytext = '') {
80

Carsten  Rose's avatar
Carsten Rose committed
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
        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,
113
            CLIENT_UPLOAD_FILENAME => SANITIZE_ALLOW_ALLBUT,
Carsten  Rose's avatar
Carsten Rose committed
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

//            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
132

133
134
        ];

Carsten  Rose's avatar
Carsten Rose committed
135
        self::$sanitizeStore = [
136
137
138
139
            STORE_FORM => true,
            STORE_SIP => false,
            STORE_RECORD => false,
            STORE_PARENT_RECORD => false,
140
141
            STORE_TABLE_DEFAULT => false,
            STORE_TABLE_COLUMN_TYPES => false,
142
143
            STORE_CLIENT => true,
            STORE_TYPO3 => false,
144
            STORE_ZERO => false,
145
            STORE_SYSTEM => false,
146
            STORE_EXTRA => false
147
148
        ];

149
        self::fillSystemStore();
150
        self::fillStoreTypo3($bodytext);
151
        self::fillStoreClient();
152
        self::fillStoreSip();
Carsten  Rose's avatar
Carsten Rose committed
153
        self::fillStoreExtra();
154
    }
155

156
157
    /**
     * @throws CodeException
158
     * @throws qfq\UserFormException
159
     */
160
    private static function fillSystemStore() {
161
        try {
162
163
            //TODO: Vernuenftige Fehlermeldung falls nicht auf qfq.ini zugegriffen werden kann.
            //TODO: sinnvollen Platz fuer qfq.ini bestimmen. In der Installationsdoku erwaehnen.
164
            $config = parse_ini_file(__DIR__ . '/../../../' . CONFIG_INI, false);
165

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

169
        } catch (\Exception $e) {
170
            throw new qfq\UserFormException ("Error read file " . CONFIG_INI . ": " . $e->getMessage(), ERROR_IO_READ_FILE);
171
        }
172

173
        // Adjust config
174
        if (!isset($config['SHOW_DEBUG_INFO']) || $config['SHOW_DEBUG_INFO'] === 'auto') {
175
176
177
            $config['SHOW_DEBUG_INFO'] = (isset($GLOBALS["TSFE"]->beUserLogin) && $GLOBALS["TSFE"]->beUserLogin === true) ? 'yes' : 'no';
        }

178
179
180
181
182
183
184
        // 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);
185
186
                if ($pos === false && isset($GLOBALS['TYPO3_LOADED_EXT'][EXT_KEY]['ext_localconf.php'])) {

187
                    // Typo3 extension: probably index.php
188
                    $config[SYSTEM_PATH_EXT] = dirname($GLOBALS['TYPO3_LOADED_EXT'][EXT_KEY]['ext_localconf.php']);
189
                    $config[SYSTEM_SITE_PATH] = dirname($_SERVER['SCRIPT_FILENAME']);
190
                } else {
191
                    // API
192
                    $config[SYSTEM_PATH_EXT] = substr($_SERVER['SCRIPT_FILENAME'], 0, $pos + strlen($relExtDir));
193
                    $config[SYSTEM_SITE_PATH] = substr($_SERVER['SCRIPT_FILENAME'], 0, $pos);
194
                }
195
196
197
198
            } else {
                // No $_SERVER >>this means phpUnit.
                $config[SYSTEM_SITE_PATH] = getcwd();
                $config[SYSTEM_PATH_EXT] = getcwd();
199
200
201
            }
        }

202
203
204
        // Defaults
        Support::setIfNotSet($config, SYSTEM_DATE_FORMAT, 'yyyy-mm-dd');

205
206
207
208
209
210
        // 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];
        }


211
        self::setVarArray($config, STORE_SYSTEM, true);
212
213
    }

214
215
216
    /**
     * @param array $dataArray
     * @param $store
217
     * @param bool|false $flagOverwrite
218
     * @throws UserFormException
219
     * @throws \qfq\CodeException
220
     */
221
    public static function setVarArray(array $dataArray, $store, $flagOverwrite = false) {
Carsten  Rose's avatar
Carsten Rose committed
222
        // Check valid Storename
Carsten  Rose's avatar
Carsten Rose committed
223
        if (!isset(self::$sanitizeStore))
224
            throw new UserFormException("Unknown Store: $store", ERROR_UNNOWN_STORE);
Carsten  Rose's avatar
Carsten Rose committed
225
226


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

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

234
235
        self::$raw[$store] = $dataArray;
    }
236

237
238
239
240
    /**
     * @param $bodytext
     * @throws CodeException
     */
241
    private static function fillStoreTypo3($bodytext) {
242

243
        $arr = KeyValueStringParser::parse($bodytext, "=", "\n");
244
245
246
247
248
249
250
251
252

        if (isset($GLOBALS["TSFE"]->fe_user->user["username"]))
            $arr[TYPO3_FE_USER] = $GLOBALS["TSFE"]->fe_user->user["username"];

        if (isset($GLOBALS["TSFE"]->fe_user->user["uid"]))
            $arr[TYPO3_FE_USER_UID] = $GLOBALS["TSFE"]->fe_user->user["uid"];

        if (isset($GLOBALS["TSFE"]->fe_user->user["usergroup"]))
            $arr[TYPO3_FE_USER_GROUP] = $GLOBALS["TSFE"]->fe_user->user["usergroup"];
253

Carsten  Rose's avatar
Carsten Rose committed
254
255
256
        if (isset($GLOBALS["TSFE"]->page["uid"]))
            $arr[TYPO3_TT_CONTENT_UID] = $GLOBALS["TSFE"]->page["uid"];

257
258
259
        if (isset($GLOBALS["TSFE"]->id))
            $arr[TYPO3_PAGE_ID] = $GLOBALS["TSFE"]->id;

Carsten  Rose's avatar
Carsten Rose committed
260
261
262
        if (isset($GLOBALS["TSFE"]->type))
            $arr[TYPO3_PAGE_TYPE] = $GLOBALS["TSFE"]->type;

263
264
265
        if (isset($GLOBALS["TSFE"]->sys_language_uid))
            $arr[TYPO3_PAGE_LANGUAGE] = $GLOBALS["TSFE"]->sys_language_uid;

266
        self::setVarArray($arr, STORE_TYPO3, true);
267
    }
268

269
270
271
    /**
     * @throws CodeException
     */
272
    private static function fillStoreClient() {
273
        // copy GET and POST and SERVER Parameter. Priority: SERVER, POST, GET
274
275
276
277
278
279
280
281
282
        $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);
283

284
        self::setVarArray($arr, STORE_CLIENT, true);
285
    }
286

Carsten  Rose's avatar
Carsten Rose committed
287
288
    /**
     * @throws CodeException
289
     * @throws UserFormException
Carsten  Rose's avatar
Carsten Rose committed
290
     */
291
    private static function fillStoreSip() {
Carsten  Rose's avatar
Carsten Rose committed
292

293
        $sessionName = self::getVar(SYSTEM_SESSION_NAME, STORE_SYSTEM);
294
        self::$sip = new Sip($sessionName);
295

296
297
298
299
        $s = self::getVar(CLIENT_SIP, STORE_CLIENT);
        if ($s !== false) {
            // if session is given, copy values to store
            $param = self::$sip->getVarsFromSip($s);
300
301
            $param[SIP_SIP] = $s;
            $param[SIP_URLPARAM] = self::$sip->getQueryStringFromSip($s);
302

303
//            self::setVarArray(KeyValueStringParser::parse($param, "=", "&"), STORE_SIP);
304
            self::setVarArray($param, STORE_SIP, true);
305
306
307
        }
    }

308
    /**
309
     * Cycles through all stores in $useStore.
310
     * First match will return the found value.
Carsten  Rose's avatar
Carsten Rose committed
311
     * During cycling: fill cache with requestet value and sanitize raw value.
312
     *
313
     * @param string $key
314
     * @param string $useStores f.e.: 'FSRD'
Carsten  Rose's avatar
Carsten Rose committed
315
     * @param string $sanitizeClass
Carsten  Rose's avatar
Carsten Rose committed
316
     * @param string $foundInStore Returns the name of the store where $key has been found. If $key is not found, return ''.
317
     * @return string a) if found: value, b) false
Carsten  Rose's avatar
Carsten Rose committed
318
     * @throws \qfq\CodeException
319
     */
Carsten  Rose's avatar
Carsten Rose committed
320
    public static function getVar($key, $useStores = STORE_USE_DEFAULT, $sanitizeClass = '', &$foundInStore = '') {
321
322

        // no store specifed?
323
        if ($useStores === "" || $useStores === null) {
324
            $useStores = STORE_USE_DEFAULT;
325
326
        }

327
        // no sanitizeClass specified: take predefined (if exist) or default.
328
        if ($sanitizeClass === '' || $sanitizeClass === null) {
Carsten  Rose's avatar
Carsten Rose committed
329
            $sanitizeClass = isset(self::$sanitizeClass[$key]) ? self::$sanitizeClass[$key] : SANITIZE_DEFAULT;
330
331
        }

332
333
334
        while ($useStores !== false) {

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

338
            if (!isset(self::$raw[$store][$key])) {
339
340
341
                switch ($store) {
                    case STORE_ZERO:
                        return 0;
342
343
                    case STORE_EMPTY:
                        return '';
344
345
                    case STORE_VAR:
                        if ($key === VAR_RANDOM) {
346
                            return Support::randomAlphaNum(RANDOM_LENGTH);
347
348
349
350
351
352
353
                        } 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
354
                }
355
356
            }

357
            $rawVal = isset(self::$raw[$store][$key]) ? self::$raw[$store][$key] : null;
Carsten  Rose's avatar
Carsten Rose committed
358
            if (self::$sanitizeStore[$store] && $sanitizeClass != '') {
359
360
361
362
363
                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);
364
365
            } else {
                return $rawVal;
366
            }
367
        }
Carsten  Rose's avatar
Carsten Rose committed
368
        $foundInStore = '';
369
        return false;
370
    }
371

Carsten  Rose's avatar
Carsten Rose committed
372
373
374
375
376
    /**
     * @throws UserFormException
     * @throws \qfq\CodeException
     */
    private static function fillStoreExtra() {
377
378
        $value = Session::get(STORE_EXTRA);
        if ($value === false)
Carsten  Rose's avatar
Carsten Rose committed
379
            self::setVarArray(array(), STORE_EXTRA, true);
380
381
        else
            self::setVarArray($_SESSION[STORE_EXTRA], STORE_EXTRA, true);
Carsten  Rose's avatar
Carsten Rose committed
382
383
    }

384
385
    /**
     * @param string $bodytext
386
     * @param bool|false $phpUnit
387
     * @return null|\qfq\Store
388
     */
389
    public static function getInstance($bodytext = '', $phpUnit = false) {
390

391
        if ($phpUnit) {
392
            if (self::$instance !== null) {
393
                // fake to have a clean environment for the next test.
394
395
396
397
398
                self::unsetStore(STORE_TYPO3);
                self::fillStoreTypo3($bodytext);

                self::unsetStore(STORE_CLIENT);
                self::fillStoreClient();
399
400
401
402
403
            }
        }

        // Design Pattern: Singleton
        if (self::$instance === null) {
404
405
406
            self::$phpUnit = $phpUnit;

            self::$instance = new self($bodytext);
Carsten  Rose's avatar
Carsten Rose committed
407
408
409
410
        } 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);
411
412
        }

413
414
415
416
417
418
419
        // 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);
        }

420
        return self::$instance;
421
    }
422

423
424
    /**
     * @param $store
425
426
     * @throws UserFormException
     * @throws \qfq\CodeException
427
428
     */
    public static function unsetStore($store) {
Carsten  Rose's avatar
Carsten Rose committed
429
        // Check valid Storename
Carsten  Rose's avatar
Carsten Rose committed
430
        if (!isset(self::$sanitizeStore))
431
            throw new UserFormException("Unknown Store: $store", ERROR_UNNOWN_STORE);
Carsten  Rose's avatar
Carsten Rose committed
432

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

436
437
438
        if (isset(self::$raw[$store])) {
            self::$raw[$store] = array();
        }
Carsten  Rose's avatar
Carsten Rose committed
439

440
441
    }

442
    /**
Carsten  Rose's avatar
Carsten Rose committed
443
444
445
     * @param string $key
     * @param string|array $value
     * @param string $store
446
447
448
449
450
451
452
453
454
455
456
457
458
     * @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])) {
459
            throw new UserFormException("Value of '$key' already set in store '$store'.", ERROR_STORE_KEY_EXIST);
460
461
462
        }

        self::$raw[$store][$key] = $value;
Carsten  Rose's avatar
Carsten Rose committed
463
464
465

        // The STORE_EXTRA saves arrays and is persistent
        if ($store === STORE_EXTRA) {
466
467
468
469
470
            $store = Session::get(STORE_EXTRA);
            if ($store === false)
                $store = array();
            $store[$key] = $value;
            Session::set(STORE_EXTRA, $store);
471

Carsten  Rose's avatar
Carsten Rose committed
472
473
        }

474
475
    }

476
477
478
479
    /**
     * @param $formName
     * @throws CodeException
     */
480
    public static function createSipAfterFormLoad($formName) {
481
        $recordId = self::getVar(CLIENT_RECORD_ID, STORE_TYPO3 . STORE_CLIENT);
482
483
484
485
486
487
488
        if ($recordId === false) {
            $recordId = 0;
        }

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

        // Construct fake urlparam
489
        $tmpUrlparam = OnArray::toString($tmpParam);
490
491

        // Create a fake SIP which has never been passed by URL - further processing might expect this to exist.
492
        $sip = self::getSipInstance()->queryStringToSip($tmpUrlparam, RETURN_SIP);
493
        self::setVar(CLIENT_SIP, $sip, STORE_CLIENT);
494
495
496
497
498

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

499
500
501
    }

    /**
502
     * @return null|Sip
503
     */
504
    public static function getSipInstance() {
505
506
        return self::$sip;
    }
507

508
509
    /**
     * @param $store
510
511
512
     * @return array
     * @throws UserFormException
     * @throws \qfq\CodeException
513
514
     */
    public static function getStore($store) {
Carsten  Rose's avatar
Carsten Rose committed
515
        // Check valid Storename
Carsten  Rose's avatar
Carsten Rose committed
516
        if (!isset(self::$sanitizeStore[$store]))
517
            throw new UserFormException("Unknown Store: $store", ERROR_UNNOWN_STORE);
Carsten  Rose's avatar
Carsten Rose committed
518

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

522
523
524
525
526
        if (isset(self::$raw[$store])) {
            return self::$raw[$store];
        }
        return array();
    }
527

Carsten  Rose's avatar
Carsten Rose committed
528

529
    /**
Carsten  Rose's avatar
Carsten Rose committed
530
531
     * Fills STORE_TABLE_DEFAULT and STORE_TABLE_COLUMN_TYPES
     *
532
533
534
     * @param $tableName
     * @throws CodeException
     */
535
    public static function fillStoreTableDefaultColumnType($tableName) {
536
537
538
539
        $db = new qfq\Database();

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

Carsten  Rose's avatar
Carsten Rose committed
540
541
        self::setVarArray(array_column($tableDefinition, 'Default', 'Field'), STORE_TABLE_DEFAULT, true);
        self::setVarArray(array_column($tableDefinition, 'Type', 'Field'), STORE_TABLE_COLUMN_TYPES, true);
542
    }
543
544
545
546
547
}