Completed
Pull Request — master (#563)
by Richard
08:33
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;
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;
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;
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;
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;
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;
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;
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