Completed
Pull Request — master (#39)
by Richard
12:05
created

XoopsObject::setVars()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 2
eloc 3
nc 2
nop 2
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 30 and the first side effect is on line 21.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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
 * @version             $Id: object.php 13091 2015-06-16 21:08:34Z beckmi $
19
 */
20
21
defined('XOOPS_ROOT_PATH') || exit('Restricted access');
22
/**
23
 * YOU SHOULD NOT USE ANY OF THE UNICODE TYPES, THEY WILL BE REMOVED
24
 */
25
26
/**
27
 * *#@+
28
 * Xoops object datatype
29
 */
30
define('XOBJ_DTYPE_TXTBOX', 1);
31
define('XOBJ_DTYPE_TXTAREA', 2);
32
define('XOBJ_DTYPE_INT', 3);
33
define('XOBJ_DTYPE_URL', 4);
34
define('XOBJ_DTYPE_EMAIL', 5);
35
define('XOBJ_DTYPE_ARRAY', 6);
36
define('XOBJ_DTYPE_OTHER', 7);
37
define('XOBJ_DTYPE_SOURCE', 8);
38
define('XOBJ_DTYPE_STIME', 9);
39
define('XOBJ_DTYPE_MTIME', 10);
40
define('XOBJ_DTYPE_LTIME', 11);
41
define('XOBJ_DTYPE_FLOAT', 13);
42
define('XOBJ_DTYPE_DECIMAL', 14);
43
define('XOBJ_DTYPE_ENUM', 15);
44
// YOU SHOULD NEVER USE THE FOLLOWING TYPES, THEY WILL BE REMOVED
45
define('XOBJ_DTYPE_UNICODE_TXTBOX', 16);
46
define('XOBJ_DTYPE_UNICODE_TXTAREA', 17);
47
define('XOBJ_DTYPE_UNICODE_URL', 18);
48
define('XOBJ_DTYPE_UNICODE_EMAIL', 19);
49
define('XOBJ_DTYPE_UNICODE_ARRAY', 20);
50
define('XOBJ_DTYPE_UNICODE_OTHER', 21);
51
// Addition for 2.5.5
52
define('XOBJ_DTYPE_DATE', 22);
53
define('XOBJ_DTYPE_TIME', 23);
54
define('XOBJ_DTYPE_TIMESTAMP', 24);
55
56
/**
57
 * Base class for all objects in the Xoops kernel (and beyond)
58
 */
59
class XoopsObject
60
{
61
    /**
62
     * holds all variables(properties) of an object
63
     *
64
     * @var array
65
     * @access protected
66
     */
67
    public $vars = array();
68
69
    /**
70
     * variables cleaned for store in DB
71
     *
72
     * @var array
73
     * @access protected
74
     */
75
    public $cleanVars = array();
76
77
    /**
78
     * is it a newly created object?
79
     *
80
     * @var bool
81
     * @access private
82
     */
83
    public $_isNew = false;
84
85
    /**
86
     * has any of the values been modified?
87
     *
88
     * @var bool
89
     * @access private
90
     */
91
    public $_isDirty = false;
92
93
    /**
94
     * errors
95
     *
96
     * @var array
97
     * @access private
98
     */
99
    public $_errors = array();
100
101
    /**
102
     * additional filters registered dynamically by a child class object
103
     *
104
     * @access private
105
     */
106
    public $_filters = array();
107
108
    /**
109
     * constructor
110
     *
111
     * normally, this is called from child classes only
112
     *
113
     * @access public
114
     */
115
    public function __construct()
116
    {
117
    }
118
119
    /**
120
     * PHP 4 style constructor compatibility shim
121
     * @deprecated all callers should be using parent::__construct()
122
     */
123
    public function XoopsObject()
124
    {
125
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
126
        trigger_error("Should call parent::__construct in {$trace[0]['file']} line {$trace[0]['line']},");
127
        self::__construct();
128
    }
129
130
    /**
131
     * *#@+
132
     * used for new/clone objects
133
     *
134
     * @access public
135
     */
136
    public function setNew()
137
    {
138
        $this->_isNew = true;
139
    }
140
141
    public function unsetNew()
142
    {
143
        $this->_isNew = false;
144
    }
145
146
    /**
147
     * @return bool
148
     */
149
    public function isNew()
150
    {
151
        return $this->_isNew;
152
    }
153
154
    /**
155
     * *#@+
156
     * mark modified objects as dirty
157
     *
158
     * used for modified objects only
159
     *
160
     * @access public
161
     */
162
    public function setDirty()
163
    {
164
        $this->_isDirty = true;
165
    }
166
167
    public function unsetDirty()
168
    {
169
        $this->_isDirty = false;
170
    }
171
172
    /**
173
     * @return bool
174
     */
175
    public function isDirty()
176
    {
177
        return $this->_isDirty;
178
    }
179
180
    /**
181
     * initialize variables for the object
182
     *
183
     * YOU SHOULD NOT USE THE $enumeration PARAMETER
184
     *
185
     * @access   public
186
     *
187
     * @param string $key
188
     * @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)
189
     * @param null   $value
190
     * @param bool   $required  require html form input?
191
     * @param int    $maxlength for XOBJ_DTYPE_TXTBOX type only
192
     * @param string $options
193
     * @param string $enumerations
194
     *
195
     * @return void
196
     */
197
    public function initVar($key, $data_type, $value = null, $required = false, $maxlength = null, $options = '', $enumerations = '')
198
    {
199
        $this->vars[$key] = array(
200
            'value'       => $value,
201
            'required'    => $required,
202
            'data_type'   => $data_type,
203
            'maxlength'   => $maxlength,
204
            'changed'     => false,
205
            'options'     => $options,
206
            'enumeration' => $enumerations);
207
    }
208
209
    /**
210
     * assign a value to a variable
211
     *
212
     * @access public
213
     * @param string $key   name of the variable to assign
214
     * @param mixed  $value value to assign
215
     */
216
    public function assignVar($key, $value)
217
    {
218
        if (isset($key) && isset($this->vars[$key])) {
219
            switch ($this->vars[$key]['data_type']) {
220
                case XOBJ_DTYPE_UNICODE_ARRAY:
221
                    if (is_array($value)) {
222
                        $this->vars[$key]['value'] =& array_walk($value, "xoops_aw_decode");
223
                    } else {
224
                        $this->vars[$key]['value'] =& xoops_convert_decode($value);
225
                    }
226
                    break;
227
                case XOBJ_DTYPE_UNICODE_URL:
228
                case XOBJ_DTYPE_UNICODE_EMAIL:
229
                case XOBJ_DTYPE_UNICODE_OTHER:
230
                case XOBJ_DTYPE_UNICODE_TXTBOX:
231
                case XOBJ_DTYPE_UNICODE_TXTAREA:
232
                    $this->vars[$key]['value'] =& xoops_convert_decode($value);
233
                    break;
234 View Code Duplication
                case XOBJ_DTYPE_DATE:
235
                    if (!is_string($value) && is_numeric($value)) {
236
                        $this->vars[$key]['value'] =& date(_DBDATESTRING, $value);
237
                    } else {
238
                        $this->vars[$key]['value'] =& date(_DBDATESTRING, strtotime($value));
239
                    }
240
                    break;
241 View Code Duplication
                case XOBJ_DTYPE_TIME:
242
                    if (!is_string($value) && is_numeric($value)) {
243
                        $this->vars[$key]['value'] =& date(_DBTIMESTRING, $value);
244
                    } else {
245
                        $this->vars[$key]['value'] =& date(_DBTIMESTRING, strtotime($value));
246
                    }
247
                    break;
248 View Code Duplication
                case XOBJ_DTYPE_TIMESTAMP:
249
                    if (!is_string($value) && is_numeric($value)) {
250
                        $this->vars[$key]['value'] =& date(_DBTIMESTAMPSTRING, $value);
251
                    } else {
252
                        $this->vars[$key]['value'] =& date(_DBTIMESTAMPSTRING, strtotime($value));
253
                    }
254
                    break;
255
                // YOU SHOULD NOT USE THE ABOVE TYPES, THEY WILL BE REMOVED
256
                default:
257
                    $this->vars[$key]['value'] =& $value;
258
            }
259
        }
260
    }
261
262
    /**
263
     * assign values to multiple variables in a batch
264
     *
265
     * @access   private
266
     * @param $var_arr
267
     * @internal param array $var_array associative array of values to assign
268
     */
269
    public function assignVars($var_arr)
270
    {
271
        foreach ($var_arr as $key => $value) {
272
            $this->assignVar($key, $value);
273
        }
274
    }
275
276
    /**
277
     * assign a value to a variable
278
     *
279
     * @access public
280
     * @param string $key   name of the variable to assign
281
     * @param mixed  $value value to assign
282
     * @param bool   $not_gpc
283
     */
284
    public function setVar($key, $value, $not_gpc = false)
285
    {
286
        if (!empty($key) && isset($value) && isset($this->vars[$key])) {
287
            $this->vars[$key]['value']   =& $value;
288
            $this->vars[$key]['not_gpc'] = $not_gpc;
289
            $this->vars[$key]['changed'] = true;
290
            $this->setDirty();
291
        }
292
    }
293
294
    /**
295
     * assign values to multiple variables in a batch
296
     *
297
     * @access private
298
     * @param array $var_arr associative array of values to assign
299
     * @param bool  $not_gpc
300
     */
301
    public function setVars($var_arr, $not_gpc = false)
302
    {
303
        foreach ($var_arr as $key => $value) {
304
            $this->setVar($key, $value, $not_gpc);
305
        }
306
    }
307
308
    /**
309
     * unset variable(s) for the object
310
     *
311
     * @access public
312
     *
313
     * @param mixed $var
314
     *
315
     * @return bool
316
     */
317
    public function destroyVars($var)
318
    {
319
        if (empty($var)) {
320
            return true;
321
        }
322
        $var = !is_array($var) ? array($var) : $var;
323
        foreach ($var as $key) {
324
            if (!isset($this->vars[$key])) {
325
                continue;
326
            }
327
            $this->vars[$key]['changed'] = null;
328
        }
329
330
        return true;
331
    }
332
333
    /**
334
     * @param $var
335
     * @return bool
336
     * @deprecated use destroyVars() instead,  destoryVars() will be removed in the next major release
337
     */
338
    public function destoryVars($var)
339
    {
340
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
341
        trigger_error("XoopsObject::destoryVars() is deprecated, called from {$trace[0]['file']} line {$trace[0]['line']},");
342
        return $this->destroyVars($var);
343
    }
344
345
    /**
346
     * Assign values to multiple variables in a batch
347
     *
348
     * Meant for a CGI context:
349
     * - prefixed CGI args are considered save
350
     * - avoids polluting of namespace with CGI args
351
     *
352
     * @access private
353
     * @param array  $var_arr associative array of values to assign
354
     * @param string $pref    prefix (only keys starting with the prefix will be set)
355
     * @param bool   $not_gpc
356
     */
357
    public function setFormVars($var_arr = null, $pref = 'xo_', $not_gpc = false)
358
    {
359
        $len = strlen($pref);
360
        foreach ($var_arr as $key => $value) {
0 ignored issues
show
Bug introduced by
The expression $var_arr of type array|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
361
            if ($pref == substr($key, 0, $len)) {
362
                $this->setVar(substr($key, $len), $value, $not_gpc);
363
            }
364
        }
365
    }
366
367
    /**
368
     * returns all variables for the object
369
     *
370
     * @access public
371
     * @return array associative array of key->value pairs
372
     */
373
    public function &getVars()
374
    {
375
        return $this->vars;
376
    }
377
378
    /**
379
     * Returns the values of the specified variables
380
     *
381
     * @param  mixed  $keys     An array containing the names of the keys to retrieve, or null to get all of them
382
     * @param  string $format   Format to use (see getVar)
383
     * @param  int    $maxDepth Maximum level of recursion to use if some vars are objects themselves
384
     * @return array  associative array of key->value pairs
385
     */
386
    public function getValues($keys = null, $format = 's', $maxDepth = 1)
387
    {
388
        if (!isset($keys)) {
389
            $keys = array_keys($this->vars);
390
        }
391
        $vars = array();
392
        foreach ($keys as $key) {
393
            if (isset($this->vars[$key])) {
394
                if (is_object($this->vars[$key]) && is_a($this->vars[$key], 'XoopsObject')) {
395
                    if ($maxDepth) {
396
                        $vars[$key] = $this->vars[$key]->getValues(null, $format, $maxDepth - 1);
397
                    }
398
                } else {
399
                    $vars[$key] = $this->getVar($key, $format);
400
                }
401
            }
402
        }
403
404
        return $vars;
405
    }
406
407
    /**
408
     * returns a specific variable for the object in a proper format
409
     *
410
     * YOU SHOULD NOT USE ANY OF THE UNICODE TYPES, THEY WILL BE REMOVED
411
     *
412
     * @access public
413
     * @param  string $key    key of the object's variable to be returned
414
     * @param  string $format format to use for the output
415
     * @return mixed  formatted value of the variable
416
     */
417
    public function getVar($key, $format = 's')
418
    {
419
        $ret = null;
420
        if (!isset($this->vars[$key])) {
421
            return $ret;
422
        }
423
        $ret = $this->vars[$key]['value'];
424
        $ts  = MyTextSanitizer::getInstance();
425
        switch ($this->vars[$key]['data_type']) {
426
            case XOBJ_DTYPE_UNICODE_TXTBOX:
427
            case XOBJ_DTYPE_TXTBOX:
428
                switch (strtolower($format)) {
429
                    case 's':
430
                    case 'show':
431
                    case 'e':
432
                    case 'edit':
433
                        return $ts->htmlSpecialChars($ret);
434
                        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...
435
                    case 'p':
436
                    case 'preview':
437
                    case 'f':
438
                    case 'formpreview':
439
                        return $ts->htmlSpecialChars($ts->stripSlashesGPC($ret));
440
                        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...
441
                    case 'n':
442
                    case 'none':
443
                    default:
444
                        break 1;
445
                }
446
                break;
447
            case XOBJ_DTYPE_UNICODE_TXTAREA:
448
            case XOBJ_DTYPE_TXTAREA:
449
                switch (strtolower($format)) {
450
                    case 's':
451 View Code Duplication
                    case 'show':
452
                        $html   = !empty($this->vars['dohtml']['value']) ? 1 : 0;
453
                        $xcode  = (!isset($this->vars['doxcode']['value']) || $this->vars['doxcode']['value'] == 1) ? 1 : 0;
454
                        $smiley = (!isset($this->vars['dosmiley']['value']) || $this->vars['dosmiley']['value'] == 1) ? 1 : 0;
455
                        $image  = (!isset($this->vars['doimage']['value']) || $this->vars['doimage']['value'] == 1) ? 1 : 0;
456
                        $br     = (!isset($this->vars['dobr']['value']) || $this->vars['dobr']['value'] == 1) ? 1 : 0;
457
458
                        return $ts->displayTarea($ret, $html, $smiley, $xcode, $image, $br);
459
                        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...
460
                    case 'e':
461
                    case 'edit':
462
                        return htmlspecialchars($ret, ENT_QUOTES);
463
                        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...
464
                    case 'p':
465 View Code Duplication
                    case 'preview':
466
                        $html   = !empty($this->vars['dohtml']['value']) ? 1 : 0;
467
                        $xcode  = (!isset($this->vars['doxcode']['value']) || $this->vars['doxcode']['value'] == 1) ? 1 : 0;
468
                        $smiley = (!isset($this->vars['dosmiley']['value']) || $this->vars['dosmiley']['value'] == 1) ? 1 : 0;
469
                        $image  = (!isset($this->vars['doimage']['value']) || $this->vars['doimage']['value'] == 1) ? 1 : 0;
470
                        $br     = (!isset($this->vars['dobr']['value']) || $this->vars['dobr']['value'] == 1) ? 1 : 0;
471
472
                        return $ts->previewTarea($ret, $html, $smiley, $xcode, $image, $br);
473
                        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...
474
                    case 'f':
475
                    case 'formpreview':
476
                        return htmlspecialchars($ts->stripSlashesGPC($ret), ENT_QUOTES);
477
                        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...
478
                    case 'n':
479
                    case 'none':
480
                    default:
481
                        break 1;
482
                }
483
                break;
484
            case XOBJ_DTYPE_UNICODE_ARRAY:
485
                switch (strtolower($format)) {
486
                    case 'n':
487
                    case 'none':
488
                        break 1;
489
                    default:
490
                        if (!is_array($ret)) {
491
                            if ($ret != '') {
492
                                $ret = unserialize($ret);
493
                            }
494
                            $ret = is_array($ret) ? $ret : array();
495
                            if (is_array($ret)) {
496
                                $ret = array_walk($ret, "xoops_aw_decode");
497
                            }
498
                        }
499
500
                        return $ret;
501
                        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...
502
                }
503
                break;
504
            case XOBJ_DTYPE_ARRAY:
505
                switch (strtolower($format)) {
506
                    case 'n':
507
                    case 'none':
508
                        break 1;
509
                    default:
510
                        if (!is_array($ret)) {
511
                            if ($ret != '') {
512
                                $ret = unserialize($ret);
513
                            }
514
                            $ret = is_array($ret) ? $ret : array();
515
                        }
516
517
                        return $ret;
518
                        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...
519
                }
520
                break;
521
            case XOBJ_DTYPE_SOURCE:
522
                switch (strtolower($format)) {
523
                    case 's':
524
                    case 'show':
525
                        break 1;
526
                    case 'e':
527
                    case 'edit':
528
                        return htmlspecialchars($ret, ENT_QUOTES);
529
                        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...
530
                    case 'p':
531
                    case 'preview':
532
                        return $ts->stripSlashesGPC($ret);
533
                        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...
534
                    case 'f':
535
                    case 'formpreview':
536
                        return htmlspecialchars($ts->stripSlashesGPC($ret), ENT_QUOTES);
537
                        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...
538
                    case 'n':
539
                    case 'none':
540
                    default:
541
                        break 1;
542
                }
543
                break;
544 View Code Duplication
            case XOBJ_DTYPE_DATE:
545
                switch (strtolower($format)) {
546
                    case 's':
547
                    case 'show':
548
                        if (is_string($ret) && !is_numeric($ret)) {
549
                            return date(_DBDATESTRING, strtotime($ret));
550
                        } else {
551
                            return date(_DBDATESTRING, $ret);
552
                        }
553
                        break 1;
0 ignored issues
show
Unused Code introduced by
break 1; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
554
                    case 'e':
555
                    case 'edit':
556
                        if (is_string($ret) && !is_numeric($ret)) {
557
                            return htmlspecialchars(date(_DBDATESTRING, strtotime($ret)), ENT_QUOTES);
558
                        } else {
559
                            return htmlspecialchars(date(_DBDATESTRING, $ret), ENT_QUOTES);
560
                        }
561
                        break 1;
0 ignored issues
show
Unused Code introduced by
break 1; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
562
                    case 'p':
563
                    case 'preview':
564
                        if (is_string($ret) && !is_numeric($ret)) {
565
                            return $ts->stripSlashesGPC(date(_DBDATESTRING, strtotime($ret)));
566
                        } else {
567
                            return $ts->stripSlashesGPC(date(_DBDATESTRING, $ret));
568
                        }
569
                        break 1;
0 ignored issues
show
Unused Code introduced by
break 1; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
570
                    case 'f':
571
                    case 'formpreview':
572
                        if (is_string($ret) && !is_numeric($ret)) {
573
                            return htmlspecialchars($ts->stripSlashesGPC(date(_DBDATESTRING, strtotime($ret))), ENT_QUOTES);
574
                        } else {
575
                            return htmlspecialchars($ts->stripSlashesGPC(date(_DBDATESTRING, $ret)), ENT_QUOTES);
576
                        }
577
                        break 1;
0 ignored issues
show
Unused Code introduced by
break 1; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
578
                    case 'n':
579
                    case 'none':
580
                    default:
581
                        break 1;
582
                }
583
                break;
584 View Code Duplication
            case XOBJ_DTYPE_TIME:
585
                switch (strtolower($format)) {
586
                    case 's':
587
                    case 'show':
588
                        if (is_string($ret) && !is_numeric($ret)) {
589
                            return date(_DBTIMESTRING, strtotime($ret));
590
                        } else {
591
                            return date(_DBTIMESTRING, $ret);
592
                        }
593
                        break 1;
0 ignored issues
show
Unused Code introduced by
break 1; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
594
                    case 'e':
595
                    case 'edit':
596
                        if (is_string($ret) && !is_numeric($ret)) {
597
                            return htmlspecialchars(date(_DBTIMESTRING, strtotime($ret)), ENT_QUOTES);
598
                        } else {
599
                            return htmlspecialchars(date(_DBTIMESTRING, $ret), ENT_QUOTES);
600
                        }
601
                        break 1;
0 ignored issues
show
Unused Code introduced by
break 1; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
602
                    case 'p':
603
                    case 'preview':
604
                        if (is_string($ret) && !is_numeric($ret)) {
605
                            return $ts->stripSlashesGPC(date(_DBTIMESTRING, strtotime($ret)));
606
                        } else {
607
                            return $ts->stripSlashesGPC(date(_DBTIMESTRING, $ret));
608
                        }
609
                        break 1;
0 ignored issues
show
Unused Code introduced by
break 1; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
610
                    case 'f':
611
                    case 'formpreview':
612
                        if (is_string($ret) && !is_numeric($ret)) {
613
                            return htmlspecialchars($ts->stripSlashesGPC(date(_DBTIMESTRING, strtotime($ret))), ENT_QUOTES);
614
                        } else {
615
                            return htmlspecialchars($ts->stripSlashesGPC(date(_DBTIMESTRING, $ret)), ENT_QUOTES);
616
                        }
617
                        break 1;
0 ignored issues
show
Unused Code introduced by
break 1; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
618
                    case 'n':
619
                    case 'none':
620
                    default:
621
                        break 1;
622
                }
623
                break;
624 View Code Duplication
            case XOBJ_DTYPE_TIMESTAMP:
625
                switch (strtolower($format)) {
626
                    case 's':
627
                    case 'show':
628
                        if (is_string($ret) && !is_numeric($ret)) {
629
                            return date(_DBTIMESTAMPSTRING, strtotime($ret));
630
                        } else {
631
                            return date(_DBTIMESTAMPSTRING, $ret);
632
                        }
633
                        break 1;
0 ignored issues
show
Unused Code introduced by
break 1; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
634
                    case 'e':
635
                    case 'edit':
636
                        if (is_string($ret) && !is_numeric($ret)) {
637
                            return htmlspecialchars(date(_DBTIMESTAMPSTRING, strtotime($ret)), ENT_QUOTES);
638
                        } else {
639
                            return htmlspecialchars(date(_DBTIMESTAMPSTRING, $ret), ENT_QUOTES);
640
                        }
641
                        break 1;
0 ignored issues
show
Unused Code introduced by
break 1; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
642
                    case 'p':
643
                    case 'preview':
644
                        if (is_string($ret) && !is_numeric($ret)) {
645
                            return $ts->stripSlashesGPC(date(_DBTIMESTAMPSTRING, strtotime($ret)));
646
                        } else {
647
                            return $ts->stripSlashesGPC(date(_DBTIMESTAMPSTRING, $ret));
648
                        }
649
                        break 1;
0 ignored issues
show
Unused Code introduced by
break 1; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
650
                    case 'f':
651
                    case 'formpreview':
652
                        if (is_string($ret) && !is_numeric($ret)) {
653
                            return htmlspecialchars($ts->stripSlashesGPC(date(_DBTIMESTAMPSTRING, strtotime($ret))), ENT_QUOTES);
654
                        } else {
655
                            return htmlspecialchars($ts->stripSlashesGPC(date(_DBTIMESTAMPSTRING, $ret)), ENT_QUOTES);
656
                        }
657
                        break 1;
0 ignored issues
show
Unused Code introduced by
break 1; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
658
                    case 'n':
659
                    case 'none':
660
                    default:
661
                        break 1;
662
                }
663
                break;
664
            default:
665
                if ($this->vars[$key]['options'] != '' && $ret != '') {
666
                    switch (strtolower($format)) {
667
                        case 's':
668
                        case 'show':
669
                            $selected = explode('|', $ret);
670
                            $options  = explode('|', $this->vars[$key]['options']);
671
                            $i        = 1;
672
                            $ret      = array();
673
                            foreach ($options as $op) {
674
                                if (in_array($i, $selected)) {
675
                                    $ret[] = $op;
676
                                }
677
                                ++$i;
678
                            }
679
680
                            return implode(', ', $ret);
681
                        case 'e':
682
                        case 'edit':
683
                            $ret = explode('|', $ret);
684
                            break 1;
685
                        default:
686
                            break 1;
687
                    }
688
                }
689
                break;
690
        }
691
692
        return $ret;
693
    }
694
695
    /**
696
     * clean values of all variables of the object for storage.
697
     * also add slashes wherever needed
698
     *
699
     * YOU SHOULD NOT USE ANY OF THE UNICODE TYPES, THEY WILL BE REMOVED
700
     *
701
     * @return bool true if successful
702
     * @access public
703
     */
704
    public function cleanVars()
705
    {
706
        $ts              = MyTextSanitizer::getInstance();
707
        $existing_errors = $this->getErrors();
708
        $this->_errors   = array();
709
        foreach ($this->vars as $k => $v) {
710
            $cleanv = $v['value'];
711
            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...
712
            } else {
713
                $cleanv = is_string($cleanv) ? trim($cleanv) : $cleanv;
714
                switch ($v['data_type']) {
715 View Code Duplication
                    case XOBJ_DTYPE_TIMESTAMP:
716
                        $cleanv = !is_string($cleanv) && is_numeric($cleanv) ? date(_DBTIMESTAMPSTRING, $cleanv) : date(_DBTIMESTAMPSTRING, strtotime($cleanv));
717
                        break;
718 View Code Duplication
                    case XOBJ_DTYPE_TIME:
719
                        $cleanv = !is_string($cleanv) && is_numeric($cleanv) ? date(_DBTIMESTRING, $cleanv) : date(_DBTIMESTRING, strtotime($cleanv));
720
                        break;
721 View Code Duplication
                    case XOBJ_DTYPE_DATE:
722
                        $cleanv = !is_string($cleanv) && is_numeric($cleanv) ? date(_DBDATESTRING, $cleanv) : date(_DBDATESTRING, strtotime($cleanv));
723
                        break;
724 View Code Duplication
                    case XOBJ_DTYPE_TXTBOX:
725
                        if ($v['required'] && $cleanv != '0' && $cleanv == '') {
726
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
727
                            continue 2;
728
                        }
729
                        if (isset($v['maxlength']) && strlen($cleanv) > (int)($v['maxlength'])) {
730
                            $this->setErrors(sprintf(_XOBJ_ERR_SHORTERTHAN, $k, (int)($v['maxlength'])));
731
                            continue 2;
732
                        }
733
                        if (!$v['not_gpc']) {
734
                            $cleanv = $ts->stripSlashesGPC($ts->censorString($cleanv));
0 ignored issues
show
Deprecated Code introduced by
The method MyTextSanitizer::censorString() has been deprecated.

This method has been deprecated.

Loading history...
735
                        } else {
736
                            $cleanv = $ts->censorString($cleanv);
0 ignored issues
show
Deprecated Code introduced by
The method MyTextSanitizer::censorString() has been deprecated.

This method has been deprecated.

Loading history...
737
                        }
738
                        break;
739 View Code Duplication
                    case XOBJ_DTYPE_TXTAREA:
740
                        if ($v['required'] && $cleanv != '0' && $cleanv == '') {
741
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
742
                            continue 2;
743
                        }
744
                        if (!$v['not_gpc']) {
745
                            $cleanv = $ts->stripSlashesGPC($ts->censorString($cleanv));
0 ignored issues
show
Deprecated Code introduced by
The method MyTextSanitizer::censorString() has been deprecated.

This method has been deprecated.

Loading history...
746
                        } else {
747
                            $cleanv = $ts->censorString($cleanv);
0 ignored issues
show
Deprecated Code introduced by
The method MyTextSanitizer::censorString() has been deprecated.

This method has been deprecated.

Loading history...
748
                        }
749
                        break;
750
                    case XOBJ_DTYPE_SOURCE:
751
                        if (!$v['not_gpc']) {
752
                            $cleanv = $ts->stripSlashesGPC($cleanv);
753
                        }
754
                        break;
755
                    case XOBJ_DTYPE_INT:
756
                        $cleanv = (int)($cleanv);
757
                        break;
758
759
                    case XOBJ_DTYPE_EMAIL:
760
                        if ($v['required'] && $cleanv == '') {
761
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
762
                            continue 2;
763
                        }
764
                        if ($cleanv != '' && !preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+([\.][a-z0-9-]+)+$/i", $cleanv)) {
765
                            $this->setErrors("Invalid Email"); //_XOBJ_ERR_INVALID_EMAIL
766
                            continue 2;
767
                        }
768
                        if (!$v['not_gpc']) {
769
                            $cleanv = $ts->stripSlashesGPC($cleanv);
770
                        }
771
                        break;
772 View Code Duplication
                    case XOBJ_DTYPE_URL:
773
                        if ($v['required'] && $cleanv == '') {
774
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
775
                            continue 2;
776
                        }
777
                        if ($cleanv != '' && !preg_match("/^http[s]*:\/\//i", $cleanv)) {
778
                            $cleanv = 'http://' . $cleanv;
779
                        }
780
                        if (!$v['not_gpc']) {
781
                            $cleanv =& $ts->stripSlashesGPC($cleanv);
782
                        }
783
                        break;
784
                    case XOBJ_DTYPE_ARRAY:
785
                        $cleanv = (array)$cleanv;
786
                        $cleanv = serialize($cleanv);
787
                        break;
788
                    case XOBJ_DTYPE_STIME:
789
                    case XOBJ_DTYPE_MTIME:
790 View Code Duplication
                    case XOBJ_DTYPE_LTIME:
791
                        $cleanv = !is_string($cleanv) ? (int)($cleanv) : strtotime($cleanv);
792
                        break;
793
                    case XOBJ_DTYPE_FLOAT:
794
                        $cleanv = (float)($cleanv);
795
                        break;
796
                    case XOBJ_DTYPE_DECIMAL:
797
                        $cleanv = (float)($cleanv);
798
                        break;
799
                    case XOBJ_DTYPE_ENUM:
800
                        if (!in_array($cleanv, $v['enumeration'])) {
801
                            $this->setErrors("Invalid Enumeration");//_XOBJ_ERR_INVALID_ENUMERATION
802
                            continue 2;
803
                        }
804
                        break;
805 View Code Duplication
                    case XOBJ_DTYPE_UNICODE_TXTBOX:
806
                        if ($v['required'] && $cleanv != '0' && $cleanv == '') {
807
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
808
                            continue 2;
809
                        }
810
                        $cleanv = xoops_convert_encode($cleanv);
811
                        if (isset($v['maxlength']) && strlen($cleanv) > (int)($v['maxlength'])) {
812
                            $this->setErrors(sprintf(_XOBJ_ERR_SHORTERTHAN, $k, (int)($v['maxlength'])));
813
                            continue 2;
814
                        }
815
                        if (!$v['not_gpc']) {
816
                            $cleanv = $ts->stripSlashesGPC($ts->censorString($cleanv));
0 ignored issues
show
Deprecated Code introduced by
The method MyTextSanitizer::censorString() has been deprecated.

This method has been deprecated.

Loading history...
817
                        } else {
818
                            $cleanv = $ts->censorString($cleanv);
0 ignored issues
show
Deprecated Code introduced by
The method MyTextSanitizer::censorString() has been deprecated.

This method has been deprecated.

Loading history...
819
                        }
820
                        break;
821 View Code Duplication
                    case XOBJ_DTYPE_UNICODE_TXTAREA:
822
                        if ($v['required'] && $cleanv != '0' && $cleanv == '') {
823
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
824
                            continue 2;
825
                        }
826
                        $cleanv = xoops_convert_encode($cleanv);
827
                        if (!$v['not_gpc']) {
828
                            $cleanv = $ts->stripSlashesGPC($ts->censorString($cleanv));
0 ignored issues
show
Deprecated Code introduced by
The method MyTextSanitizer::censorString() has been deprecated.

This method has been deprecated.

Loading history...
829
                        } else {
830
                            $cleanv = $ts->censorString($cleanv);
0 ignored issues
show
Deprecated Code introduced by
The method MyTextSanitizer::censorString() has been deprecated.

This method has been deprecated.

Loading history...
831
                        }
832
                        break;
833 View Code Duplication
                    case XOBJ_DTYPE_UNICODE_EMAIL:
834
                        if ($v['required'] && $cleanv == '') {
835
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
836
                            continue 2;
837
                        }
838
                        if ($cleanv != '' && !preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+([\.][a-z0-9-]+)+$/i", $cleanv)) {
839
                            $this->setErrors("Invalid Email");
840
                            continue 2;
841
                        }
842
                        $cleanv = xoops_convert_encode($cleanv);
843
                        if (!$v['not_gpc']) {
844
                            $cleanv = $ts->stripSlashesGPC($cleanv);
845
                        }
846
                        break;
847 View Code Duplication
                    case XOBJ_DTYPE_UNICODE_URL:
848
                        if ($v['required'] && $cleanv == '') {
849
                            $this->setErrors(sprintf(_XOBJ_ERR_REQUIRED, $k));
850
                            continue 2;
851
                        }
852
                        if ($cleanv != '' && !preg_match("/^http[s]*:\/\//i", $cleanv)) {
853
                            $cleanv = 'http://' . $cleanv;
854
                        }
855
                        $cleanv = xoops_convert_encode($cleanv);
856
                        if (!$v['not_gpc']) {
857
                            $cleanv =& $ts->stripSlashesGPC($cleanv);
858
                        }
859
                        break;
860
                    case XOBJ_DTYPE_UNICODE_ARRAY:
861
                        $cleanv = serialize(array_walk($cleanv, 'xoops_aw_encode'));
862
                        break;
863
                    default:
864
                        break;
865
866
                }
867
            }
868
            $this->cleanVars[$k] = str_replace('\\"', '"', $cleanv);
869
            unset($cleanv);
870
        }
871
        if (count($this->_errors) > 0) {
872
            $this->_errors = array_merge($existing_errors, $this->_errors);
873
874
            return false;
875
        }
876
        $this->_errors = array_merge($existing_errors, $this->_errors);
877
        $this->unsetDirty();
878
879
        return true;
880
    }
881
882
    /**
883
     * dynamically register additional filter for the object
884
     *
885
     * @param string $filtername name of the filter
886
     *
887
     * @deprecated \XoopsObject::registerFilter is deprecated since XOOPS 2.5.8 and will be removed in the next major release
888
     */
889
    public function registerFilter($filtername)
890
    {
891
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
892
        trigger_error("XoopsObject::registerFilter() is deprecated, called from {$trace[0]['file']} line {$trace[0]['line']},");
893
        $this->_filters[] = $filtername;
894
    }
895
896
    /**
897
     * load all additional filters that have been registered to the object
898
     *
899
     * @access private
900
     */
901
    public function _loadFilters()
902
    {
903
        static $loaded;
904
        if (isset($loaded)) {
905
            return null;
906
        }
907
        $loaded = 1;
908
909
        $path = empty($this->plugin_path) ? __DIR__ . '/filters' : $this->plugin_path;
0 ignored issues
show
Bug introduced by
The property plugin_path does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
910
        if (file_exists($file = $path . '/filter.php')) {
911
            include_once $file;
912
            foreach ($this->_filters as $f) {
913
                if (file_exists($file = $path . '/' . strtolower($f) . 'php')) {
914
                    include_once $file;
915
                }
916
            }
917
        }
918
    }
919
920
    /**
921
     * load all local filters for the object
922
     *
923
     * Filter distribution:
924
     * In each module folder there is a folder "filter" containing filter files with,
925
     * filename: [name_of_target_class][.][function/action_name][.php];
926
     * function name: [dirname][_][name_of_target_class][_][function/action_name];
927
     * parameter: the target object
928
     *
929
     * @param string $method function or action name
930
     *
931
     * @deprecated \XoopsObject::loadFilters is deprecated since XOOPS 2.5.8 and will be removed in the next major release
932
     */
933
    public function loadFilters($method)
934
    {
935
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
936
        trigger_error("XoopsObject::loadFilters() is deprecated, called from {$trace[0]['file']} line {$trace[0]['line']},");
937
938
        $this->_loadFilters();
939
940
        xoops_load('XoopsCache');
941
        $class = get_class($this);
942
        if (!$modules_active = XoopsCache::read('system_modules_active')) {
943
            $module_handler = xoops_getHandler('module');
944
            $modules_obj    = $module_handler->getObjects(new Criteria('isactive', 1));
945
            $modules_active = array();
946
            foreach (array_keys($modules_obj) as $key) {
947
                $modules_active[] = $modules_obj[$key]->getVar('dirname');
948
            }
949
            unset($modules_obj);
950
            XoopsCache::write('system_modules_active', $modules_active);
951
        }
952
        foreach ($modules_active as $dirname) {
953
            if (file_exists($file = XOOPS_ROOT_PATH . '/modules/' . $dirname . '/filter/' . $class . '.' . $method . '.php')) {
954
                include_once $file;
955
                if (function_exists($class . '_' . $method)) {
956
                    call_user_func_array($dirname . '_' . $class . '_' . $method, array(&$this));
957
                }
958
            }
959
        }
960
    }
961
962
    /**
963
     * create a clone(copy) of the current object
964
     *
965
     * @access public
966
     * @return object clone
967
     */
968
    public function xoopsClone()
969
    {
970
        $class = get_class($this);
971
        $clone = null;
0 ignored issues
show
Unused Code introduced by
$clone is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
972
        $clone = new $class();
973
        foreach ($this->vars as $k => $v) {
974
            $clone->assignVar($k, $v['value']);
975
        }
976
        // need this to notify the handler class that this is a newly created object
977
        $clone->setNew();
978
979
        return $clone;
980
    }
981
982
    /**
983
     * Adjust a newly cloned object
984
     */
985
    public function __clone()
986
    {
987
        // need this to notify the handler class that this is a newly created object
988
        $this->setNew();
989
    }
990
991
    /**
992
     * add an error
993
     *
994
     * @param $err_str
995
     * @internal param string $value error to add
996
     * @access   public
997
     */
998
    public function setErrors($err_str)
999
    {
1000
        if (is_array($err_str)) {
1001
            $this->_errors = array_merge($this->_errors, $err_str);
1002
        } else {
1003
            $this->_errors[] = trim($err_str);
1004
        }
1005
    }
1006
1007
    /**
1008
     * return the errors for this object as an array
1009
     *
1010
     * @return array an array of errors
1011
     * @access public
1012
     */
1013
    public function getErrors()
1014
    {
1015
        return $this->_errors;
1016
    }
1017
1018
    /**
1019
     * return the errors for this object as html
1020
     *
1021
     * @return string html listing the errors
1022
     * @access public
1023
     */
1024
    public function getHtmlErrors()
1025
    {
1026
        $ret = '<h4>Errors</h4>';
1027
        if (!empty($this->_errors)) {
1028
            foreach ($this->_errors as $error) {
1029
                $ret .= $error . '<br />';
1030
            }
1031
        } else {
1032
            $ret .= 'None<br />';
1033
        }
1034
1035
        return $ret;
1036
    }
1037
1038
    /**
1039
     * Returns an array representation of the object
1040
     *
1041
     * Deprecated, use getValues() directly
1042
     *
1043
     * @return array
1044
     */
1045
    public function toArray()
1046
    {
1047
        return $this->getValues();
1048
    }
1049
}
1050
1051
/**
1052
 * XOOPS object handler class.
1053
 * This class is an abstract class of handler classes that are responsible for providing
1054
 * data access mechanisms to the data source of its corresponding data objects
1055
 *
1056
 * @package             kernel
1057
 * @abstract
1058
 * @author              Kazumi Ono <[email protected]>
1059
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
1060
 */
