Completed
Push — datatype ( 11f376 )
by Richard
11:36
created

XoopsObject::offsetGet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
ccs 2
cts 2
cp 1
crap 1
1
<?php
2
/**
3
 * XOOPS Kernel Object
4
 *
5
 * You may not change or alter any portion of this comment or credits
6
 * of supporting developers from this source code or any supporting source code
7
 * which is considered copyrighted (c) material of the original comment or credit authors.
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 */
12
13
namespace Xoops\Core\Kernel;
14
15
/**
16
 * Establish Xoops object datatype legacy defines
17
 * New code should use DataType::* constants
18
 *
19
 * These will eventually be removed. See Xoops\Core\Kernel\DataType for more.
20
 */
21
define('XOBJ_DTYPE_TXTBOX', DataType\StringType::class);
22
define('XOBJ_DTYPE_TXTAREA', DataType\TextType::class);
23
define('XOBJ_DTYPE_INT', DataType\IntegerType::class);
24
define('XOBJ_DTYPE_URL', DataType\UrlType::class);
25
define('XOBJ_DTYPE_EMAIL', DataType\EmailType::class);
26
define('XOBJ_DTYPE_ARRAY', DataType\ArrayType::class);
27
define('XOBJ_DTYPE_OTHER', DataType\OtherType::class);
28
define('XOBJ_DTYPE_SOURCE', DataType\SourceType::class);
29
define('XOBJ_DTYPE_STIME', DataType\SimpleTimeType::class);
30
define('XOBJ_DTYPE_MTIME', DataType\SimpleTimeType::class);
31
define('XOBJ_DTYPE_LTIME', DataType\SimpleTimeType::class);
32
define('XOBJ_DTYPE_FLOAT', DataType\FloatType::class);
33
define('XOBJ_DTYPE_DECIMAL', DataType\DecimalType::class);
34
define('XOBJ_DTYPE_ENUM', DataType\EnumerationType::class);
35
36
37
/**
38
 * Base class for all objects in the Xoops kernel (and beyond)
39
 *
40
 * @category  Xoops\Core\Kernel\XoopsObject
41
 * @package   Xoops\Core\Kernel
42
 * @author    Kazumi Ono (AKA onokazu) <http://www.myweb.ne.jp/, http://jp.xoops.org/>
43
 * @author    Taiwen Jiang <[email protected]>
44
 * @copyright 2000-2019 XOOPS Project (https://xoops.org)
45
 * @license   GNU GPL 2 or later (https://www.gnu.org/licenses/gpl-2.0.html)
46
 */
