Passed
Push — cirework ( 7349fb...97b46e )
by Richard
04:26
created

XoopsPersistableObjectHandler::loadHandler()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 2
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
ccs 9
cts 9
cp 1
crap 2
1
<?php
2
/**
3
 * You may not change or alter any portion of this comment or credits
4
 * of supporting developers from this source code or any supporting source code
5
 * which is considered copyrighted (c) material of the original comment or credit authors.
6
 * This program is distributed in the hope that it will be useful,
7
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9
 */
10
11
namespace Xoops\Core\Kernel;
12
13
use Xoops\Core\Database\Connection;
14
15
/**
16
 * XOOPS Kernel Persistable Object Handler class.
17
 *
18
 * @category  Xoops\Core\Kernel\XoopsPersistableObjectHandler
19
 * @package   Xoops\Core\Kernel
20
 * @author    Taiwen Jiang <[email protected]>
21
 * @author    Jan Keller Pedersen <[email protected]>
22
 * @copyright 2000-2015 XOOPS Project (http://xoops.org)
23
 * @license   GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
24
 * @link      http://xoops.org
25
 * @since     2.0.0
26
 */
27
abstract class XoopsPersistableObjectHandler extends XoopsObjectHandler
28
{
29
    /**
30
     * holds reference to custom extended object handler
31
     *
32
     * var object
33
     *
34
     * @access private
35
     */
36
    /**
37
     * static protected
38
     */
39
    protected $handler;
40
41
    /**
42
     * holds reference to predefined extended object handlers: read, stats, joint, write, sync
43
     *
44
     * The handlers hold methods for different purposes, which could be all put together inside of current class.
45
     * However, load codes only if they are necessary, thus they are now split out.
46
     *
47
     * var array of objects
48
     *
49
     * @access private
50
     */
51
    private $handlers = array('read' => null, 'stats' => null, 'joint' => null, 'write' => null, 'sync' => null);
52
53
    /**
54
     * Information about the class, the handler is managing
55
     *
56
     * @var string
57
     * @access public
58
     */
59
    public $table;
60
61
    /**
62
     * @var string
63
     */
64
    public $keyName;
65
66
    /**
67
     * @var string
68
     */
69
    public $className;
70
71
    /**
72
     * @var string
73
     */
74
    public $table_link;
75
76
    /**
77
     * @var string
78
     */
79
    public $identifierName;
80
81
    /**
82
     * @var string
83
     */
84
    public $field_link;
85
86
    /**
87
     * @var string
88
     */
89
    public $field_object;
90
91
    /**
92
     * Constructor
93
     *
94
     * @param null|Connection $db             database connection
95
     * @param string          $table          Name of database table
96
     * @param string          $className      Name of the XoopsObject class this handler manages
97
     * @param string          $keyName        Name of the property holding the key
98
     * @param string          $identifierName Name of the property holding an identifier
99
     *                                         name (title, name ...), used on getList()
100
     */
101 150
    protected function __construct(
102
        Connection $db = null,
103
        $table = '',
104
        $className = '',
105
        $keyName = '',
106
        $identifierName = ''
107
    ) {
108 150
        parent::__construct($db);
109 150
        $this->table = $this->db2->prefix($table);
110 150
        $this->keyName = $keyName;
111 150
        $this->className = $className;
112 150
        if ($identifierName) {
113 145
            $this->identifierName = $identifierName;
114
        }
115 150
    }
116
117
    /**
118
     * Set custom handler
119
     *
120
     * @param string|object $handler handler
121
     * @param array|null    $args    arguments
122
     *
123
     * @return object|null
124
     */
125 1
    public function setHandler($handler = null, $args = null)
126
    {
127 1
        $this->handler = null;
128 1
        if (is_object($handler)) {
129
            $this->handler = $handler;
130
        } else {
131 1
            if (is_string($handler)) {
132
                $xmf = XoopsModelFactory::getInstance();
133
                $this->handler = $xmf->loadHandler($this, $handler, $args);
134
            }
135
        }
136 1
        return $this->handler;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->handler also could return the type Xoops\Core\Kernel\XoopsModelAbstract which is incompatible with the documented return type object|null.
Loading history...
137
    }
138
139
    /**
140
     * Load predefined handler
141
     *
142
     * @param string $name handler name
143
     * @param mixed  $args args
144
     *
145
     * @return XoopsModelAbstract handler
146
     */
147 59
    public function loadHandler($name, $args = null)
148
    {
149 59
        static $handlers;
150 59
        if (!isset($handlers[$name])) {
151 24
            $xmf = XoopsModelFactory::getInstance();
152 24
            $handlers[$name] = $xmf->loadHandler($this, $name, $args);
153
        }
154
        /* @var $handler XoopsModelAbstract */
155 59
        $handler = $handlers[$name];
156 59
        $handler->setHandler($this);
157 59
        $handler->setVars($args);
158
159 59
        return $handler;
160
161
        /**
162
         * // Following code just kept as placeholder for PHP5
163
         * if (!isset(self::$handlers[$name])) {
164
         * self::$handlers[$name] = XoopsModelFactory::loadHandler($this, $name, $args);
165
         * } else {
166
         * self::$handlers[$name]->setHandler($this);
167
         * self::$handlers[$name]->setVars($args);
168
         * }
169
         *
170
         * return self::$handlers[$name];
171
         */
172
    }
173
174
    /**
175
     * Magic method for overloading of delegation
176
     *
177
     * @param string $name method name
178
     * @param array  $args arguments
179
     *
180
     * @return mixed
181
     */
182 1
    public function __call($name, $args)
183
    {
184 1
        if (is_object($this->handler) && is_callable(array($this->handler, $name))) {
185
            return call_user_func_array(array($this->handler, $name), $args);
186
        }
187 1
        foreach (array_keys($this->handlers) as $_handler) {
188 1
            $handler = $this->loadHandler($_handler);
189 1
            if (is_callable(array($handler, $name))) {
190 1
                return call_user_func_array(array($handler, $name), $args);
191
            }
192
        }
193
194 1
        return null;
195
    }
196
197
    /**
198
     * Methods of native handler
199
     */
200
201
    /**
202
     * create a new object
203
     *
204
     * @param bool $isNew Flag the new objects as new
205
     *
206
     * @return XoopsObject
207
     */
208 49
    public function create($isNew = true)
209
    {
210 49
        if (empty($this->className)) {
211 2
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type Xoops\Core\Kernel\XoopsObject.
Loading history...
212
        }
213
214
        /* @var $obj XoopsObject */
215 47
        $obj = new $this->className();
216 47
        if ($isNew === true) {
217 9
            $obj->setNew();
218
        }
219 47
        return $obj;
220
    }
221
222
    /**
223
     * Load an object from the database
224
     *
225
     * @param mixed $id     ID
226
     * @param array $fields fields to fetch
227
     *
228
     * @return XoopsObject|null
229
     */
230 11
    public function get($id = null, $fields = null)
231
    {
232 11
        $object = null;
233 11
        if (empty($id)) {
234 1
            $object = $this->create();
235 1
            return $object;
236
        }
237 10
        $qb = $this->db2->createXoopsQueryBuilder();
238 10
        $eb = $qb->expr();
239 10
        if (is_array($fields) && count($fields) > 0) {
240
            if (!in_array($this->keyName, $fields)) {
241
                $fields[] = $this->keyName;
242
            }
243
            $first=true;
244
            foreach ($fields as $field) {
245
                if ($first) {
246
                    $first=false;
247
                    $qb->select($field);
248
                } else {
249
                    $qb->addSelect($field);
250
                }
251
            }
252
        } else {
253 10
            $qb->select('*');
254
        }
255 10
        $qb->from($this->table, null)
256 10
            ->where($eb->eq($this->keyName, ':id'))
257 10
            ->setParameter(':id', $id, \PDO::PARAM_INT);
258 10
        if (!$result = $qb->execute()) {
259
            return $object;
260
        }
261 10
        $row = $result->fetch(\PDO::FETCH_ASSOC);
262 10
        if (!$row) {
263 1
            return $object;
264
        }
265 10
        $object = $this->create(false);
266 10
        $object->assignVars($row);
267
268 10
        return $object;
269
    }
270
271
    /**
272
     * Methods of write handler
273
     */
274
275
    /**
276
     * insert an object into the database
277
     *
278
     * @param XoopsObject $object object to insert
279
     * @param bool        $force  flag to force the query execution despite security settings
280
     *
281
     * @return mixed
282
     */
283 9
    public function insert(XoopsObject $object, $force = true)
284
    {
285
        /* @var $handler Model\Write */
286 9
        $handler = $this->loadHandler('write');
287 9
        return $handler->insert($object, $force);
288
    }
289
290
    /**
291
     * delete an object from the database
292
     *
293
     * @param XoopsObject $object object to delete
294
     * @param bool        $force  force delete
295
     *
296
     * @return bool FALSE if failed.
297
     */
298 7
    public function delete(XoopsObject $object, $force = false)
299
    {
300
        /* @var $handler Model\Write */
301 7
        $handler = $this->loadHandler('write');
302 7
        return $handler->delete($object, $force);
303
    }
304
305
    /**
306
     * delete all objects matching the conditions
307
     *
308
     * @param CriteriaElement $criteria criteria to match
309
     * @param boolean         $force    force to delete
310
     * @param boolean         $asObject delete in object way: instantiate all objects
311
     *                                       and delete one by one
312
     *
313
     * @return bool
314
     */
315 6
    public function deleteAll(CriteriaElement $criteria, $force = true, $asObject = false)
316
    {
317 6
        if (empty($criteria)) {
318
            return false;
319
        }
320
321
        /* @var $handler Model\Write */
322 6
        $handler = $this->loadHandler('write');
323 6
        return $handler->deleteAll($criteria, $force, $asObject);
324
    }
325
326
    /**
327
     * Change a field for objects with a certain criteria
328
     *
329
     * @param string          $fieldname  Name of the field
330
     * @param mixed           $fieldvalue Value to write
331
     * @param CriteriaElement $criteria   criteria to match
332
     * @param boolean         $force      force to query
333
     *
334
     * @return bool
335
     */
336 1
    public function updateAll($fieldname, $fieldvalue, CriteriaElement $criteria, $force = false)
337
    {
338 1
        if (empty($criteria)) {
339
            return false;
340
        }
341
342
        /* @var $handler Model\Write */
343 1
        $handler = $this->loadHandler('write');
344 1
        return $handler->updateAll($fieldname, $fieldvalue, $criteria, $force);
345
    }
346
347
    /**
348
     * Methods of read handler
349
     */
350
351
    /**
352
     * Retrieve objects from the database
353
     *
354
     * @param CriteriaElement|null $criteria  criteria to match
355
     * @param bool                 $id_as_key use the ID as key for the array
356
     * @param bool                 $as_object return an array of objects
357
     *
358
     * @return array
359
     */
360 26
    public function getObjects(CriteriaElement $criteria = null, $id_as_key = false, $as_object = true)
361
    {
362
        /* @var $handler Model\Read */
363 26
        $handler = $this->loadHandler('read');
364 26
        $ret = $handler->getObjects($criteria, $id_as_key, $as_object);
365 26
        return $ret;
366
    }
367
368
    /**
369
     * get all objects matching a condition
370
     *
371
     * @param CriteriaElement|null $criteria  criteria to match
372
     * @param array                $fields    variables to fetch
373
     * @param bool                 $asObject  flag indicating as object, otherwise as array
374
     * @param bool                 $id_as_key use the ID as key for the array
375
     *
376
     * @return array of objects/array as requested by $asObject
377
     */
378 2
    public function getAll(CriteriaElement $criteria = null, $fields = null, $asObject = true, $id_as_key = true)
379
    {
380
        /* @var $handler Model\Read */
381 2
        $handler = $this->loadHandler('read');
382 2
        $ret = $handler->getAll($criteria, $fields, $asObject, $id_as_key);
383 2
        return $ret;
384
    }
385
386
    /**
387
     * Retrieve a list of objects data
388
     *
389
     * @param CriteriaElement|null $criteria criteria to match
390
     * @param int                  $limit    Max number of objects to fetch
391
     * @param int                  $start    Which record to start at
392
     *
393
     * @return array
394
     */
395 1
    public function getList(CriteriaElement $criteria = null, $limit = 0, $start = 0)
396
    {
397
        /* @var $handler Model\Read */
398 1
        $handler = $this->loadHandler('read');
399 1
        $ret = $handler->getList($criteria, $limit, $start);
400 1
        return $ret;
401
    }
402
403
    /**
404
     * get IDs of objects matching a condition
405
     *
406
     * @param CriteriaElement|null $criteria criteria to match
407
     *
408
     * @return array of object IDs
409
     */
410 1
    public function getIds(CriteriaElement $criteria = null)
411
    {
412
        /* @var $handler Model\Read */
413 1
        $handler = $this->loadHandler('read');
414 1
        $ret = $handler->getIds($criteria);
415 1
        return $ret;
416
    }
417
418
    /**
419
     * Methods of stats handler
420
     */
421
422
    /**
423
     * count objects matching a condition
424
     *
425
     * @param CriteriaElement|null $criteria criteria to match
426
     *
427
     * @return int count of objects
428
     */
429 8
    public function getCount(CriteriaElement $criteria = null)
430
    {
431
        /* @var $handler Model\Stats */
432 8
        $handler = $this->loadHandler('stats');
433 8
        return $handler->getCount($criteria);
434
    }
435
436
    /**
437
     * Get counts of objects matching a condition
438
     *
439
     * @param CriteriaElement|null $criteria criteria to match
440
     *
441
     * @return array of counts
442
     */
443 1
    public function getCounts(CriteriaElement $criteria = null)
444
    {
445
        /* @var $handler Model\Stats*/
446 1
        $handler = $this->loadHandler('stats');
447 1
        return $handler->getCounts($criteria);
448
    }
449
450
    /**
451
     * Methods of joint handler
452
     */
453
454
    /**
455
     * get a list of objects matching a condition joint with another related object
456
     *
457
     * @param CriteriaElement|null $criteria     criteria to match
458
     * @param array                $fields       variables to fetch
459
     * @param bool                 $asObject     flag indicating as object, otherwise as array
460
     * @param string               $field_link   field of linked object for JOIN
461
     * @param string               $field_object field of current object for JOIN
462
     *
463
     * @return array as specified by $asObject
464
     */
465 1
    public function getByLink(
466
        CriteriaElement $criteria = null,
467
        $fields = null,
468
        $asObject = true,
469
        $field_link = null,
470
        $field_object = null
471
    ) {
472
        /* @var $handler Model\Joint */
473 1
        $handler = $this->loadHandler('joint');
474 1
        $ret = $handler->getByLink($criteria, $fields, $asObject, $field_link, $field_object);
475 1
        return $ret;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ret returns the type false which is incompatible with the documented return type array.
Loading history...
476
    }
477
478
    /**
479
     * Count of objects matching a condition
480
     *
481
     * @param CriteriaElement|null $criteria criteria to match
482
     *
483
     * @return int count of objects
484
     */
485 1
    public function getCountByLink(CriteriaElement $criteria = null)
486
    {
487
        /* @var $handler Model\Joint */
488 1
        $handler = $this->loadHandler('joint');
489 1
        $ret = $handler->getCountByLink($criteria);
490 1
        return $ret;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ret returns the type false which is incompatible with the documented return type integer.
Loading history...
491
    }
492
493
    /**
494
     * array of count of objects matching a condition of, groupby linked object keyname
495
     *
496
     * @param CriteriaElement|null $criteria criteria to match
497
     *
498
     * @return int count of objects
499
     */
500 1
    public function getCountsByLink(CriteriaElement $criteria = null)
501
    {
502
        /* @var $handler Model\Joint */
503 1
        $handler = $this->loadHandler('joint');
504 1
        $ret = $handler->getCountsByLink($criteria);
505 1
        return $ret;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ret returns the type false which is incompatible with the documented return type integer.
Loading history...
506
    }
507
508
    /**
509
     * update objects matching a condition against linked objects
510
     *
511
     * @param array                $data     array of key => value
512
     * @param CriteriaElement|null $criteria criteria to match
513
     *
514
     * @return int count of objects
515
     */
516 1
    public function updateByLink($data, CriteriaElement $criteria = null)
517
    {
518
        /* @var $handler Model\Joint */
519 1
        $handler = $this->loadHandler('joint');
520 1
        $ret = $handler->updateByLink($data, $criteria);
521 1
        return $ret;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ret could also return false which is incompatible with the documented return type integer. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
522
    }
523
524
    /**
525
     * Delete objects matching a condition against linked objects
526
     *
527
     * @param CriteriaElement|null $criteria criteria to match
528
     *
529
     * @return int count of objects
530
     */
531 1
    public function deleteByLink(CriteriaElement $criteria = null)
532
    {
533
        /* @var $handler Model\Joint */
534 1
        $handler = $this->loadHandler('joint');
535 1
        $ret = $handler->deleteByLink($criteria);
536 1
        return $ret;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ret could also return false which is incompatible with the documented return type integer. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
537
    }
538
539
    /**
540
     * Methods of sync handler
541
     */
542
543
    /**
544
     * Clean orphan objects against linked objects
545
     *
546
     * @param string $table_link   table of linked object for JOIN
547
     * @param string $field_link   field of linked object for JOIN
548
     * @param string $field_object field of current object for JOIN
549
     *
550
     * @return bool true on success
551
     */
552
    public function cleanOrphan($table_link = '', $field_link = '', $field_object = '')
553
    {
554
        /* @var $handler Model\Sync */
555
        $handler = $this->loadHandler('sync');
556
        $ret = $handler->cleanOrphan($table_link, $field_link, $field_object);
557
        return $ret;
558
    }
559
560
    /**
561
     * Synchronizing objects
562
     *
563
     * @param string $table_link   parent table
564
     * @param string $field_link   primary key (parent table)
565
     * @param string $field_object foreign key (child table)
566
     *
567
     * @return bool true on success
568
     */
569
    public function synchronization($table_link = '', $field_link = '', $field_object = '')
570
    {
571
        $retval = $this->cleanOrphan($table_link, $field_link, $field_object);
572
        return $retval;
573
    }
574
}
575