1061
class XoopsObjectHandler
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
1062
{
1063
    /**
1064
     * XoopsDatabase holds referenced to {@link XoopsDatabase} class object
1065
     *
1066
     * @var XoopsDatabase
1067
     */
1068
    public $db;
1069
1070
    /**
1071
     * called from child classes only
1072
     *
1073
     * @param XoopsDatabase $db reference to the {@link XoopsDatabase} object
1074
     * @access protected
1075
     */
1076
    public function __construct(XoopsDatabase $db)
1077
    {
1078
        $this->db = $db;
1079
    }
1080
1081
    /**
1082
     * PHP 4 style constructor compatibility shim
1083
     *
1084
     * @param XoopsDatabase $db database object
1085
     * @deprecated all callers should be using parent::__construct()
1086
     */
1087
    public function XoopsObjectHandler($db)
1088
    {
1089
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
1090
        trigger_error("Should call parent::__construct in {$trace[0]['file']} line {$trace[0]['line']},");
1091
        self::__construct($db);
1092
    }
1093
1094
    /**
1095
     * creates a new object
1096
     *
1097
     * @abstract
1098
     */
1099
    public function create()
1100
    {
1101
    }
1102
1103
    /**
1104
     * gets a value object
1105
     *
1106
     * @param int $int_id
1107
     * @abstract
1108
     */
1109
    public function get($int_id)
1110
    {
1111
    }
1112
1113
    /**
1114
     * insert/update object
1115
     *
1116
     * @param XoopsObject $object
1117
     * @abstract
1118
     */
1119
    public function insert(XoopsObject $object)
1120
    {
1121
    }
1122
1123
    /**
1124
     * delete object from database
1125
     *
1126
     * @param XoopsObject $object
1127
     * @abstract
1128
     */
1129
    public function delete(XoopsObject $object)
1130
    {
1131
    }
1132
}
1133
1134
/**
1135
 * Persistable Object Handler class.
1136
 *
1137
 * @author              Taiwen Jiang <[email protected]>
1138
 * @author              Jan Keller Pedersen <[email protected]>
1139
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
1140
 * @package             Kernel
1141
 */