47
abstract class XoopsObject implements \ArrayAccess
48
{
49
    /**
50
     * holds all variables(properties) of an object
51
     *
52
     * @var array
53
     */
54
    public $vars = [];
55
56
    /**
57
     * variables cleaned for store in DB
58
     *
59
     * @var array
60
     */
61
    public $cleanVars = [];
62
63
    /**
64
     * parameter types matching $cleanVars above
65
     *
66
     * @var array
67
     */
68
    public $cleanTypes = [];
69
70
    /**
71
     * is it a newly created object?
72
     *
73
     * @var bool
74
     */
75
    private $isNew = false;
76
77
    /**
78
     * has any of the values been modified?
79
     *
80
     * @var bool
81
     */
82
    private $isDirty = false;
83
84
    /**
85
     * errors
86
     *
87
     * @var array
88
     */
89
    private $errors = [];
90
91
    /**
92
     * @var string
93
     */
94
    public $plugin_path;
95
96
    /**
97
     * constructor
98
     *
99
     * normally, this is called from child classes only
100
     *
101
     * @access public
102
     */
103 24
    public function __construct()
104
    {
105 24
    }
106
107
    /**
108
     * used for new/clone objects
109
     *
110
     * @return void
111
     */
112 17
    public function setNew(): void
113
    {
114 17
        $this->isNew = true;
115 17
    }
116
117
    /**
118
     * clear new flag
119
     *
120
     * @return void
121
     */
122 8
    public function unsetNew(): void
123
    {
124 8
        $this->isNew = false;
125 8
    }
126
127
    /**
128
     * check new flag
129
     *
130
     * @return bool
131
     */
132 12
    public function isNew(): bool
133
    {
134 12
        return $this->isNew;
135
    }
136
137
    /**
138
     * mark modified objects as dirty
139
     *
140
     * used for modified objects only
141
     *
142
     * @return void
143
     */
144 39
    public function setDirty(): void
145
    {
146 39
        $this->isDirty = true;
147 39
    }
148
149
    /**
150
     * clear dirty flag
151
     *
152
     * @return void
153
     */
154 14
    public function unsetDirty(): void
155
    {
156 14
        $this->isDirty = false;
157 14
    }
158
159
    /**
160
     * check dirty flag
161
     *
162
     * @return bool
163
     */
164 14
    public function isDirty(): bool
165
    {
166 14
        return $this->isDirty;
167
    }
168
169
    /**
170
     * initialize variables for the object
171
     *
172
     * @param string $key       key
173
     * @param int    $data_type set to one of DataType::XXX constants (set to DataType::OTHER
174
     *                           if no data type checking nor text sanitizing is required)
175
     * @param mixed  $value     value
176
     * @param bool   $required  require html form input?
177
     * @param mixed  $maxlength for DataType::STRING type only
178
     * @param string $options   does this data have any select options?
179
     *
180
     * @return void
181
     */
182 304
    public function initVar($key, $data_type, $value = null, $required = false, $maxlength = null, $options = ''): void
183
    {
184 304
        $this->vars[$key] = [
185 304
            'value' => $value,
186 304
            'required' => $required,
187 304
            'data_type' => $data_type,
188 304
            'maxlength' => $maxlength,
189
            'changed' => false,
190 304
            'options' => $options
191
        ];
192 304
    }
193
194
    /**
195
     * assign a value to a variable
196
     *
197
     * @param string $key   name of the variable to assign
198
     * @param mixed  $value value to assign
199
     *
200
     * @return void
201
     */
202 59
    public function assignVar($key, $value): void
203
    {
204 59
        if (isset($key, $this->vars[$key])) {
205 59
            $this->vars[$key]['value'] = $value;
206
        }
207 59
    }
208
209
    /**
210
     * assign values to multiple variables in a batch
211
     *
212
     * @param array $var_arr associative array of values to assign
213
     *
214
     * @return void
215
     */
216 50
    public function assignVars($var_arr): void
217
    {
218 50
        if (is_array($var_arr)) {
0 ignored issues
show
introduced by
The condition is_array($var_arr) is always true.
Loading history...
219 50
            foreach ($var_arr as $key => $value) {
220 50
                $this->assignVar($key, $value);
221
            }
222
        }
223 50
    }
224
225
    /**
226
     * assign a value to a variable
227
     *
228
     * @param string $key     name of the variable to assign
229
     * @param mixed  $value   value to assign
230
     *
231
     * @return void
232
     */
233 37
    public function setVar($key, $value): void
234
    {
235 37
        if (!empty($key) && isset($value, $this->vars[$key])) {
236 37
            $this->vars[$key]['value'] = $value;
237 37
            $this->vars[$key]['changed'] = true;
238 37
            $this->setDirty();
239
        }
240 37
    }
241
242
    /**
243
     * assign values to multiple variables in a batch
244
     *
245
     * @param array $var_arr associative array of values to assign
246
     *
247
     * @return void
248
     */
249 4
    public function setVars($var_arr): void
250
    {
251 4
        if (is_array($var_arr)) {
0 ignored issues
show
introduced by
The condition is_array($var_arr) is always true.
Loading history...
252 4
            foreach ($var_arr as $key => $value) {
253 4
                $this->setVar($key, $value);
254
            }
255
        }
256 4
    }
257
258
    /**
259
     * unset variable(s) for the object
260
     *
261
     * @param string|string[] $var variable(s)
262
     *
263
     * @return bool
264
     */
265 1
    public function destroyVars($var): bool
266
    {
267 1
        if (empty($var)) {
268 1
            return true;
269
        }
270
        $var = !is_array($var) ? [$var] : $var;
271
        foreach ($var as $key) {
272
            if (!isset($this->vars[$key])) {
273
                continue;
274
            }
275
            $this->vars[$key]['changed'] = null;
276
        }
277
        return true;
278
    }
279
280
    /**
281
     * returns all variables for the object
282
     *
283
     * @return array associative array of key->value pairs
284
     */
285 26
    public function getVars(): array
286
    {
287 26
        return $this->vars;
288
    }
289
290
    /**
291
     * Returns the values of the specified variables
292
     *
293
     * @param mixed  $keys     An array containing the names of the keys to retrieve, or null to get all of them
294
     * @param string $format   Format::xxxx constant representing intended use (see getVar)
295
     * @param int    $maxDepth Maximum level of recursion to use if some vars are objects themselves
296
     *
297
     * @return array associative array of key->value pairs
298
     */
299 3
    public function getValues($keys = null, $format = Format::SHOW, $maxDepth = 1)
300
    {
301 3
        if (!isset($keys)) {
302 3
            $keys = array_keys($this->vars);
303
        }
304 3
        $vars = [];
305 3
        if (is_array($keys)) {
306 3
            foreach ($keys as $key) {
307 3
                if (isset($this->vars[$key])) {
308 3
                    if ($this->vars[$key] instanceof self) {
309
                        if ($maxDepth) {
310
                            /* @var $obj XoopsObject */
311
                            $obj = $this->vars[$key];
312
                            $vars[$key] = $obj->getValues(null, $format, $maxDepth - 1);
313
                        }
314
                    } else {
315 3
                        $vars[$key] = $this->getVar($key, $format);
316
                    }
317
                }
318
            }
319
        }
320 3
        return $vars;
321
    }
322
323
    /**
324
     * returns a specific variable for the object in a proper format
325
     *
326
     * @param string $key    key of the object's variable to be returned
327
     * @param string $format format to use for the output
328
     *
329
     * @return mixed formatted value of the variable
330
     */
331 203
    public function getVar($key, $format = Format::SHOW)
332
    {
333 203
        $ret = null;
334 203
        if (!isset($this->vars[$key])) {
335 1
            return $ret;
336
        }
337 203
        $ret = DataType::getVar($this, $key, $format);
338 203
        return $ret;
339
    }
340
341
    /**
342
     * clean values of all variables of the object for storage.
343
     *
344
     * @return bool true if successful
345
     */
346 3
    public function cleanVars(): bool
347
    {
348 3
        $existing_errors = $this->getErrors();
349 3
        $this->errors = [];
350 3
        foreach ($this->vars as $k => $v) {
351 3
            if ($v['changed']) {
352 3
                $this->cleanVars[$k] = DataType::cleanVar($this, $k);
353
            }
354
        }
355 3
        $this->cleanTypes = [];
356 3
        foreach ($this->cleanVars as $k => $v) {
357 3
            $this->cleanTypes[] = DataType::getBindingType($this, $k);
358
        }
359 3
        if (count($this->errors) > 0) {
360
            $this->errors = array_merge($existing_errors, $this->errors);
361
            return false;
362
        }
363
        // $this->_errors = array_merge($existing_errors, $this->_errors);
364 3
        $this->unsetDirty();
365 3
        return true;
366
    }
367
368
    /**
369
     * create a clone(copy) of the current object
370
     *
371
     * @return object clone
372
     */
373 1
    public function xoopsClone()
374
    {
375 1
        return clone $this;
376
    }
377
378
    /**
379
     * Adjust a newly cloned object
380
     */
381 1
    public function __clone()
382
    {
383
        // need this to notify the handler class that this is a newly created object
384 1
        $this->setNew();
385 1
    }
386
387
    /**
388
     * add an error
389
     *
390
     * @param string $err_str to add
391
     *
392
     * @return void
393
     */
394 2
    public function setErrors($err_str): void
395
    {
396 2
        if (is_array($err_str)) {
0 ignored issues
show
introduced by
The condition is_array($err_str) is always false.
Loading history...
397 1
            $this->errors = array_merge($this->errors, $err_str);
398
        } else {
399 2
            $this->errors[] = trim($err_str);
400
        }
401 2
    }
402
403
    /**
404
     * return the errors for this object as an array
405
     *
406
     * @return array an array of errors
407
     */
408 14
    public function getErrors(): array
409
    {
410 14
        return $this->errors;
411
    }
412
413
    /**
414
     * return the errors for this object as html
415
     *
416
     * @return string html listing the errors
417
     * @todo remove hardcoded HTML strings
418
     */
419 1
    public function getHtmlErrors(): string
420
    {
421 1
        $ret = '<h4>Errors</h4>';
422 1
        if (!empty($this->errors)) {
423 1
            foreach ($this->errors as $error) {
424 1
                $ret .= $error . '<br />';
425
            }
426
        } else {
427
            $ret .= 'None<br />';
428
        }
429 1
        return $ret;
430
    }
431
432
    /**
433
     * Get object variables as an array
434
     *
435
     * @return array of object values
436
     */
437 1
    public function toArray()
438
    {
439 1
        return $this->getValues();
440
    }
441
442
    /**
443
     * ArrayAccess methods
444
     */
445
446
    /**
447
     * offsetExists
448
     *
449
     * @param mixed $offset array key
450
     *
451
     * @return bool true if offset exists
452
     */
453 1
    public function offsetExists($offset)
454
    {
455 1
        return isset($this->vars[$offset]);
456
    }
457
458
    /**
459
     * offsetGet
460
     *
461
     * @param mixed $offset array key
462
     *
463
     * @return mixed value
464
     */
465 5
    public function offsetGet($offset)
466
    {
467 5
        return $this->getVar($offset);
468
    }
469
470
    /**
471
     * offsetSet
472
     *
473
     * @param mixed $offset array key
474
     * @param mixed $value
475
     *
476
     * @return void
477
     */
478 15
    public function offsetSet($offset, $value)
479
    {
480 15
        $this->setVar($offset, $value);
481 15
    }
482
483
    /**
484
     * offsetUnset
485
     *
486
     * @param mixed $offset array key
487
     *
488
     * @return void
489
     */
490 2
    public function offsetUnset($offset)
491
    {
492 2
        $this->vars[$offset]['value'] = null;
493 2
        $this->vars[$offset]['changed'] = true;
494 2
        $this->setDirty();
495 2
    }
496
}
497