Passed
Push — master ( b5dddf...91d417 )
by Richard
09:12
created

XoopsObject::assignVars()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 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
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
13
 * @license             GNU GPL 2 (http://www.gnu.org/licenses/gpl-2.0.html)
14
 * @package             kernel
15
 * @since               2.0.0
16
 * @author              Kazumi Ono (AKA onokazu) http://www.myweb.ne.jp/, http://jp.xoops.org/
17
 * @author              Taiwen Jiang <[email protected]>
18
 */
19
20
defined('XOOPS_ROOT_PATH') || exit('Restricted access');
21
/**
22
 * YOU SHOULD NOT USE ANY OF THE UNICODE TYPES, THEY WILL BE REMOVED
23
 */
24
25
/**
26
 * *#@+
27
 * Xoops object datatype
28
 */
29
define('XOBJ_DTYPE_TXTBOX', 1);
30
define('XOBJ_DTYPE_TXTAREA', 2);
31
define('XOBJ_DTYPE_INT', 3);
32
define('XOBJ_DTYPE_URL', 4);
33
define('XOBJ_DTYPE_EMAIL', 5);
34
define('XOBJ_DTYPE_ARRAY', 6);
35
define('XOBJ_DTYPE_OTHER', 7);
36
define('XOBJ_DTYPE_SOURCE', 8);
37
define('XOBJ_DTYPE_STIME', 9);
38
define('XOBJ_DTYPE_MTIME', 10);
39
define('XOBJ_DTYPE_LTIME', 11);
40
define('XOBJ_DTYPE_FLOAT', 13);
41
define('XOBJ_DTYPE_DECIMAL', 14);
42
define('XOBJ_DTYPE_ENUM', 15);
43
// YOU SHOULD NEVER USE THE FOLLOWING TYPES, THEY WILL BE REMOVED
44
define('XOBJ_DTYPE_UNICODE_TXTBOX', 16);
45
define('XOBJ_DTYPE_UNICODE_TXTAREA', 17);
46
define('XOBJ_DTYPE_UNICODE_URL', 18);
47
define('XOBJ_DTYPE_UNICODE_EMAIL', 19);
48
define('XOBJ_DTYPE_UNICODE_ARRAY', 20);
49
define('XOBJ_DTYPE_UNICODE_OTHER', 21);
50
// Addition for 2.5.5
51
define('XOBJ_DTYPE_DATE', 22);
52
define('XOBJ_DTYPE_TIME', 23);
53
define('XOBJ_DTYPE_TIMESTAMP', 24);
54
55
/**
56
 * Base class for all objects in the Xoops kernel (and beyond)
57
 */
58
class XoopsObject
59
{
60
    /**
61
     * holds all variables(properties) of an object
62
     *
63
     * @var array
64
     * @access protected
65
     */
66
    public $vars = array();
67
68
    /**
69
     * variables cleaned for store in DB
70
     *
71
     * @var array
72
     * @access protected
73
     */
74
    public $cleanVars = array();
75
76
    /**
77
     * is it a newly created object?
78
     *
79
     * @var bool
80
     * @access private
81
     */
82
    public $_isNew = false;
83
84
    /**
85
     * has any of the values been modified?
86
     *
87
     * @var bool
88
     * @access private
89
     */
90
    public $_isDirty = false;
91
92
    /**
93
     * errors
94
     *
95
     * @var array
96
     * @access private
97
     */
98
    public $_errors = array();
99
100
    /**
101
     * additional filters registered dynamically by a child class object
102
     *
103
     * @access private
104
     */
105
    public $_filters = array();
106
107
    /**
108
     * constructor
109
     *
110
     * normally, this is called from child classes only
111
     *
112
     * @access public
113
     */
114
    public function __construct()
115
    {
116
    }
117
118
    /**
119
     * PHP 4 style constructor compatibility shim
120
     * @deprecated all callers should be using parent::__construct()
121
     */
122
    public function XoopsObject()
123
    {
124
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
125
        trigger_error("Should call parent::__construct in {$trace[0]['file']} line {$trace[0]['line']},");
126
        self::__construct();
0 ignored issues
show
Bug Best Practice introduced by
The method XoopsObject::__construct() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

126
        self::/** @scrutinizer ignore-call */ 
127
              __construct();
Loading history...
127
    }
128
129
    /**
130
     * *#@+
131
     * used for new/clone objects
132
     *
133
     * @access public
134
     */
135
    public function setNew()
136
    {
137
        $this->_isNew = true;
138
    }
139
140
    public function unsetNew()
141
    {
142
        $this->_isNew = false;
143
    }
144
145
    /**
146
     * @return bool
147
     */
148
    public function isNew()
149
    {
150
        return $this->_isNew;
151
    }
152
153
    /**
154
     * *#@+
155
     * mark modified objects as dirty
156
     *
157
     * used for modified objects only
158
     *
159
     * @access public
160
     */
161
    public function setDirty()
162
    {
163
        $this->_isDirty = true;
164
    }
165
166
    public function unsetDirty()
167
    {
168
        $this->_isDirty = false;
169
    }
170
171
    /**
172
     * @return bool
173
     */
174
    public function isDirty()
175
    {
176
        return $this->_isDirty;
177
    }
178
179
    /**
180
     * initialize variables for the object
181
     *
182
     * YOU SHOULD NOT USE THE $enumeration PARAMETER
183
     *
184
     * @access   public
185
     *
186
     * @param string $key
187
     * @param int    $data_type set to one of XOBJ_DTYPE_XXX constants (set to XOBJ_DTYPE_OTHER if no data type checking nor text sanitizing is required)
188
     * @param null   $value
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $value is correct as it would always require null to be passed?
Loading history...
189
     * @param bool   $required  require html form input?
190
     * @param int    $maxlength for XOBJ_DTYPE_TXTBOX type only
191
     * @param string $options
192
     * @param string $enumerations
193
     *
194
     * @return void
195
     */
196
    public function initVar($key, $data_type, $value = null, $required = false, $maxlength = null, $options = '', $enumerations = '')
197
    {
198
        $this->vars[$key] = array(
199
            'value'       => $value,
200
            'required'    => $required,
201
            'data_type'   => $data_type,
202
            'maxlength'   => $maxlength,
203
            'changed'     => false,
204
            'options'     => $options,
205
            'enumeration' => $enumerations);
206
    }
207
208
    /**
209
     * assign a value to a variable
210
     *
211
     * @access public
212
     * @param string $key   name of the variable to assign
213
     * @param mixed  $value value to assign
214
     */
215
    public function assignVar($key, $value)
216
    {
217
        if (isset($key) && isset($this->vars[$key])) {
218
            switch ($this->vars[$key]['data_type']) {
219
                case XOBJ_DTYPE_UNICODE_ARRAY:
220
                    if (is_array($value)) {
221
                        $this->vars[$key]['value'] =& array_walk($value, 'xoops_aw_decode');
222
                    } else {
223
                        $this->vars[$key]['value'] =& xoops_convert_decode($value);
224
                    }
225
                    break;
226
                case XOBJ_DTYPE_UNICODE_URL:
227
                case XOBJ_DTYPE_UNICODE_EMAIL:
228
                case XOBJ_DTYPE_UNICODE_OTHER:
229
                case XOBJ_DTYPE_UNICODE_TXTBOX:
230
                case XOBJ_DTYPE_UNICODE_TXTAREA:
231
                    $this->vars[$key]['value'] = xoops_convert_decode($value);
232
                    break;
233
                case XOBJ_DTYPE_DATE:
234
                    if (!is_string($value) && is_numeric($value)) {
235
                        $this->vars[$key]['value'] = date(_DBDATESTRING, $value);
236
                    } else {
237
                        $this->vars[$key]['value'] = date(_DBDATESTRING, strtotime($value));
238
                    }
239
                    break;
240
                case XOBJ_DTYPE_TIME:
241
                    if (!is_string($value) && is_numeric($value)) {
242
                        $this->vars[$key]['value'] = date(_DBTIMESTRING, $value);
243
                    } else {
244
                        $this->vars[$key]['value'] = date(_DBTIMESTRING, strtotime($value));
245
                    }
246
                    break;
247
                case XOBJ_DTYPE_TIMESTAMP:
248
                    if (!is_string($value) && is_numeric($value)) {
249
                        $this->vars[$key]['value'] = date(_DBTIMESTAMPSTRING, $value);
250
                    } else {
251
                        $this->vars[$key]['value'] = date(_DBTIMESTAMPSTRING, strtotime($value));
252
                    }
253
                    break;
254
                // YOU SHOULD NOT USE THE ABOVE TYPES, THEY WILL BE REMOVED
255
                default:
256
                    $this->vars[$key]['value'] =& $value;
257
            }
258
        }
259
    }
260
261
    /**
262
     * assign values to multiple variables in a batch
263
     *
264
     * @access   private
265
     * @param $var_arr
266
     * @internal param array $var_array associative array of values to assign
267
     */
268
    public function assignVars($var_arr)
269
    {
270
        foreach ($var_arr as $key => $value) {
271
            $this->assignVar($key, $value);
272
        }
273
    }
274
275
    /**
276
     * assign a value to a variable
277
     *
278
     * @access public
279
     * @param string $key   name of the variable to assign
280
     * @param mixed  $value value to assign
281
     * @param bool   $not_gpc
282
     */
283
    public function setVar($key, $value, $not_gpc = false)
284
    {
285
        if (!empty($key) && isset($value) && isset($this->vars[$key])) {
286
            $this->vars[$key]['value']   =& $value;
287
            $this->vars[$key]['not_gpc'] = $not_gpc;
288
            $this->vars[$key]['changed'] = true;
289
            $this->setDirty();
290
        }
291
    }
292
293
    /**
294
     * assign values to multiple variables in a batch
295
     *
296
     * @access private
297
     * @param array $var_arr associative array of values to assign
298
     * @param bool  $not_gpc
299
     */
300
    public function setVars($var_arr, $not_gpc = false)
301
    {
302
        foreach ($var_arr as $key => $value) {
303
            $this->setVar($key, $value, $not_gpc);
304
        }
305
    }
306
307
    /**
308
     * unset variable(s) for the object
309
     *
310
     * @access public
311
     *
312
     * @param mixed $var
313
     *
314
     * @return bool
315
     */
316
    public function destroyVars($var)
317
    {
318
        if (empty($var)) {
319
            return true;
320
        }
321
        $var = !is_array($var) ? array($var) : $var;
322
        foreach ($var as $key) {
323
            if (!isset($this->vars[$key])) {
324
                continue;
325
            }
326
            $this->vars[$key]['changed'] = null;
327
        }
328
329
        return true;
330
    }
331
332
    /**
333
     * @param $var
334
     * @return bool
335
     * @deprecated use destroyVars() instead,  destoryVars() will be removed in the next major release
336
     */
337
    public function destoryVars($var)
338
    {
339
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
340
        trigger_error("XoopsObject::destoryVars() is deprecated, called from {$trace[0]['file']} line {$trace[0]['line']}");
341
        return $this->destroyVars($var);
342
    }
343
344
    /**
345
     * Assign values to multiple variables in a batch
346
     *
347
     * Meant for a CGI context:
348
     * - prefixed CGI args are considered save
349
     * - avoids polluting of namespace with CGI args
350
     *
351
     * @access private
352
     * @param array  $var_arr associative array of values to assign
353
     * @param string $pref    prefix (only keys starting with the prefix will be set)
354
     * @param bool   $not_gpc
355
     */
356
    public function setFormVars($var_arr = null, $pref = 'xo_', $not_gpc = false)
357
    {
358
        $len = strlen($pref);
359
        foreach ($var_arr as $key => $value) {
360
            if ($pref == substr($key, 0, $len)) {
361
                $this->setVar(substr($key, $len), $value, $not_gpc);
362
            }
363
        }
364
    }
365
366
    /**
367
     * returns all variables for the object
368
     *
369
     * @access public
370
     * @return array associative array of key->value pairs
371
     */
372
    public function &getVars()
373
    {
374
        return $this->vars;
375
    }
376
377
    /**
378
     * Returns the values of the specified variables
379
     *
380
     * @param  mixed  $keys     An array containing the names of the keys to retrieve, or null to get all of them
381
     * @param  string $format   Format to use (see getVar)
382
     * @param  int    $maxDepth Maximum level of recursion to use if some vars are objects themselves
383
     * @return array  associative array of key->value pairs
384
     */
385
    public function getValues($keys = null, $format = 's', $maxDepth = 1)
386
    {
387
        if (!isset($keys)) {
388
            $keys = array_keys($this->vars);
389
        }
390
        $vars = array();
391
        foreach ($keys as $key) {
392
            if (isset($this->vars[$key])) {
393
                if (is_object($this->vars[$key]) && is_a($this->vars[$key], 'XoopsObject')) {
394
                    if ($maxDepth) {
395
                        $vars[$key] = $this->vars[$key]->getValues(null, $format, $maxDepth - 1);
396
                    }
397
                } else {
398
                    $vars[$key] = $this->getVar($key, $format);
399
                }
400
            }
401
        }
402
403
        return $vars;
404
    }
405
406
    /**
407
     * returns a specific variable for the object in a proper format
408
     *
409
     * YOU SHOULD NOT USE ANY OF THE UNICODE TYPES, THEY WILL BE REMOVED
410
     *
411
     * @access public
412
     * @param  string $key    key of the object's variable to be returned
413
     * @param  string $format format to use for the output
414
     * @return mixed  formatted value of the variable
415
     */
416
    public function getVar($key, $format = 's')
417
    {
418
        $ret = null;
419
        if (!isset($this->vars[$key])) {
420
            return $ret;
421
        }
422
        $ret = $this->vars[$key]['value'];
423
        $ts  = MyTextSanitizer::getInstance();
424
        switch ($this->vars[$key]['data_type']) {
425
            case XOBJ_DTYPE_INT:
426
                $ret = (int) $ret;
427
                break;
428
            case XOBJ_DTYPE_UNICODE_TXTBOX:
429
            case XOBJ_DTYPE_TXTBOX:
430
                switch (strtolower($format)) {
431
                    case 's':
432
                    case 'show':
433
                    case 'e':
434
                    case 'edit':
435
                        return $ts->htmlSpecialChars($ret);
436
                        break 1;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
437
                    case 'p':
438
                    case 'preview':
439
                    case 'f':
440
                    case 'formpreview':
441
                        return $ts->htmlSpecialChars($ts->stripSlashesGPC($ret));
442
                        break 1;
443
                    case 'n':
444
                    case 'none':
445
                    default:
446
                        break 1;
447
                }
448
                break;
449
            case XOBJ_DTYPE_UNICODE_TXTAREA:
450
            case XOBJ_DTYPE_TXTAREA:
451
                switch (strtolower($format)) {
452
                    case 's':
453
                    case 'show':
454
                        $html   = !empty($this->vars['dohtml']['value']) ? 1 : 0;
455
                        $xcode  = (!isset($this->vars['doxcode']['value']) || $this->vars['doxcode']['value'] == 1) ? 1 : 0;
456
                        $smiley = (!isset($this->vars['dosmiley']['value']) || $this->vars['dosmiley']['value'] == 1) ? 1 : 0;
457
                        $image  = (!isset($this->vars['doimage']['value']) || $this->vars['doimage']['value'] == 1) ? 1 : 0;
458
                        $br     = (!isset($this->vars['dobr']['value']) || $this->vars['dobr']['value'] == 1) ? 1 : 0;
459
460
                        return $ts->displayTarea($ret, $html, $smiley, $xcode, $image, $br);
461
                        break 1;
462
                    case 'e':
463
                    case 'edit':
464
                        return htmlspecialchars($ret, ENT_QUOTES);
465
                        break 1;
466
                    case 'p':
467
                    case 'preview':
468
                        $html   = !empty($this->vars['dohtml']['value']) ? 1 : 0;
469
                        $xcode  = (!isset($this->vars['doxcode']['value']) || $this->vars['doxcode']['value'] == 1) ? 1 : 0;
470
                        $smiley = (!isset($this->vars['dosmiley']['value']) || $this->vars['dosmiley']['value'] == 1) ? 1 : 0;
471
                        $image  = (!isset($this->vars['doimage']['value']) || $this->vars['doimage']['value'] == 1) ? 1 : 0;
472
                        $br     = (!isset($this->vars['dobr']['value']) || $this->vars['dobr']['value'] == 1) ? 1 : 0;
473
474
                        return $ts->previewTarea($ret, $html, $smiley, $xcode, $image, $br);
475
                        break 1;
476
                    case 'f':
477
                    case 'formpreview':
478
                        return htmlspecialchars($ts->stripSlashesGPC($ret), ENT_QUOTES);
479
                        break 1;
480
                    case 'n':
481
                    case 'none':
482
                    default:
483
                        break 1;
484
                }
485
                break;
486
            case XOBJ_DTYPE_UNICODE_ARRAY:
487
                switch (strtolower($format)) {
488
                    case 'n':
489
                    case 'none':
490
                        break 1;
491
                    default:
492
                        if (!is_array($ret)) {
493
                            if ($ret != '') {
494
                                $ret = unserialize($ret);
495
                            }
496
                            $ret = is_array($ret) ? $ret : array();
497
                            if (is_array($ret)) {
0 ignored issues
show
introduced by
The condition is_array($ret) is always true.
Loading history...
498
                                $ret = array_walk($ret, 'xoops_aw_decode');
499
                            }
500
                        }
501
502
                        return $ret;
503
                        break 1;
504
                }
505
                break;
506
            case XOBJ_DTYPE_ARRAY:
507
                switch (strtolower($format)) {
508
                    case 'n':
509
                    case 'none':
510
                        break 1;
511
                    default:
512
                        if (!is_array($ret)) {
513
                            if ($ret != '') {
514
                                $ret = unserialize($ret);
515
                            }
516
                            $ret = is_array($ret) ? $ret : array();
517
                        }
518
519
                        return $ret;
520
                        break 1;
521
                }
522
                break;
523
            case XOBJ_DTYPE_SOURCE:
524
                switch (strtolower($format)) {
525
                    case 's':
526
                    case 'show':
527
                        break 1;
528
                    case 'e':
529
                    case 'edit':
530
                        return htmlspecialchars($ret, ENT_QUOTES);
531
                        break 1;
532
                    case 'p':
533
                    case 'preview':
534
                        return $ts->stripSlashesGPC($ret);
535
                        break 1;
536
                    case 'f':
537
                    case 'formpreview':
538
                        return htmlspecialchars($ts->stripSlashesGPC($ret), ENT_QUOTES);
539
                        break 1;
540
                    case 'n':
541
                    case 'none':
542
                    default:
543
                        break 1;
544
                }
545
                break;
546
            case XOBJ_DTYPE_DATE:
547
                switch (strtolower($format)) {
548
                    case 's':
549
                    case 'show':
550
                        if (is_string($ret) && !is_numeric($ret)) {
551
                            return date(_DBDATESTRING, strtotime($ret));
552
                        } else {
553
                            return date(_DBDATESTRING, $ret);
554
                        }
555
                        break 1;
556
                    case 'e':
557
                    case 'edit':
558
                        if (is_string($ret) && !is_numeric($ret)) {
559
                            return htmlspecialchars(date(_DBDATESTRING, strtotime($ret)), ENT_QUOTES);
560
                        } else {
561
                            return htmlspecialchars(date(_DBDATESTRING, $ret), ENT_QUOTES);
562
                        }
563
                        break 1;
564
                    case 'p':
565
                    case 'preview':
566
                        if (is_string($ret) && !is_numeric($ret)) {
567
                            return $ts->stripSlashesGPC(date(_DBDATESTRING, strtotime($ret)));
568
                        } else {
569
                            return $ts->stripSlashesGPC(date(_DBDATESTRING, $ret));
570
                        }
571
                        break 1;
572
                    case 'f':
573
                    case 'formpreview':
574
                        if (is_string($ret) && !is_numeric($ret)) {
575
                            return htmlspecialchars($ts->stripSlashesGPC(date(_DBDATESTRING, strtotime($ret))), ENT_QUOTES);
576
                        } else {
577
                            return htmlspecialchars($ts->stripSlashesGPC(date(_DBDATESTRING, $ret)), ENT_QUOTES);
578
                        }
579
                        break 1;
580
                    case 'n':
581
                    case 'none':
582
                    default:
583
                        break 1;
584
                }
585
                break;
586
            case XOBJ_DTYPE_TIME:
587
                switch (strtolower($format)) {
588
                    case 's':
589
                    case 'show':
590
                        if (is_string($ret) && !is_numeric($ret)) {
591
                            return date(_DBTIMESTRING, strtotime($ret));
592
                        } else {
593
                            return date(_DBTIMESTRING, $ret);
594
                        }
595
                        break 1;
596
                    case 'e':
597
                    case 'edit':
598
                        if (is_string($ret) && !is_numeric($ret)) {
599
                            return htmlspecialchars(date(_DBTIMESTRING, strtotime($ret)), ENT_QUOTES);
600
                        } else {
601
                            return htmlspecialchars(date(_DBTIMESTRING, $ret), ENT_QUOTES);
602
                        }
603
                        break 1;
604
                    case 'p':
605
                    case 'preview':
606
                        if (is_string($ret) && !is_numeric($ret)) {
607
                            return $ts->stripSlashesGPC(date(_DBTIMESTRING, strtotime($ret)));
608
                        } else {
609
                            return $ts->stripSlashesGPC(date(_DBTIMESTRING, $ret));
610
                        }
611
                        break 1;
612
                    case 'f':
613
                    case 'formpreview':
614
                        if (is_string($ret) && !is_numeric($ret)) {
615
                            return htmlspecialchars($ts->stripSlashesGPC(date(_DBTIMESTRING, strtotime($ret))), ENT_QUOTES);
616
                        } else {
617
                            return htmlspecialchars($ts->stripSlashesGPC(date(_DBTIMESTRING, $ret)), ENT_QUOTES);
618
                        }
619
                        break 1;
620
                    case 'n':
621
                    case 'none':
622
                    default:
623
                        break 1;
624
                }
625
                break;
626
            case XOBJ_DTYPE_TIMESTAMP:
627
                switch (strtolower($format)) {
628
                    case 's':
629
                    case 'show':
630
                        if (is_string($ret) && !is_numeric($ret)) {
631
                            return date(_DBTIMESTAMPSTRING, strtotime($ret));
632
                        } else {
633
                            return date(_DBTIMESTAMPSTRING, $ret);
634
                        }
635
                        break 1;
636
                    case 'e':
637
                    case 'edit':
638
                        if (is_string($ret) && !is_numeric($ret)) {
639
                            return htmlspecialchars(date(_DBTIMESTAMPSTRING, strtotime($ret)), ENT_QUOTES);
640
                        } else {
641
                            return htmlspecialchars(date(_DBTIMESTAMPSTRING, $ret), ENT_QUOTES);
642
                        }
643
                        break 1;
644
                    case 'p':
645
                    case 'preview':
646
                        if (is_string($ret) && !is_numeric($ret)) {
647
                            return $ts->stripSlashesGPC(date(_DBTIMESTAMPSTRING, strtotime($ret)));
648
                        } else {
649
                            return $ts->stripSlashesGPC(date(_DBTIMESTAMPSTRING, $ret));
650
                        }
651
                        break 1;
652
                    case 'f':
653
                    case 'formpreview':
654
                        if (is_string($ret) && !is_numeric($ret)) {
655
                            return htmlspecialchars($ts->stripSlashesGPC(date(_DBTIMESTAMPSTRING, strtotime($ret))), ENT_QUOTES);
656
                        } else {
657
                            return htmlspecialchars($ts->stripSlashesGPC(date(_DBTIMESTAMPSTRING, $ret)), ENT_QUOTES);
658
                        }
659
                        break 1;
660
                    case 'n':
661
                    case 'none':
662
                    default:
663
                        break 1;
664
                }
665
                break;
666
            default:
667
                if ($this->vars[$key]['options'] != '' && $ret != '') {
668
                    switch (strtolower($format)) {
669
                        case 's':
670
                        case 'show':
671
                            $selected = explode('|', $ret);
672
                            $options  = explode('|', $this->vars[$key]['options']);
673
                            $i        = 1;
674
                            $ret      = array();
675
                            foreach ($options as $op) {
676
                                if (in_array($i, $selected)) {
677
                                    $ret[] = $op;
678
                                }
679
                                ++$i;
680
                            }
681
682
                            return implode(', ', $ret);
683
                        case 'e':
684
                        case 'edit':
685
                            $ret = explode('|', $ret);
686
                            break 1;
687
                        default:
688
                            break 1;
689
                    }
690
                }
691
                break;
692
        }
693
694
        return $ret;
695
    }
696
697
    /**
698
     * clean values of all variables of the object for storage.
699
     * also add slashes wherever needed
700
     *
701
     * YOU SHOULD NOT USE ANY OF THE UNICODE TYPES, THEY WILL BE REMOVED
702
     *
703
     * @return bool true if successful
704
     * @access public
705
     */
706
    public function cleanVars()
707
    {
708
        $ts              = MyTextSanitizer::getInstance();
709
        $existing_errors = $this->getErrors();
710
        $this->_errors   = array();
711
        foreach ($this->vars as $k => $v) {
712
            $cleanv = $v['value'];
713
            if (!$v['changed']) {
714
            } else {
715
                $cleanv = is_string($cleanv) ? trim($cleanv) : $cleanv;
716
                switch ($v['data_type']) {
717
                    case XOBJ_DTYPE_TIMESTAMP:
718
                        $cleanv = !is_string($cleanv) && is_numeric($cleanv) ? date(_DBTIMESTAMPSTRING, $cleanv) : date(_DBTIMESTAMPSTRING, strtotime($cleanv));
719
                        break;
720
                    case XOBJ_DTYPE_TIME:
721
                        $cleanv = !is_string($cleanv) && is_numeric($cleanv) ? date(_DBTIMESTRING, $cleanv) : date(_DBTIMESTRING, strtotime($cleanv));
722
                        break;
723
                    case XOBJ_DTYPE_DATE:
724
                        $cleanv = !is_string($cleanv) && is_numeric($cleanv) ? date(_DBDATESTRING, $cleanv) : date(_DBDATESTRING, strtotime($cleanv));
725
                        break;
726
                    case XOBJ_DTYPE_TXTBOX:
727
                        if ($v['required'] && $cleanv != '0' && $cleanv == '') {
728
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
729
                            continue 2;
730
                        }
731
                        if (isset($v['maxlength']) && strlen($cleanv) > (int)$v['maxlength']) {
732
                            $this->setErrors(sprintf(_XOBJ_ERR_SHORTERTHAN, $k, (int)$v['maxlength']));
733
                            continue 2;
734
                        }
735
                        if (!$v['not_gpc']) {
736
                            $cleanv = $ts->stripSlashesGPC($ts->censorString($cleanv));
737
                        } else {
738
                            $cleanv = $ts->censorString($cleanv);
739
                        }
740
                        break;
741
                    case XOBJ_DTYPE_TXTAREA:
742
                        if ($v['required'] && $cleanv != '0' && $cleanv == '') {
743
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
744
                            continue 2;
745
                        }
746
                        if (!$v['not_gpc']) {
747
                            $cleanv = $ts->stripSlashesGPC($ts->censorString($cleanv));
748
                        } else {
749
                            $cleanv = $ts->censorString($cleanv);
750
                        }
751
                        break;
752
                    case XOBJ_DTYPE_SOURCE:
753
                        if (!$v['not_gpc']) {
754
                            $cleanv = $ts->stripSlashesGPC($cleanv);
755
                        }
756
                        break;
757
                    case XOBJ_DTYPE_INT:
758
                        $cleanv = (int)$cleanv;
759
                        break;
760
761
                    case XOBJ_DTYPE_EMAIL:
762
                        if ($v['required'] && $cleanv == '') {
763
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
764
                            continue 2;
765
                        }
766
                        if ($cleanv != '' && !preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+([\.][a-z0-9-]+)+$/i", $cleanv)) {
767
                            $this->setErrors('Invalid Email'); //_XOBJ_ERR_INVALID_EMAIL
768
                            continue 2;
769
                        }
770
                        if (!$v['not_gpc']) {
771
                            $cleanv = $ts->stripSlashesGPC($cleanv);
772
                        }
773
                        break;
774
                    case XOBJ_DTYPE_URL:
775
                        if ($v['required'] && $cleanv == '') {
776
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
777
                            continue 2;
778
                        }
779
                        if ($cleanv != '' && !preg_match("/^http[s]*:\/\//i", $cleanv)) {
780
                            $cleanv = XOOPS_PROT . $cleanv;
781
                        }
782
                        if (!$v['not_gpc']) {
783
                            $cleanv =& $ts->stripSlashesGPC($cleanv);
784
                        }
785
                        break;
786
                    case XOBJ_DTYPE_ARRAY:
787
                        $cleanv = (array)$cleanv;
788
                        $cleanv = serialize($cleanv);
789
                        break;
790
                    case XOBJ_DTYPE_STIME:
791
                    case XOBJ_DTYPE_MTIME:
792
                    case XOBJ_DTYPE_LTIME:
793
                        $cleanv = !is_string($cleanv) ? (int)$cleanv : strtotime($cleanv);
794
                        break;
795
                    case XOBJ_DTYPE_FLOAT:
796
                        $cleanv = (float)$cleanv;
797
                        break;
798
                    case XOBJ_DTYPE_DECIMAL:
799
                        $cleanv = (float)$cleanv;
800
                        break;
801
                    case XOBJ_DTYPE_ENUM:
802
                        if (!in_array($cleanv, $v['enumeration'])) {
803
                            $this->setErrors('Invalid Enumeration');//_XOBJ_ERR_INVALID_ENUMERATION
804
                            continue 2;
805
                        }
806
                        break;
807
                    case XOBJ_DTYPE_UNICODE_TXTBOX:
808
                        if ($v['required'] && $cleanv != '0' && $cleanv == '') {
809
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
810
                            continue 2;
811
                        }
812
                        $cleanv = xoops_convert_encode($cleanv);
813
                        if (isset($v['maxlength']) && strlen($cleanv) > (int)$v['maxlength']) {
814
                            $this->setErrors(sprintf(_XOBJ_ERR_SHORTERTHAN, $k, (int)$v['maxlength']));
815
                            continue 2;
816
                        }
817
                        if (!$v['not_gpc']) {
818
                            $cleanv = $ts->stripSlashesGPC($ts->censorString($cleanv));
819
                        } else {
820
                            $cleanv = $ts->censorString($cleanv);
821
                        }
822
                        break;
823
                    case XOBJ_DTYPE_UNICODE_TXTAREA:
824
                        if ($v['required'] && $cleanv != '0' && $cleanv == '') {
825
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
826
                            continue 2;
827
                        }
828
                        $cleanv = xoops_convert_encode($cleanv);
829
                        if (!$v['not_gpc']) {
830
                            $cleanv = $ts->stripSlashesGPC($ts->censorString($cleanv));
831
                        } else {
832
                            $cleanv = $ts->censorString($cleanv);
833
                        }
834
                        break;
835
                    case XOBJ_DTYPE_UNICODE_EMAIL:
836
                        if ($v['required'] && $cleanv == '') {
837
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
838
                            continue 2;
839
                        }
840
                        if ($cleanv != '' && !preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+([\.][a-z0-9-]+)+$/i", $cleanv)) {
841
                            $this->setErrors('Invalid Email');
842
                            continue 2;
843
                        }
844
                        $cleanv = xoops_convert_encode($cleanv);
845
                        if (!$v['not_gpc']) {
846
                            $cleanv = $ts->stripSlashesGPC($cleanv);
847
                        }
848
                        break;
849
                    case XOBJ_DTYPE_UNICODE_URL:
850
                        if ($v['required'] && $cleanv == '') {
851
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
852
                            continue 2;
853
                        }
854
                        if ($cleanv != '' && !preg_match("/^http[s]*:\/\//i", $cleanv)) {
855
                            $cleanv = XOOPS_PROT . $cleanv;
856
                        }
857
                        $cleanv = xoops_convert_encode($cleanv);
858
                        if (!$v['not_gpc']) {
859
                            $cleanv =& $ts->stripSlashesGPC($cleanv);
860
                        }
861
                        break;
862
                    case XOBJ_DTYPE_UNICODE_ARRAY:
863
                        $cleanv = serialize(array_walk($cleanv, 'xoops_aw_encode'));
0 ignored issues
show
Bug introduced by
It seems like $cleanv can also be of type string; however, parameter $array of array_walk() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

863
                        $cleanv = serialize(array_walk(/** @scrutinizer ignore-type */ $cleanv, 'xoops_aw_encode'));
Loading history...
864
                        break;
865
                    default:
866
                        break;
867
868
                }
869
            }
870
            $this->cleanVars[$k] = str_replace('\\"', '"', $cleanv);
871
            unset($cleanv);
872
        }
873
        if (count($this->_errors) > 0) {
874
            $this->_errors = array_merge($existing_errors, $this->_errors);
875
876
            return false;
877
        }
878
        $this->_errors = array_merge($existing_errors, $this->_errors);
879
        $this->unsetDirty();
880
881
        return true;
882
    }
883
884
    /**
885
     * dynamically register additional filter for the object
886
     *
887
     * @param string $filtername name of the filter
888
     *
889
     * @deprecated \XoopsObject::registerFilter is deprecated since XOOPS 2.5.8 and will be removed in the next major release
890
     */
891
    public function registerFilter($filtername)
892
    {
893
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
894
        trigger_error("XoopsObject::registerFilter() is deprecated, called from {$trace[0]['file']} line {$trace[0]['line']}");
895
        $this->_filters[] = $filtername;
896
    }
897
898
    /**
899
     * load all additional filters that have been registered to the object
900
     *
901
     * @access private
902
     */
903
    public function _loadFilters()
904
    {
905
        static $loaded;
906
        if (isset($loaded)) {
907
            return null;
908
        }
909
        $loaded = 1;
910
911
        $path = empty($this->plugin_path) ? __DIR__ . '/filters' : $this->plugin_path;
912
        if (file_exists($file = $path . '/filter.php')) {
913
            include_once $file;
914
            foreach ($this->_filters as $f) {
915
                if (file_exists($file = $path . '/' . strtolower($f) . 'php')) {
916
                    include_once $file;
917
                }
918
            }
919
        }
920
    }
921
922
    /**
923
     * load all local filters for the object
924
     *
925
     * Filter distribution:
926
     * In each module folder there is a folder "filter" containing filter files with,
927
     * filename: [name_of_target_class][.][function/action_name][.php];
928
     * function name: [dirname][_][name_of_target_class][_][function/action_name];
929
     * parameter: the target object
930
     *
931
     * @param string $method function or action name
932
     *
933
     * @deprecated \XoopsObject::loadFilters is deprecated since XOOPS 2.5.8 and will be removed in the next major release
934
     */
935
    public function loadFilters($method)
936
    {
937
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
938
        trigger_error("XoopsObject::loadFilters() is deprecated, called from {$trace[0]['file']} line {$trace[0]['line']}");
939
940
        $this->_loadFilters();
941
942
        xoops_load('XoopsCache');
943
        $class = get_class($this);
944
        if (!$modules_active = XoopsCache::read('system_modules_active')) {
945
            /* @var $module_handler XoopsModuleHandler */
946
            $module_handler = xoops_getHandler('module');
947
            $modules_obj    = $module_handler->getObjects(new Criteria('isactive', 1));
948
            $modules_active = array();
949
            foreach (array_keys($modules_obj) as $key) {
950
                $modules_active[] = $modules_obj[$key]->getVar('dirname');
951
            }
952
            unset($modules_obj);
953
            XoopsCache::write('system_modules_active', $modules_active);
954
        }
955
        foreach ($modules_active as $dirname) {
956
            if (file_exists($file = XOOPS_ROOT_PATH . '/modules/' . $dirname . '/filter/' . $class . '.' . $method . '.php')) {
957
                include_once $file;
958
                if (function_exists($class . '_' . $method)) {
959
                    call_user_func_array($dirname . '_' . $class . '_' . $method, array(&$this));
960
                }
961
            }
962
        }
963
    }
964
965
    /**
966
     * create a clone(copy) of the current object
967
     *
968
     * @access public
969
     * @return object clone
970
     */
971
    public function xoopsClone()
972
    {
973
        $class = get_class($this);
974
        $clone = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $clone is dead and can be removed.
Loading history...
975
        $clone = new $class();
976
        foreach ($this->vars as $k => $v) {
977
            $clone->assignVar($k, $v['value']);
978
        }
979
        // need this to notify the handler class that this is a newly created object
980
        $clone->setNew();
981
982
        return $clone;
983
    }
984
985
    /**
986
     * Adjust a newly cloned object
987
     */
988
    public function __clone()
989
    {
990
        // need this to notify the handler class that this is a newly created object
991
        $this->setNew();
992
    }
993
994
    /**
995
     * add an error
996
     *
997
     * @param $err_str
998
     * @internal param string $value error to add
999
     * @access   public
1000
     */
1001
    public function setErrors($err_str)
1002
    {
1003
        if (is_array($err_str)) {
1004
            $this->_errors = array_merge($this->_errors, $err_str);
1005
        } else {
1006
            $this->_errors[] = trim($err_str);
1007
        }
1008
    }
1009
1010
    /**
1011
     * return the errors for this object as an array
1012
     *
1013
     * @return array an array of errors
1014
     * @access public
1015
     */
1016
    public function getErrors()
1017
    {
1018
        return $this->_errors;
1019
    }
1020
1021
    /**
1022
     * return the errors for this object as html
1023
     *
1024
     * @return string html listing the errors
1025
     * @access public
1026
     */
1027
    public function getHtmlErrors()
1028
    {
1029
        $ret = '<h4>Errors</h4>';
1030
        if (!empty($this->_errors)) {
1031
            foreach ($this->_errors as $error) {
1032
                $ret .= $error . '<br>';
1033
            }
1034
        } else {
1035
            $ret .= 'None<br>';
1036
        }
1037
1038
        return $ret;
1039
    }
1040
1041
    /**
1042
     * Returns an array representation of the object
1043
     *
1044
     * Deprecated, use getValues() directly
1045
     *
1046
     * @return array
1047
     */
1048
    public function toArray()
1049
    {
1050
        return $this->getValues();
1051
    }
1052
}
1053
1054
/**
1055
 * XOOPS object handler class.
1056
 * This class is an abstract class of handler classes that are responsible for providing
1057
 * data access mechanisms to the data source of its corresponding data objects
1058
 *
1059
 * @package             kernel
1060
 * @abstract
1061
 * @author              Kazumi Ono <[email protected]>
1062
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
1063
 */
1064
class XoopsObjectHandler
1065
{
1066
    /**
1067
     * XoopsDatabase holds referenced to {@link XoopsDatabase} class object
1068
     *
1069
     * @var XoopsDatabase
1070
     */
1071
    public $db;
1072
1073
    /**
1074
     * called from child classes only
1075
     *
1076
     * @param XoopsDatabase $db reference to the {@link XoopsDatabase} object
1077
     * @access protected
1078
     */
1079
    public function __construct(XoopsDatabase $db)
1080
    {
1081
        /* @var $db XoopsMySQLDatabase  */
1082
        $this->db = $db;
1083
    }
1084
1085
    /**
1086
     * PHP 4 style constructor compatibility shim
1087
     *
1088
     * @param XoopsDatabase $db database object
1089
     * @deprecated all callers should be using parent::__construct()
1090
     */
1091
    public function XoopsObjectHandler($db)
1092
    {
1093
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
1094
        trigger_error("Should call parent::__construct in {$trace[0]['file']} line {$trace[0]['line']},");
1095
        self::__construct($db);
0 ignored issues
show
Bug Best Practice introduced by
The method XoopsObjectHandler::__construct() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1095
        self::/** @scrutinizer ignore-call */ 
1096
              __construct($db);
Loading history...
1096
    }
1097
1098
    /**
1099
     * creates a new object
1100
     *
1101
     * @abstract
1102
     * @return XoopsObject
1103
     */
1104
    public function create()
1105
    {
1106
    }
1107
1108
    /**
1109
     * gets a value object
1110
     *
1111
     * @param int $int_id
1112
     * @abstract
1113
     * @return XoopsObject
1114
     */
1115
    public function get($int_id)
1116
    {
1117
    }
1118
1119
    /**
1120
     * insert/update object
1121
     *
1122
     * @param XoopsObject $object
1123
     * @abstract
1124
     */
1125
    public function insert(XoopsObject $object)
1126
    {
1127
    }
1128
1129
    /**
1130
     * delete object from database
1131
     *
1132
     * @param XoopsObject $object
1133
     * @abstract
1134
     */
1135
    public function delete(XoopsObject $object)
1136
    {
1137
    }
1138
}
1139
1140
/**
1141
 * Persistable Object Handler class.
1142
 *
1143
 * @author              Taiwen Jiang <[email protected]>
1144
 * @author              Jan Keller Pedersen <[email protected]>
1145
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
1146
 * @package             Kernel
1147
 */
1148
class XoopsPersistableObjectHandler extends XoopsObjectHandler
1149
{
1150
    /**
1151
     * holds reference to custom extended object handler
1152
     *
1153
     * var object
1154
     *
1155
     * @access private
1156
     */
1157
    /**
1158
     * static protected
1159
     */
1160
    public $handler;
1161
1162
    /**
1163
     * holds reference to predefined extended object handlers: read, stats, joint, write, sync
1164
     *
1165
     * The handlers hold methods for different purposes, which could be all put together inside of current class.
1166
     * However, load codes only if they are necessary, thus they are now split out.
1167
     *
1168
     * var array of objects
1169
     *
1170
     * @access private
1171
     */
1172
    /**
1173
     * static protected
1174
     */
1175
    public $handlers = array('read' => null, 'stats' => null, 'joint' => null, 'write' => null, 'sync' => null);
1176
1177
    /**
1178
     * Information about the class, the handler is managing
1179
     *
1180
     * @var string
1181
     */
1182
    public $table;
1183
1184
    /**
1185
     * @var string
1186
     */
1187
    public $keyName;
1188
1189
    /**
1190
     * @var string
1191
     */
1192
    public $className;
1193
1194
    /**
1195
     * @var string
1196
     */
1197
    public $identifierName;
1198
1199
    /**
1200
     * @var string
1201
     */
1202
    public $field_link;
1203
1204
    /**
1205
     * @var string
1206
     */
1207
    public $field_object;
1208
1209
    /**
1210
     * Constructor
1211
     *
1212
     * @param null|XoopsDatabase $db             database connection
1213
     * @param string             $table          Name of database table
1214
     * @param string             $className      Name of the XoopsObject class this handler manages
1215
     * @param string             $keyName        Name of the property holding the key
1216
     * @param string             $identifierName Name of the property holding an identifier
1217
     *                                            name (title, name ...), used on getList()
1218
     */
1219
    public function __construct(XoopsDatabase $db = null, $table = '', $className = '', $keyName = '', $identifierName = '')
1220
    {
1221
        $db    = XoopsDatabaseFactory::getDatabaseConnection();
1222
        $table = $db->prefix($table);
1223
        parent::__construct($db);
1224
        $this->table     = $table;
1225
        $this->keyName   = $keyName;
1226
        $this->className = $className;
1227
        if ($identifierName) {
1228
            $this->identifierName = $identifierName;
1229
        }
1230
    }
1231
1232
    /**
1233
     * PHP 4 style constructor compatibility shim
1234
     *
1235
     * @param null|XoopsDatabase $db             database connection
1236
     * @param string             $table          Name of database table
1237
     * @param string             $className      Name of the XoopsObject class this handler manages
1238
     * @param string             $keyName        Name of the property holding the key
1239
     * @param string             $identifierName Name of the property holding an identifier
1240
     *                                            name (title, name ...), used on getList()
1241
     *
1242
     * @deprecated all callers should be using parent::__construct()
1243
     */
1244
    public function XoopsPersistableObjectHandler(XoopsDatabase $db = null, $table = '', $className = '', $keyName = '', $identifierName = '')
1245
    {
1246
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
1247
        trigger_error("Should call parent::__construct in {$trace[0]['file']} line {$trace[0]['line']},");
1248
        self::__construct($db, $table, $className, $keyName, $identifierName);
0 ignored issues
show
Bug Best Practice introduced by
The method XoopsPersistableObjectHandler::__construct() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1248
        self::/** @scrutinizer ignore-call */ 
1249
              __construct($db, $table, $className, $keyName, $identifierName);
Loading history...
1249
    }
1250
1251
    /**
1252
     * Set custom handler
1253
     *
1254
     * @access   protected
1255
     * @param null|string   $handler
1256
     * @param null   $args
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $args is correct as it would always require null to be passed?
Loading history...
1257
     * @param string $path path to class
1258
     * @internal param object $handler
1259
     * @internal param mixed  $args
1260
     * @return object of handler
1261
     */
1262
    public function setHandler($handler = null, $args = null, $path = null)
1263
    {
1264
        $this->handler = null;
1265
        if (is_object($handler)) {
1266
            $this->handler = $handler;
1267
        } elseif (is_string($handler)) {
1268
            xoops_load('XoopsModelFactory');
1269
            $this->handler = XoopsModelFactory::loadHandler($this, $handler, $args);
1270
        }
1271
1272
        return $this->handler;
1273
    }
1274
1275
    /**
1276
     * Load predefined handler
1277
     *
1278
     * @access protected
1279
     * @param  string $name handler name
1280
     * @param  mixed  $args args
1281
     * @return XoopsModelAbstract of handler {@link XoopsModelAbstract}
1282
     */
1283
    public function loadHandler($name, $args = null)
1284
    {
1285
        static $handlers;
1286
        if (!isset($handlers[$name])) {
1287
            xoops_load('XoopsModelFactory');
1288
            $handlers[$name] = XoopsModelFactory::loadHandler($this, $name, $args);
1289
        } else {
1290
            $handlers[$name]->setHandler($this);
1291
            $handlers[$name]->setVars($args);
1292
        }
1293
1294
        return $handlers[$name];
1295
1296
        /**
1297
         * // Following code just kept as placeholder for PHP5
1298
         * if (!isset(self::$handlers[$name])) {
1299
         * self::$handlers[$name] = XoopsModelFactory::loadHandler($this, $name, $args);
1300
         * } else {
1301
         * self::$handlers[$name]->setHandler($this);
1302
         * self::$handlers[$name]->setVars($args);
1303
         * }
1304
         *
1305
         * return self::$handlers[$name];
1306
         */
1307
    }
1308
1309
    /**
1310
     * Magic method for overloading of delegation
1311
     *
1312
     * To be enabled in XOOPS 3.0 with PHP 5
1313
     *
1314
     * @access protected
1315
     * @param  string $name method name
1316
     * @param  array  $args arguments
1317
     * @return mixed
1318
     */
1319
    public function __call($name, $args)
1320
    {
1321
        if (is_object($this->handler) && is_callable(array($this->handler, $name))) {
1322
            return call_user_func_array(array($this->handler, $name), $args);
1323
        }
1324
        foreach (array_keys($this->handlers) as $_handler) {
1325
            $handler = $this->loadHandler($_handler);
1326
            if (is_callable(array($handler, $name))) {
1327
                return call_user_func_array(array($handler, $name), $args);
1328
            }
1329
        }
1330
1331
        return null;
1332
    }
1333
1334
    /**
1335
     * *#@+
1336
     * Methods of native handler {@link XoopsPersistableObjectHandler}
1337
     */
1338
    /**
1339
     * create a new object
1340
     *
1341
     * @param  bool $isNew Flag the new objects as new
1342
     * @return XoopsObject {@link XoopsObject}
1343
     */
1344
    public function create($isNew = true)
1345
    {
1346
        $obj = new $this->className();
1347
        if ($isNew === true) {
1348
            $obj->setNew();
1349
        }
1350
1351
        return $obj;
1352
    }
1353
1354
    /**
1355
     * Load a {@link XoopsObject} object from the database
1356
     *
1357
     * @access protected
1358
     * @param  mixed $id     ID
1359
     * @param  array $fields fields to fetch
1360
     * @return XoopsObject {@link XoopsObject}
1361
     */
1362
    public function get($id = null, $fields = null)
1363
    {
1364
        $object = null;
1365
        if (empty($id)) {
1366
            $object = $this->create();
1367
1368
            return $object;
1369
        }
1370
        if (is_array($fields) && count($fields) > 0) {
1371
            $select = implode(',', $fields);
1372
            if (!in_array($this->keyName, $fields)) {
1373
                $select .= ', ' . $this->keyName;
1374
            }
1375
        } else {
1376
            $select = '*';
1377
        }
1378
        $sql = sprintf('SELECT %s FROM %s WHERE %s = %s', $select, $this->table, $this->keyName, $this->db->quote($id));
0 ignored issues
show
Bug introduced by
The method quote() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1378
        $sql = sprintf('SELECT %s FROM %s WHERE %s = %s', $select, $this->table, $this->keyName, $this->db->/** @scrutinizer ignore-call */ quote($id));
Loading history...
1379
        //$sql = "SELECT {$select} FROM {$this->table} WHERE {$this->keyName} = " . $this->db->quote($id);
1380
        if (!$result = $this->db->query($sql)) {
0 ignored issues
show
Bug introduced by
The method query() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1380
        if (!$result = $this->db->/** @scrutinizer ignore-call */ query($sql)) {
Loading history...
1381
            return $object;
1382
        }
1383
        if (!$this->db->getRowsNum($result)) {
0 ignored issues
show
Bug introduced by
The method getRowsNum() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1383
        if (!$this->db->/** @scrutinizer ignore-call */ getRowsNum($result)) {
Loading history...
1384
            return $object;
1385
        }
1386
        $object = $this->create(false);
1387
        $object->assignVars($this->db->fetchArray($result));
0 ignored issues
show
Bug introduced by
The method fetchArray() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1387
        $object->assignVars($this->db->/** @scrutinizer ignore-call */ fetchArray($result));
Loading history...
1388
1389
        return $object;
1390
    }
1391
    /**
1392
     * *#@-
1393
     */
1394
1395
    /**
1396
     * *#@+
1397
     * Methods of write handler {@link XoopsObjectWrite}
1398
     */
1399
    /**
1400
     * insert an object into the database
1401
     *
1402
     * @param  XoopsObject $object {@link XoopsObject} reference to object
1403
     * @param  bool        $force  flag to force the query execution despite security settings
1404
     * @return mixed       object ID
1405
     */
1406
    public function insert(XoopsObject $object, $force = true)
1407
    {
1408
        $handler = $this->loadHandler('write');
1409
1410
        return $handler->insert($object, $force);
0 ignored issues
show
Bug introduced by
The method insert() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelWrite. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1410
        return $handler->/** @scrutinizer ignore-call */ insert($object, $force);
Loading history...
1411
    }
1412
1413
    /**
1414
     * delete an object from the database
1415
     *
1416
     * @param  XoopsObject $object {@link XoopsObject} reference to the object to delete
1417
     * @param  bool        $force
1418
     * @return bool        FALSE if failed.
1419
     */
1420
    public function delete(XoopsObject $object, $force = false)
1421
    {
1422
        $handler = $this->loadHandler('write');
1423
1424
        return $handler->delete($object, $force);
0 ignored issues
show
Bug introduced by
The method delete() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelWrite. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1424
        return $handler->/** @scrutinizer ignore-call */ delete($object, $force);
Loading history...
1425
    }
1426
1427
    /**
1428
     * delete all objects matching the conditions
1429
     *
1430
     * @param  CriteriaElement $criteria {@link CriteriaElement} with conditions to meet
1431
     * @param  bool            $force    force to delete
1432
     * @param  bool            $asObject delete in object way: instantiate all objects and delete one by one
1433
     * @return bool
1434
     */
1435
    public function deleteAll(CriteriaElement $criteria = null, $force = true, $asObject = false)
1436
    {
1437
        $handler = $this->loadHandler('write');
1438
1439
        return $handler->deleteAll($criteria, $force, $asObject);
0 ignored issues
show
Bug introduced by
The method deleteAll() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelWrite. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1439
        return $handler->/** @scrutinizer ignore-call */ deleteAll($criteria, $force, $asObject);
Loading history...
1440
    }
1441
1442
    /**
1443
     * Change a field for objects with a certain criteria
1444
     *
1445
     * @param  string          $fieldname  Name of the field
1446
     * @param  mixed           $fieldvalue Value to write
1447
     * @param  CriteriaElement $criteria   {@link CriteriaElement}
1448
     * @param  bool            $force      force to query
1449
     * @return bool
1450
     */
1451
    public function updateAll($fieldname, $fieldvalue, CriteriaElement $criteria = null, $force = false)
1452
    {
1453
        $handler = $this->loadHandler('write');
1454
1455
        return $handler->updateAll($fieldname, $fieldvalue, $criteria, $force);
0 ignored issues
show
Bug introduced by
The method updateAll() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelWrite. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1455
        return $handler->/** @scrutinizer ignore-call */ updateAll($fieldname, $fieldvalue, $criteria, $force);
Loading history...
1456
    }
1457
    /**
1458
     * *#@-
1459
     */
1460
1461
    /**
1462
     * *#@+
1463
     * Methods of read handler {@link XoopsObjectRead}
1464
     */
1465
    /**
1466
     * Retrieve objects from the database
1467
     *
1468
     * @param  CriteriaElement $criteria  {@link CriteriaElement} conditions to be met
1469
     * @param  bool            $id_as_key use the ID as key for the array
1470
     * @param  bool            $as_object return an array of objects
1471
     * @return array
1472
     */
1473
    public function &getObjects(CriteriaElement $criteria = null, $id_as_key = false, $as_object = true)
1474
    {
1475
        $handler = $this->loadHandler('read');
1476
        $ret     = $handler->getObjects($criteria, $id_as_key, $as_object);
0 ignored issues
show
Bug introduced by
The method getObjects() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelRead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1476
        /** @scrutinizer ignore-call */ 
1477
        $ret     = $handler->getObjects($criteria, $id_as_key, $as_object);
Loading history...
1477
1478
        return $ret;
1479
    }
1480
1481
    /**
1482
     * get all objects matching a condition
1483
     *
1484
     * @param  CriteriaElement $criteria  {@link CriteriaElement} to match
1485
     * @param  array           $fields    variables to fetch
1486
     * @param  bool            $asObject  flag indicating as object, otherwise as array
1487
     * @param  bool            $id_as_key use the ID as key for the array
1488
     * @return array           of objects/array {@link XoopsObject}
1489
     */
1490
    public function &getAll(CriteriaElement $criteria = null, $fields = null, $asObject = true, $id_as_key = true)
1491
    {
1492
        $handler = $this->loadHandler('read');
1493
        $ret     = $handler->getAll($criteria, $fields, $asObject, $id_as_key);
0 ignored issues
show
Bug introduced by
The method getAll() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelRead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1493
        /** @scrutinizer ignore-call */ 
1494
        $ret     = $handler->getAll($criteria, $fields, $asObject, $id_as_key);
Loading history...
1494
1495
        return $ret;
1496
    }
1497
1498
    /**
1499
     * Retrieve a list of objects data
1500
     *
1501
     * @param  CriteriaElement $criteria {@link CriteriaElement} conditions to be met
1502
     * @param  int             $limit    Max number of objects to fetch
1503
     * @param  int             $start    Which record to start at
1504
     * @return array
1505
     */
1506
    public function getList(CriteriaElement $criteria = null, $limit = 0, $start = 0)
1507
    {
1508
        $handler = $this->loadHandler('read');
1509
        $ret     = $handler->getList($criteria, $limit, $start);
0 ignored issues
show
Bug introduced by
The method getList() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelRead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1509
        /** @scrutinizer ignore-call */ 
1510
        $ret     = $handler->getList($criteria, $limit, $start);
Loading history...
1510
1511
        return $ret;
1512
    }
1513
1514
    /**
1515
     * get IDs of objects matching a condition
1516
     *
1517
     * @param  CriteriaElement $criteria {@link CriteriaElement} to match
1518
     * @return array           of object IDs
1519
     */
1520
    public function &getIds(CriteriaElement $criteria = null)
1521
    {
1522
        $handler = $this->loadHandler('read');
1523
        $ret     = $handler->getIds($criteria);
0 ignored issues
show
Bug introduced by
The method getIds() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelRead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1523
        /** @scrutinizer ignore-call */ 
1524
        $ret     = $handler->getIds($criteria);
Loading history...
1524
1525
        return $ret;
1526
    }
1527
1528
    /**
1529
     * get a limited list of objects matching a condition
1530
     *
1531
     * {@link CriteriaCompo}
1532
     *
1533
     * @param  int             $limit    Max number of objects to fetch
1534
     * @param  int             $start    Which record to start at
1535
     * @param  CriteriaElement $criteria {@link CriteriaElement} to match
1536
     * @param  array           $fields   variables to fetch
1537
     * @param  bool            $asObject flag indicating as object, otherwise as array
1538
     * @return array           of objects     {@link XoopsObject}
1539
     */
1540
    public function &getByLimit($limit = 0, $start = 0, CriteriaElement $criteria = null, $fields = null, $asObject = true)
1541
    {
1542
        $handler = $this->loadHandler('read');
1543
        $ret     = $handler->getByLimit($limit, $start, $criteria, $fields, $asObject);
0 ignored issues
show
Bug introduced by
The method getByLimit() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelRead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1543
        /** @scrutinizer ignore-call */ 
1544
        $ret     = $handler->getByLimit($limit, $start, $criteria, $fields, $asObject);
Loading history...
1544
1545
        return $ret;
1546
    }
1547
    /**
1548
     * *#@-
1549
     */
1550
1551
    /**
1552
     * *#@+
1553
     * Methods of stats handler {@link XoopsObjectStats}
1554
     */
1555
    /**
1556
     * count objects matching a condition
1557
     *
1558
     * @param  CriteriaElement $criteria {@link CriteriaElement} to match
1559
     * @return int             count of objects
1560
     */
1561
    public function getCount(CriteriaElement $criteria = null)
1562
    {
1563
        $handler = $this->loadHandler('stats');
1564
1565
        return $handler->getCount($criteria);
0 ignored issues
show
Bug introduced by
The method getCount() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelStats. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1565
        return $handler->/** @scrutinizer ignore-call */ getCount($criteria);
Loading history...
1566
    }
1567
1568
    /**
1569
     * Get counts of objects matching a condition
1570
     *
1571
     * @param  CriteriaElement $criteria {@link CriteriaElement} to match
1572
     * @return array           of counts
1573
     */
1574
    public function getCounts(CriteriaElement $criteria = null)
1575
    {
1576
        $handler = $this->loadHandler('stats');
1577
1578
        return $handler->getCounts($criteria);
0 ignored issues
show
Bug introduced by
The method getCounts() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelStats. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1578
        return $handler->/** @scrutinizer ignore-call */ getCounts($criteria);
Loading history...
1579
    }
1580
    /**
1581
     * *#@-
1582
     */
1583
1584
    /**
1585
     * *#@+
1586
     * Methods of joint handler {@link XoopsObjectJoint}
1587
     */
1588
    /**
1589
     * get a list of objects matching a condition joint with another related object
1590
     *
1591
     * @param  CriteriaElement $criteria     {@link CriteriaElement} to match
1592
     * @param  array           $fields       variables to fetch
1593
     * @param  bool            $asObject     flag indicating as object, otherwise as array
1594
     * @param  string          $field_link   field of linked object for JOIN
1595
     * @param  string          $field_object field of current object for JOIN
1596
     * @return array           of objects {@link XoopsObject}
1597
     */
1598
    public function &getByLink(CriteriaElement $criteria = null, $fields = null, $asObject = true, $field_link = null, $field_object = null)
1599
    {
1600
        $handler = $this->loadHandler('joint');
1601
        $ret     = $handler->getByLink($criteria, $fields, $asObject, $field_link, $field_object);
0 ignored issues
show
Bug introduced by
The method getByLink() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelJoint. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1601
        /** @scrutinizer ignore-call */ 
1602
        $ret     = $handler->getByLink($criteria, $fields, $asObject, $field_link, $field_object);
Loading history...
1602
1603
        return $ret;
1604
    }
1605
1606
    /**
1607
     * Count of objects matching a condition
1608
     *
1609
     * @param  CriteriaElement $criteria {@link CriteriaElement} to match
1610
     * @return int             count of objects
1611
     */
1612
    public function getCountByLink(CriteriaElement $criteria = null)
1613
    {
1614
        $handler = $this->loadHandler('joint');
1615
        $ret     = $handler->getCountByLink($criteria);
0 ignored issues
show
Bug introduced by
The method getCountByLink() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelJoint. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1615
        /** @scrutinizer ignore-call */ 
1616
        $ret     = $handler->getCountByLink($criteria);
Loading history...
1616
1617
        return $ret;
1618
    }
1619
1620
    /**
1621
     * array of count of objects matching a condition of, groupby linked object keyname
1622
     *
1623
     * @param  CriteriaElement $criteria {@link CriteriaElement} to match
1624
     * @return int             count of objects
1625
     */
1626
    public function getCountsByLink(CriteriaElement $criteria = null)
1627
    {
1628
        $handler = $this->loadHandler('joint');
1629
        $ret     = $handler->getCountsByLink($criteria);
0 ignored issues
show
Bug introduced by
The method getCountsByLink() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelJoint. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1629
        /** @scrutinizer ignore-call */ 
1630
        $ret     = $handler->getCountsByLink($criteria);
Loading history...
1630
1631
        return $ret;
1632
    }
1633
1634
    /**
1635
     * update objects matching a condition against linked objects
1636
     *
1637
     * @param  array           $data     array of key => value
1638
     * @param  CriteriaElement $criteria {@link CriteriaElement} to match
1639
     * @return int             count of objects
1640
     */
1641
    public function updateByLink($data, CriteriaElement $criteria = null)
1642
    {
1643
        $handler = $this->loadHandler('joint');
1644
        $ret     = $handler->updateByLink($data, $criteria);
0 ignored issues
show
Bug introduced by
The method updateByLink() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelJoint. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1644
        /** @scrutinizer ignore-call */ 
1645
        $ret     = $handler->updateByLink($data, $criteria);
Loading history...
1645
1646
        return $ret;
1647
    }
1648
1649
    /**
1650
     * Delete objects matching a condition against linked objects
1651
     *
1652
     * @param  CriteriaElement $criteria {@link CriteriaElement} to match
1653
     * @return int             count of objects
1654
     */
1655
    public function deleteByLink(CriteriaElement $criteria = null)
1656
    {
1657
        $handler = $this->loadHandler('joint');
1658
        $ret     = $handler->deleteByLink($criteria);
0 ignored issues
show
Bug introduced by
The method deleteByLink() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelJoint. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1658
        /** @scrutinizer ignore-call */ 
1659
        $ret     = $handler->deleteByLink($criteria);
Loading history...
1659
1660
        return $ret;
1661
    }
1662
    /**
1663
     * *#@-
1664
     */
1665
1666
    /**
1667
     * *#@+
1668
     * Methods of sync handler {@link XoopsObjectSync}
1669
     */
1670
    /**
1671
     * Clean orphan objects against linked objects
1672
     *
1673
     * @param  string $table_link   table of linked object for JOIN
1674
     * @param  string $field_link   field of linked object for JOIN
1675
     * @param  string $field_object field of current object for JOIN
1676
     * @return bool   true on success
1677
     */
1678
    public function cleanOrphan($table_link = '', $field_link = '', $field_object = '')
1679
    {
1680
        $handler = $this->loadHandler('sync');
1681
        $ret     = $handler->cleanOrphan($table_link, $field_link, $field_object);
0 ignored issues
show
Bug introduced by
The method cleanOrphan() does not exist on XoopsModelAbstract. It seems like you code against a sub-type of XoopsModelAbstract such as XoopsModelSync. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1681
        /** @scrutinizer ignore-call */ 
1682
        $ret     = $handler->cleanOrphan($table_link, $field_link, $field_object);
Loading history...
1682
1683
        return $ret;
1684
    }
1685
1686
    /**
1687
     * Synchronizing objects
1688
     *
1689
     * @return bool true on success
1690
     */
1691
    public function synchronization()
1692
    {
1693
        $retval = $this->cleanOrphan();
1694
1695
        return $retval;
1696
    }
1697
    /**
1698
     * *#@-
1699
     */
1700
1701
    /**#@+
1702
     * @deprecated
1703
     * @param      $result
1704
     * @param bool $id_as_key
1705
     * @param bool $as_object
1706
     * @return bool
1707
     */
1708
    public function convertResultSet($result, $id_as_key = false, $as_object = true)
1709
    {
1710
        trigger_error(__CLASS__ . '::' . __FUNCTION__ . ' is deprecated', E_USER_WARNING);
1711
1712
        return false;
1713
    }
1714
    /**#@-*/
1715
}
1716