Completed
Pull Request — master (#563)
by Richard
08:33
created

XoopsObject::setVar()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 4
nc 2
nop 2
dl 0
loc 6
rs 9.2
c 0
b 0
f 0
ccs 5
cts 5
cp 1
crap 4
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
use Xoops\Core\Kernel\Dtype;
16
17
/**
18
 * Establish Xoops object datatype legacy defines
19
 * New code should use Dtype::TYPE_* constants
20
 *
21
 * These will eventually be removed. See Xoops\Core\Kernel\Dtype for more.
22
 */
23
define('XOBJ_DTYPE_TXTBOX',  Dtype::TYPE_TEXT_BOX);
24
define('XOBJ_DTYPE_TXTAREA', Dtype::TYPE_TEXT_AREA);
25
define('XOBJ_DTYPE_INT',     Dtype::TYPE_INTEGER);
26
define('XOBJ_DTYPE_URL',     Dtype::TYPE_URL);
27
define('XOBJ_DTYPE_EMAIL',   Dtype::TYPE_EMAIL);
28
define('XOBJ_DTYPE_ARRAY',   Dtype::TYPE_ARRAY);
29
define('XOBJ_DTYPE_OTHER',   Dtype::TYPE_OTHER);
30
define('XOBJ_DTYPE_SOURCE',  Dtype::TYPE_SOURCE);
31
define('XOBJ_DTYPE_STIME',   Dtype::TYPE_SHORT_TIME);
32
define('XOBJ_DTYPE_MTIME',   Dtype::TYPE_MEDIUM_TIME);
33
define('XOBJ_DTYPE_LTIME',   Dtype::TYPE_LONG_TIME);
34
define('XOBJ_DTYPE_FLOAT',   Dtype::TYPE_FLOAT);
35
define('XOBJ_DTYPE_DECIMAL', Dtype::TYPE_DECIMAL);
36
define('XOBJ_DTYPE_ENUM',    Dtype::TYPE_ENUM);
37
38
/**
39
 * Base class for all objects in the Xoops kernel (and beyond)
40
 *
41
 * @category  Xoops\Core\Kernel\XoopsObject
42
 * @package   Xoops\Core\Kernel
43
 * @author    Kazumi Ono (AKA onokazu) <http://www.myweb.ne.jp/, http://jp.xoops.org/>
44
 * @author    Taiwen Jiang <[email protected]>
45
 * @copyright 2000-2015 XOOPS Project (http://xoops.org)
46
 * @license   GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
47
 * @link      http://xoops.org
48
 * @since     2.0.0
49
 */
50
abstract class XoopsObject implements \ArrayAccess
51
{
52
    /**
53
     * holds all variables(properties) of an object
54
     *
55
     * @var array
56
     */
57
    public $vars = array();
58
59
    /**
60
     * variables cleaned for store in DB
61
     *
62
     * @var array
63
     */
64
    public $cleanVars = array();
65
66
    /**
67
     * is it a newly created object?
68
     *
69
     * @var bool
70
     */
71
    private $isNew = false;
72
73
    /**
74
     * has any of the values been modified?
75
     *
76
     * @var bool
77
     */
78
    private $isDirty = false;
79
80
    /**
81
     * errors
82
     *
83
     * @var array
84
     */
85
    private $errors = array();
86
87
    /**
88
     * @var string
89
     */
90
    public $plugin_path;
91
92
    /**
93
     * constructor
94
     *
95
     * normally, this is called from child classes only
96
     *
97
     * @access public
98
     */
99 22
    public function __construct()
100
    {
101 22
    }
102
103
    /**
104
     * used for new/clone objects
105
     *
106
     * @return void
107
     */
108 17
    public function setNew()
109
    {
110 17
        $this->isNew = true;
111 17
    }
112
113
    /**
114
     * clear new flag
115
     *
116
     * @return void
117
     */
118 8
    public function unsetNew()
119
    {
120 8
        $this->isNew = false;
121 8
    }
122
123
    /**
124
     * check new flag
125
     *
126
     * @return bool
127
     */
128 12
    public function isNew()
129
    {
130 12
        return $this->isNew;
131
    }
132
133
    /**
134
     * mark modified objects as dirty
135
     *
136
     * used for modified objects only
137
     *
138
     * @return void
139
     */
140 38
    public function setDirty()
141
    {
142 38
        $this->isDirty = true;
143 38
    }
144
145
    /**
146
     * cleaar dirty flag
147
     *
148
     * @return void
149
     */
150 14
    public function unsetDirty()
151
    {
152 14
        $this->isDirty = false;
153 14
    }
154
155
    /**
156
     * check dirty flag
157
     *
158
     * @return bool
159
     */
160 14
    public function isDirty()
161
    {
162 14
        return $this->isDirty;
163
    }
164
165
    /**
166
     * initialize variables for the object
167
     *
168
     * @param string $key       key
169
     * @param int    $data_type set to one of Dtype::TYPE_XXX constants (set to Dtype::TYPE_OTHER
170
     *                           if no data type checking nor text sanitizing is required)
171
     * @param mixed  $value     value
172
     * @param bool   $required  require html form input?
173
     * @param mixed  $maxlength for Dtype::TYPE_TEXT_BOX type only
174
     * @param string $options   does this data have any select options?
175
     *
176
     * @return void
177
     */
178 302
    public function initVar($key, $data_type, $value = null, $required = false, $maxlength = null, $options = '')
179
    {
180 302
        $this->vars[$key] = array(
181 302
            'value' => $value,
182 302
            'required' => $required,
183 302
            'data_type' => $data_type,
184 302
            'maxlength' => $maxlength,
185
            'changed' => false,
186 302
            'options' => $options
187
        );
188 302
    }
189
190
    /**
191
     * assign a value to a variable
192
     *
193
     * @param string $key   name of the variable to assign
194
     * @param mixed  $value value to assign
195
     *
196
     * @return void
197
     */
198 60
    public function assignVar($key, $value)
199
    {
200 60
        if (isset($key) && isset($this->vars[$key])) {
201 60
            $this->vars[$key]['value'] = $value;
202
        }
203 60
    }
204
205
    /**
206
     * assign values to multiple variables in a batch
207
     *
208
     * @param array $var_arr associative array of values to assign
209
     *
210
     * @return void
211
     */
212 51
    public function assignVars($var_arr)
213
    {
214 51
        if (is_array($var_arr)) {
0 ignored issues
show
introduced by
The condition is_array($var_arr) can never be false.
Loading history...
215 51
            foreach ($var_arr as $key => $value) {
216 51
                $this->assignVar($key, $value);
217
            }
218
        }
219 51
    }
220
221
    /**
222
     * assign a value to a variable
223
     *
224
     * @param string $key     name of the variable to assign
225
     * @param mixed  $value   value to assign
226
     *
227
     * @return void
228
     */
229 36
    public function setVar($key, $value)
230
    {
231 36
        if (!empty($key) && isset($value) && isset($this->vars[$key])) {
232 36
            $this->vars[$key]['value'] = $value;
233 36
            $this->vars[$key]['changed'] = true;
234 36
            $this->setDirty();
235
        }
236 36
    }
237
238
    /**
239
     * assign values to multiple variables in a batch
240
     *
241
     * @param array $var_arr associative array of values to assign
242
     *
243
     * @return void
244
     */
245 1
    public function setVars($var_arr)
246
    {
247 1
        if (is_array($var_arr)) {
0 ignored issues
show
introduced by
The condition is_array($var_arr) can never be false.
Loading history...
248 1
            foreach ($var_arr as $key => $value) {
249 1
                $this->setVar($key, $value);
250
            }
251
        }
252 1
    }
253
254
    /**
255
     * unset variable(s) for the object
256
     *
257
     * @param mixed $var variable(s)
258
     *
259
     * @return bool
260
     */
261 1
    public function destroyVars($var)
262
    {
263 1
        if (empty($var)) {
264 1
            return true;
265
        }
266
        $var = !is_array($var) ? array($var) : $var;
267
        foreach ($var as $key) {
268
            if (!isset($this->vars[$key])) {
269
                continue;
270
            }
271
            $this->vars[$key]['changed'] = null;
272
        }
273
        return true;
274
    }
275
276
    /**
277
     * Assign values to multiple variables in a batch
278
     *
279
     * Meant for a CGI context:
280
     * - prefixed CGI args are considered save
281
     * - avoids polluting of namespace with CGI args
282
     *
283
     * @param mixed  $var_arr associative array of values to assign
284
     * @param string $pref    prefix (only keys starting with the prefix will be set)
285
     *
286
     * @return void
287
     */
288 1
    public function setFormVars($var_arr = null, $pref = 'xo_')
289
    {
290 1
        $len = strlen($pref);
291 1
        if (is_array($var_arr)) {
292 1
            foreach ($var_arr as $key => $value) {
293 1
                if ($pref == substr($key, 0, $len)) {
294 1
                    $this->setVar(substr($key, $len), $value);
295
                }
296
            }
297
        }
298 1
    }
299
300
    /**
301
     * returns all variables for the object
302
     *
303
     * @return array associative array of key->value pairs
304
     */
305 26
    public function getVars()
306
    {
307 26
        return $this->vars;
308
    }
309
310
    /**
311
     * Returns the values of the specified variables
312
     *
313
     * @param mixed  $keys     An array containing the names of the keys to retrieve, or null to get all of them
314
     * @param string $format   Format to use (see getVar)
315
     * @param int    $maxDepth Maximum level of recursion to use if some vars are objects themselves
316
     *
317
     * @return array associative array of key->value pairs
318
     */
319 3
    public function getValues($keys = null, $format = Dtype::FORMAT_SHOW, $maxDepth = 1)
320
    {
321 3
        if (!isset($keys)) {
322 3
            $keys = array_keys($this->vars);
323
        }
324 3
        $vars = array();
325 3
        if (is_array($keys)) {
326 3
            foreach ($keys as $key) {
327 3
                if (isset($this->vars[$key])) {
328 3
                    if (is_object($this->vars[$key]) && is_a($this->vars[$key], 'Xoops\Core\Kernel\XoopsObject')) {
329
                        if ($maxDepth) {
330
                            /* @var $obj XoopsObject */
331
                            $obj = $this->vars[$key];
332
                            $vars[$key] = $obj->getValues(null, $format, $maxDepth - 1);
333
                        }
334
                    } else {
335 3
                        $vars[$key] = $this->getVar($key, $format);
336
                    }
337
                }
338
            }
339
        }
340 3
        return $vars;
341
    }
342
343
    /**
344
     * returns a specific variable for the object in a proper format
345
     *
346
     * @param string $key    key of the object's variable to be returned
347
     * @param string $format format to use for the output
348
     *
349
     * @return mixed formatted value of the variable
350
     */
351 202
    public function getVar($key, $format = Dtype::FORMAT_SHOW)
352
    {
353 202
        $ret = null;
354 202
        if (!isset($this->vars[$key])) {
355 1
            return $ret;
356
        }
357 202
        $ret = Dtype::getVar($this, $key, $format);
358 202
        return $ret;
359
    }
360
361
    /**
362
     * clean values of all variables of the object for storage.
363
     *
364
     * @return bool true if successful
365
     */
366 3
    public function cleanVars()
367
    {
368 3
        $existing_errors = $this->getErrors();
369 3
        $this->errors = array();
370 3
        foreach ($this->vars as $k => $v) {
371 3
            if (!$v['changed']) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
372
            } else {
373 3
                $this->cleanVars[$k] = Dtype::cleanVar($this, $k);
374
            }
375
        }
376 3
        if (count($this->errors) > 0) {
377
            $this->errors = array_merge($existing_errors, $this->errors);
378
            return false;
379
        }
380
        // $this->_errors = array_merge($existing_errors, $this->_errors);
381 3
        $this->unsetDirty();
382 3
        return true;
383
    }
384
385
    /**
386
     * create a clone(copy) of the current object
387
     *
388
     * @return object clone
389
     */
390 1
    public function xoopsClone()
391
    {
392 1
        $clone = clone $this;
393 1
        return $clone;
394
    }
395
396
    /**
397
     * Adjust a newly cloned object
398
     */
399 1
    public function __clone()
400
    {
401
        // need this to notify the handler class that this is a newly created object
402 1
        $this->setNew();
403 1
    }
404
405
    /**
406
     * add an error
407
     *
408
     * @param string $err_str to add
409
     *
410
     * @return void
411
     */
412 2
    public function setErrors($err_str)
413
    {
414 2
        if (is_array($err_str)) {
0 ignored issues
show
introduced by
The condition is_array($err_str) can never be true.
Loading history...
415 1
            $this->errors = array_merge($this->errors, $err_str);
416
        } else {
417 2
            $this->errors[] = trim($err_str);
418
        }
419 2
    }
420
421
    /**
422
     * return the errors for this object as an array
423
     *
424
     * @return array an array of errors
425
     */
426 14
    public function getErrors()
427
    {
428 14
        return $this->errors;
429
    }
430
431
    /**
432
     * return the errors for this object as html
433
     *
434
     * @return string html listing the errors
435
     * @todo remove hardcoded HTML strings
436
     */
437 1
    public function getHtmlErrors()
438
    {
439 1
        $ret = '<h4>Errors</h4>';
440 1
        if (!empty($this->errors)) {
441 1
            foreach ($this->errors as $error) {
442 1
                $ret .= $error . '<br />';
443
            }
444
        } else {
445
            $ret .= 'None<br />';
446
        }
447 1
        return $ret;
448
    }
449
450
    /**
451
     * Get object variables as an array
452
     *
453
     * @return array of object values
454
     */
455 1
    public function toArray()
456
    {
457 1
        return $this->getValues();
458
    }
459
460
    /**
461
     * ArrayAccess methods
462
     */
463
464
    /**
465
     * offsetExists
466
     *
467
     * @param mixed $offset array key
468
     *
469
     * @return bool true if offset exists
470
     */
471 2
    public function offsetExists($offset)
472
    {
473 2
        return isset($this->vars[$offset]);
474
    }
475
476
    /**
477
     * offsetGet
478
     *
479
     * @param mixed $offset array key
480
     *
481
     * @return mixed value
482
     */
483 6
    public function offsetGet($offset)
484
    {
485 6
        return $this->getVar($offset);
486
    }
487
488
    /**
489
     * offsetSet
490
     *
491
     * @param mixed $offset array key
492
     * @param mixed $value
493
     *
494
     * @return void
495
     */
496 15
    public function offsetSet($offset, $value)
497
    {
498 15
        $this->setVar($offset, $value);
499 15
    }
500
501
    /**
502
     * offsetUnset
503
     *
504
     * @param mixed $offset array key
505
     *
506
     * @return void
507
     */
508 2
    public function offsetUnset($offset)
509
    {
510 2
        $this->vars[$offset]['value'] = null;
511 2
        $this->vars[$offset]['changed'] = true;
512 2
        $this->setDirty();
513 2
    }
514
}
515