1142
class XoopsPersistableObjectHandler extends XoopsObjectHandler
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
1143
{
1144
    /**
1145
     * holds reference to custom extended object handler
1146
     *
1147
     * var object
1148
     *
1149
     * @access private
1150
     */
1151
    /**
1152
     * static protected
1153
     */
1154
    public $handler;
1155
1156
    /**
1157
     * holds reference to predefined extended object handlers: read, stats, joint, write, sync
1158
     *
1159
     * The handlers hold methods for different purposes, which could be all put together inside of current class.
1160
     * However, load codes only if they are necessary, thus they are now split out.
1161
     *
1162
     * var array of objects
1163
     *
1164
     * @access private
1165
     */
1166
    /**
1167
     * static protected
1168
     */
1169
    public $handlers = array('read' => null, 'stats' => null, 'joint' => null, 'write' => null, 'sync' => null);
1170
1171
    /**
1172
     * *#@+
1173
     * Information about the class, the handler is managing
1174
     *
1175
     * @var string
1176
     * @access public
1177
     */
1178
    public $table;
1179
    public $keyName;
1180
    public $className;
1181
    public $identifierName;
1182
    /**
1183
     * *#@-
1184
     */
1185
1186
    /**
1187
     * Constructor
1188
     *
1189
     * @param null|XoopsDatabase $db             database connection
1190
     * @param string             $table          Name of database table
1191
     * @param string             $className      Name of the XoopsObject class this handler manages
1192
     * @param string             $keyName        Name of the property holding the key
1193
     * @param string             $identifierName Name of the property holding an identifier
1194
     *                                            name (title, name ...), used on getList()
1195
     */
1196
    public function __construct(XoopsDatabase $db = null, $table = '', $className = '', $keyName = '', $identifierName = '')
1197
    {
1198
        $db    = XoopsDatabaseFactory::getDatabaseConnection();
1199
        $table = $db->prefix($table);
1200
        parent::__construct($db);
1201
        $this->table     = $table;
1202
        $this->keyName   = $keyName;
1203
        $this->className = $className;
1204
        if ($identifierName) {
1205
            $this->identifierName = $identifierName;
1206
        }
1207
    }
1208
1209
    /**
1210
     * PHP 4 style constructor compatibility shim
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
     * @deprecated all callers should be using parent::__construct()
1220
     */
1221
    public function XoopsPersistableObjectHandler(XoopsDatabase $db = null, $table = '', $className = '', $keyName = '', $identifierName = '')
1222
    {
1223
        $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
1224
        trigger_error("Should call parent::__construct in {$trace[0]['file']} line {$trace[0]['line']},");
1225
        self::__construct($db, $table, $className, $keyName, $identifierName);
1226
    }
1227
1228
    /**
1229
     * Set custom handler
1230
     *
1231
     * @access   protected
1232
     * @param null   $handler
1233
     * @param null   $args
1234
     * @param string $path path to class
1235
     * @internal param object $handler
1236
     * @internal param mixed  $args
1237
     * @return object of handler
0 ignored issues
show
Documentation introduced by
Should the return type not be null|object?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
1238
     */
1239
    public function setHandler($handler = null, $args = null, $path = null)
0 ignored issues
show
Unused Code introduced by
The parameter $path is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1240
    {
1241
        $this->handler = null;
1242
        if (is_object($handler)) {
1243
            $this->handler = $handler;
1244
        } elseif (is_string($handler)) {
1245
            xoops_load('XoopsModelFactory');
1246
            $this->handler = XoopsModelFactory::loadHandler($this, $handler, $args);
1247
        }
1248
1249
        return $this->handler;
1250
    }
1251
1252
    /**
1253
     * Load predefined handler
1254
     *
1255
     * @access protected
1256
     * @param  string $name handler name
1257
     * @param  mixed  $args args
1258
     * @return XoopsModelAbstract of handler {@link XoopsModelAbstract}
0 ignored issues
show
Documentation introduced by
Should the return type not be XoopsModelAbstract|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
1259
     */
1260
    public function loadHandler($name, $args = null)
1261
    {
1262
        static $handlers;
1263
        if (!isset($handlers[$name])) {
1264
            xoops_load('XoopsModelFactory');
1265
            $handlers[$name] = XoopsModelFactory::loadHandler($this, $name, $args);
1266
        } else {
1267
            $handlers[$name]->setHandler($this);
1268
            $handlers[$name]->setVars($args);
1269
        }
1270
1271
        return $handlers[$name];
1272
1273
        /**
1274
         * // Following code just kept as placeholder for PHP5
1275
         * if (!isset(self::$handlers[$name])) {
1276
         * self::$handlers[$name] = XoopsModelFactory::loadHandler($this, $name, $args);
1277
         * } else {
1278
         * self::$handlers[$name]->setHandler($this);
1279
         * self::$handlers[$name]->setVars($args);
1280
         * }
1281
         *
1282
         * return self::$handlers[$name];
1283
         */
1284
    }
1285
1286
    /**
1287
     * Magic method for overloading of delegation
1288
     *
1289
     * To be enabled in XOOPS 3.0 with PHP 5
1290
     *
1291
     * @access protected
1292
     * @param  string $name method name
1293
     * @param  array  $args arguments
1294
     * @return mixed
1295
     */
1296
    public function __call($name, $args)
1297
    {
1298
        if (is_object($this->handler) && is_callable(array($this->handler, $name))) {
1299
            return call_user_func_array(array($this->handler, $name), $args);
1300
        }
1301
        foreach (array_keys($this->handlers) as $_handler) {
1302
            $handler = $this->loadHandler($_handler);
1303
            if (is_callable(array($handler, $name))) {
1304
                return call_user_func_array(array($handler, $name), $args);
1305
            }
1306
        }
1307
1308
        return null;
1309
    }
1310
1311
    /**
1312
     * *#@+
1313
     * Methods of native handler {@link XoopsPersistableObjectHandler}
1314
     */
1315
    /**
1316
     * create a new object
1317
     *
1318
     * @param  bool $isNew Flag the new objects as new
1319
     * @return XoopsObject {@link XoopsObject}
1320
     */
1321
    public function create($isNew = true)
1322
    {
1323
        $obj = new $this->className();
1324
        if ($isNew === true) {
1325
            $obj->setNew();
1326
        }
1327
1328
        return $obj;
1329
    }
1330
1331
    /**
1332
     * Load a {@link XoopsObject} object from the database
1333
     *
1334
     * @access protected
1335
     * @param  mixed $id     ID
1336
     * @param  array $fields fields to fetch
1337
     * @return XoopsObject {@link XoopsObject}
0 ignored issues
show
Documentation introduced by
Should the return type not be XoopsObject|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
1338
     */
1339
    public function get($id = null, $fields = null)
1340
    {
1341
        $object = null;
1342
        if (empty($id)) {
1343
            $object = $this->create();
1344
1345
            return $object;
1346
        }
1347 View Code Duplication
        if (is_array($fields) && count($fields) > 0) {
1348
            $select = implode(',', $fields);
1349
            if (!in_array($this->keyName, $fields)) {
1350
                $select .= ', ' . $this->keyName;
1351
            }
1352
        } else {
1353
            $select = '*';
1354
        }
1355
        $sql = sprintf('SELECT %s FROM %s WHERE %s = %s', $select, $this->table, $this->keyName, $this->db->quote($id));
1356
        //$sql = "SELECT {$select} FROM {$this->table} WHERE {$this->keyName} = " . $this->db->quote($id);
1357
        if (!$result = $this->db->query($sql)) {
1358
            return $object;
1359
        }
1360
        if (!$this->db->getRowsNum($result)) {
1361
            return $object;
1362
        }
1363
        $object = $this->create(false);
1364
        $object->assignVars($this->db->fetchArray($result));
1365
1366
        return $object;
1367
    }
1368
    /**
1369
     * *#@-
1370
     */
1371
1372
    /**
1373
     * *#@+
1374
     * Methods of write handler {@link XoopsObjectWrite}
1375
     */
1376
    /**
1377
     * insert an object into the database
1378
     *
1379
     * @param  XoopsObject $object {@link XoopsObject} reference to object
1380
     * @param  bool        $force  flag to force the query execution despite security settings
1381
     * @return mixed       object ID
1382
     */
1383
    public function insert(XoopsObject $object, $force = true)
1384
    {
1385
        $handler = $this->loadHandler('write');
1386
1387
        return $handler->insert($object, $force);
1388
    }
1389
1390
    /**
1391
     * delete an object from the database
1392
     *
1393
     * @param  XoopsObject $object {@link XoopsObject} reference to the object to delete
1394
     * @param  bool        $force
1395
     * @return bool        FALSE if failed.
1396
     */
1397
    public function delete(XoopsObject $object, $force = false)
1398
    {
1399
        $handler = $this->loadHandler('write');
1400
1401
        return $handler->delete($object, $force);
1402
    }
1403
1404
    /**
1405
     * delete all objects matching the conditions
1406
     *
1407
     * @param  CriteriaElement $criteria {@link CriteriaElement} with conditions to meet
1408
     * @param  bool            $force    force to delete
1409
     * @param  bool            $asObject delete in object way: instantiate all objects and delete one by one
1410
     * @return bool
1411
     */
1412
    public function deleteAll(CriteriaElement $criteria = null, $force = true, $asObject = false)
1413
    {
1414
        $handler = $this->loadHandler('write');
1415
1416
        return $handler->deleteAll($criteria, $force, $asObject);
1417
    }
1418
1419
    /**
1420
     * Change a field for objects with a certain criteria
1421
     *
1422
     * @param  string          $fieldname  Name of the field
1423
     * @param  mixed           $fieldvalue Value to write
1424
     * @param  CriteriaElement $criteria   {@link CriteriaElement}
1425
     * @param  bool            $force      force to query
1426
     * @return bool
1427
     */
1428
    public function updateAll($fieldname, $fieldvalue, CriteriaElement $criteria = null, $force = false)
1429
    {
1430
        $handler = $this->loadHandler('write');
1431
1432
        return $handler->updateAll($fieldname, $fieldvalue, $criteria, $force);
1433
    }
1434
    /**
1435
     * *#@-
1436
     */
1437
1438
    /**
1439
     * *#@+
1440
     * Methods of read handler {@link XoopsObjectRead}
1441
     */
1442
    /**
1443
     * Retrieve objects from the database
1444
     *
1445
     * @param  CriteriaElement $criteria  {@link CriteriaElement} conditions to be met
1446
     * @param  bool            $id_as_key use the ID as key for the array
1447
     * @param  bool            $as_object return an array of objects
1448
     * @return array
1449
     */
1450
    public function &getObjects(CriteriaElement $criteria = null, $id_as_key = false, $as_object = true)
1451
    {
1452
        $handler = $this->loadHandler('read');
1453
        $ret     = $handler->getObjects($criteria, $id_as_key, $as_object);
1454
1455
        return $ret;
1456
    }
1457
1458
    /**
1459
     * get all objects matching a condition
1460
     *
1461
     * @param  CriteriaElement $criteria  {@link CriteriaElement} to match
1462
     * @param  array           $fields    variables to fetch
1463
     * @param  bool            $asObject  flag indicating as object, otherwise as array
1464
     * @param  bool            $id_as_key use the ID as key for the array
1465
     * @return array           of objects/array {@link XoopsObject}
1466
     */
1467 View Code Duplication
    public function &getAll(CriteriaElement $criteria = null, $fields = null, $asObject = true, $id_as_key = true)
1468
    {
1469
        $handler = $this->loadHandler('read');
1470
        $ret     = $handler->getAll($criteria, $fields, $asObject, $id_as_key);
1471
1472
        return $ret;
1473
    }
1474
1475
    /**
1476
     * Retrieve a list of objects data
1477
     *
1478
     * @param  CriteriaElement $criteria {@link CriteriaElement} conditions to be met
1479
     * @param  int             $limit    Max number of objects to fetch
1480
     * @param  int             $start    Which record to start at
1481
     * @return array
1482
     */
1483
    public function getList(CriteriaElement $criteria = null, $limit = 0, $start = 0)
1484
    {
1485
        $handler = $this->loadHandler('read');
1486
        $ret     = $handler->getList($criteria, $limit, $start);
1487
1488
        return $ret;
1489
    }
1490
1491
    /**
1492
     * get IDs of objects matching a condition
1493
     *
1494
     * @param  CriteriaElement $criteria {@link CriteriaElement} to match
1495
     * @return array           of object IDs
1496
     */
1497
    public function &getIds(CriteriaElement $criteria = null)
1498
    {
1499
        $handler = $this->loadHandler('read');
1500
        $ret     = $handler->getIds($criteria);
1501
1502
        return $ret;
1503
    }
1504
1505
    /**
1506
     * get a limited list of objects matching a condition
1507
     *
1508
     * {@link CriteriaCompo}
1509
     *
1510
     * @param  int             $limit    Max number of objects to fetch
1511
     * @param  int             $start    Which record to start at
1512
     * @param  CriteriaElement $criteria {@link CriteriaElement} to match
1513
     * @param  array           $fields   variables to fetch
1514
     * @param  bool            $asObject flag indicating as object, otherwise as array
1515
     * @return array           of objects     {@link XoopsObject}
1516
     */
1517
    public function &getByLimit($limit = 0, $start = 0, CriteriaElement $criteria = null, $fields = null, $asObject = true)
1518
    {
1519
        $handler = $this->loadHandler('read');
1520
        $ret     = $handler->getByLimit($limit, $start, $criteria, $fields, $asObject);
1521
1522
        return $ret;
1523
    }
1524
    /**
1525
     * *#@-
1526
     */
1527
1528
    /**
1529
     * *#@+
1530
     * Methods of stats handler {@link XoopsObjectStats}
1531
     */
1532
    /**
1533
     * count objects matching a condition
1534
     *
1535
     * @param  CriteriaElement $criteria {@link CriteriaElement} to match
1536
     * @return int             count of objects
1537
     */
1538
    public function getCount(CriteriaElement $criteria = null)
1539
    {
1540
        $handler = $this->loadHandler('stats');
1541
1542
        return $handler->getCount($criteria);
1543
    }
1544
1545
    /**
1546
     * Get counts of objects matching a condition
1547
     *
1548
     * @param  CriteriaElement $criteria {@link CriteriaElement} to match
1549
     * @return array           of counts
1550
     */
1551
    public function getCounts(CriteriaElement $criteria = null)
1552
    {
1553
        $handler = $this->loadHandler('stats');
1554
1555
        return $handler->getCounts($criteria);
1556
    }
1557
    /**
1558
     * *#@-
1559
     */
1560
1561
    /**
1562
     * *#@+
1563
     * Methods of joint handler {@link XoopsObjectJoint}
1564
     */
1565
    /**
1566
     * get a list of objects matching a condition joint with another related object
1567
     *
1568
     * @param  CriteriaElement $criteria     {@link CriteriaElement} to match
1569
     * @param  array           $fields       variables to fetch
1570
     * @param  bool            $asObject     flag indicating as object, otherwise as array
1571
     * @param  string          $field_link   field of linked object for JOIN
1572
     * @param  string          $field_object field of current object for JOIN
1573
     * @return array           of objects {@link XoopsObject}
1574
     */
1575 View Code Duplication
    public function &getByLink(CriteriaElement $criteria = null, $fields = null, $asObject = true, $field_link = null, $field_object = null)
1576
    {
1577
        $handler = $this->loadHandler('joint');
1578
        $ret     = $handler->getByLink($criteria, $fields, $asObject, $field_link, $field_object);
1579
1580
        return $ret;
1581
    }
1582
1583
    /**
1584
     * Count of objects matching a condition
1585
     *
1586
     * @param  CriteriaElement $criteria {@link CriteriaElement} to match
1587
     * @return int             count of objects
1588
     */
1589
    public function getCountByLink(CriteriaElement $criteria = null)
1590
    {
1591
        $handler = $this->loadHandler('joint');
1592
        $ret     = $handler->getCountByLink($criteria);
1593
1594
        return $ret;
1595
    }
1596
1597
    /**
1598
     * array of count of objects matching a condition of, groupby linked object keyname
1599
     *
1600
     * @param  CriteriaElement $criteria {@link CriteriaElement} to match
1601
     * @return int             count of objects
1602
     */
1603
    public function getCountsByLink(CriteriaElement $criteria = null)
1604
    {
1605
        $handler = $this->loadHandler('joint');
1606
        $ret     = $handler->getCountsByLink($criteria);
1607
1608
        return $ret;
1609
    }
1610
1611
    /**
1612
     * update objects matching a condition against linked objects
1613
     *
1614
     * @param  array           $data     array of key => value
1615
     * @param  CriteriaElement $criteria {@link CriteriaElement} to match
1616
     * @return int             count of objects
1617
     */
1618
    public function updateByLink($data, CriteriaElement $criteria = null)
1619
    {
1620
        $handler = $this->loadHandler('joint');
1621
        $ret     = $handler->updateByLink($data, $criteria);
1622
1623
        return $ret;
1624
    }
1625
1626
    /**
1627
     * Delete objects matching a condition against linked objects
1628
     *
1629
     * @param  CriteriaElement $criteria {@link CriteriaElement} to match
1630
     * @return int             count of objects
1631
     */
1632
    public function deleteByLink(CriteriaElement $criteria = null)
1633
    {
1634
        $handler = $this->loadHandler('joint');
1635
        $ret     = $handler->deleteByLink($criteria);
1636
1637
        return $ret;
1638
    }
1639
    /**
1640
     * *#@-
1641
     */
1642
1643
    /**
1644
     * *#@+
1645
     * Methods of sync handler {@link XoopsObjectSync}
1646
     */
1647
    /**
1648
     * Clean orphan objects against linked objects
1649
     *
1650
     * @param  string $table_link   table of linked object for JOIN
1651
     * @param  string $field_link   field of linked object for JOIN
1652
     * @param  string $field_object field of current object for JOIN
1653
     * @return bool   true on success
1654
     */
1655
    public function cleanOrphan($table_link = '', $field_link = '', $field_object = '')
1656
    {
1657
        $handler = $this->loadHandler('sync');
1658
        $ret     = $handler->cleanOrphan($table_link, $field_link, $field_object);
1659
1660
        return $ret;
1661
    }
1662
1663
    /**
1664
     * Synchronizing objects
1665
     *
1666
     * @return bool true on success
1667
     */
1668
    public function synchronization()
1669
    {
1670
        $retval = $this->cleanOrphan();
1671
1672
        return $retval;
1673
    }
1674
    /**
1675
     * *#@-
1676
     */
1677
1678
    /**#@+
1679
     * @deprecated
1680
     * @param      $result
1681
     * @param bool $id_as_key
1682
     * @param bool $as_object
1683
     * @return bool
1684
     */
1685
    public function convertResultSet($result, $id_as_key = false, $as_object = true)
0 ignored issues
show
Unused Code introduced by
The parameter $result is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $id_as_key is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $as_object is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1686
    {
1687
        trigger_error(__CLASS__ . "::" . __FUNCTION__ . ' is deprecated', E_USER_WARNING);
1688
1689
        return false;
1690
    }
1691
    /**#@-*/
1692
}
1693