Completed
Push — master ( 9d3fbd...af269e )
by Michael
09:48
created

class/PersistableObjectHandler.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
*/
11
12
/**
13
 * oledrion
14
 *
15
 * @copyright   {@link https://xoops.org/ XOOPS Project}
16
 * @license     {@link http://www.fsf.org/copyleft/gpl.html GNU public license}
17
 * @author      Hervé Thouzard (http://www.herve-thouzard.com/)
18
 */
19
// defined('XOOPS_ROOT_PATH') || exit('XOOPS root path not defined');
20
21
class Oledrion_Object extends XoopsObject
22
{
23
    /**
24
     * @param  string $format
25
     * @return array
26
     */
27
    public function toArray($format = 's')
28
    {
29
        $ret = array();
30
        foreach ($this->vars as $k => $v) {
31
            $ret[$k] = $this->getVar($k, $format);
32
        }
33
34
        return $ret;
35
    }
36
37
    // TODO: Rajouter une méthode intsert() et delete()
38
39
    /**
40
     * Permet de valoriser un champ de la table comme si c'était une propriété de la classe
41
     *
42
     * @example $enregistrement->nom_du_champ = 'ma chaine'
43
     *
44
     * @param  string $key   Le nom du champ à traiter
45
     * @param  mixed  $value La valeur à lui attribuer
46
     * @return void
47
     */
48
    public function __set($key, $value)
49
    {
50
        return $this->setVar($key, $value);
51
    }
52
53
    /**
54
     * Permet d'accéder aux champs de la table comme à des propriétés de la classe
55
     *
56
     * @example echo $enregistrement->nom_du_champ;
57
     *
58
     * @param  string $key Le nom du champ que l'on souhaite récupérer
59
     * @return mixed
60
     */
61
    public function __get($key)
62
    {
63
        return $this->getVar($key);
64
    }
65
}
66
67
/**
68
 * Persistable Object Handler class.
69
 * This class is responsible for providing data access mechanisms to the data source
70
 * of derived class objects. Original Author : Mithrandir
71
 *
72
 */
73
class Oledrion_XoopsPersistableObjectHandler extends XoopsObjectHandler
74
{
75
    /**#@+
76
     * Information about the class, the handler is managing
77
     *
78
     * @var string
79
     */
80
    public $table;
81
    protected $keyName;
82
    protected $className;
83
    protected $identifierName;
84
    protected $cacheOptions = array();
85
86
    /**#@-*/
87
88
    /**
89
     * Constructor - called from child classes
90
     * @param object|XoopsDatabase $db           {@link XoopsDatabase}
91
     *                                           object
92
     * @param string               $tablename    Name of database table
93
     * @param string               $classname    Name of Class, this handler is managing
94
     * @param string               $keyname      Name of the property, holding the key
95
     * @param string               $idenfierName Name of the property, holding the label
96
     * @param array                $cacheOptions Optional, options for the cache
0 ignored issues
show
Should the type for parameter $cacheOptions not be array|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
97
     */
98
    public function __construct(XoopsDatabase $db, $tablename, $classname, $keyname, $idenfierName = '', $cacheOptions = null)
99
    {
100
        //require_once dirname(__DIR__) . '/include/common.php';
101
        require_once XOOPS_ROOT_PATH . '/modules/oledrion/include/common.php';
102
        //        $this->XoopsObjectHandler($db);
103
        parent::__construct($db);
104
        $this->table     = $db->prefix($tablename);
105
        $this->keyName   = $keyname;
106
        $this->className = $classname;
107
        if (trim($idenfierName) != '') {
108
            $this->identifierName = $idenfierName;
109
        }
110
        // To diable cache, add this line after the first one : 'caching' => false,
111
        if (null === $cacheOptions) {
112
            $this->setCachingOptions(array(
113
                                         'cacheDir'               => OLEDRION_CACHE_PATH,
114
                                         'lifeTime'               => null,
115
                                         'automaticSerialization' => true,
116
                                         'fileNameProtection'     => false
117
                                     ));
118
        } else {
119
            $this->setCachingOptions($cacheOptions);
120
        }
121
    }
122
123
    /**
124
     * @param $cacheOptions
125
     */
126
    public function setCachingOptions($cacheOptions)
127
    {
128
        $this->cacheOptions = $cacheOptions;
129
    }
130
131
    /**
132
     * Generates a unique ID for a Sql Query
133
     *
134
     * @param  string  $query The SQL query for which we want a unidque ID
135
     * @param  integer $start Which record to start at
136
     * @param  integer $limit Max number of objects to fetch
137
     * @return string  An MD5 of the query
138
     */
139
    protected function _getIdForCache($query, $start, $limit)
140
    {
141
        $id = md5($query . '-' . (string)$start . '-' . (string)$limit);
142
143
        return $id;
144
    }
145
146
    /**
147
     * create a new object
148
     *
149
     * @param bool $isNew Flag the new objects as "new"?
150
     *
151
     * @return object
152
     */
153
    public function create($isNew = true)
154
    {
155
        $obj = new $this->className();
156
        if ($isNew === true) {
157
            $obj->setNew();
158
        }
159
160
        return $obj;
161
    }
162
163
    /**
164
     * retrieve an object
165
     *
166
     * @param  mixed $id        ID of the object - or array of ids for joint keys. Joint keys MUST be given in the same order as in the constructor
167
     * @param  bool  $as_object whether to return an object or an array
168
     * @return mixed reference to the object, FALSE if failed
169
     */
170
    public function get($id, $as_object = true)
171
    {
172
        if (is_array($this->keyName)) {
173
            $criteria = new CriteriaCompo();
174
            $vnb      = count($this->keyName);
175
            for ($i = 0; $i < $vnb; ++$i) {
176
                $criteria->add(new Criteria($this->keyName[$i], (int)$id[$i]));
177
            }
178
        } else {
179
            $criteria = new Criteria($this->keyName, (int)$id);
180
        }
181
        $criteria->setLimit(1);
182
        $obj_array = $this->getObjects($criteria, false, $as_object);
183
        if (count($obj_array) != 1) {
184
            $ret = null;
185
        } else {
186
            $ret = $obj_array[0];
187
        }
188
189
        return $ret;
190
    }
191
192
    /**
193
     * retrieve objects from the database
194
     *
195
     * @param object  $criteria  {@link CriteriaElement} conditions to be met
196
     * @param bool    $id_as_key use the ID as key for the array?
197
     * @param bool    $as_object return an array of objects?
198
     *
199
     * @param  string $fields
200
     * @param  bool   $autoSort
201
     * @return array
202
     */
203
    public function getObjects(
204
        $criteria = null,
205
        $id_as_key = false,
206
        $as_object = true,
207
        $fields = '*',
208
        $autoSort = true
209
    ) {
210
        //require_once __DIR__ . '/lite.php';
211
        $ret   = array();
212
        $limit = $start = 0;
213
        $sql   = 'SELECT ' . $fields . ' FROM ' . $this->table;
214 View Code Duplication
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
215
            $sql .= ' ' . $criteria->renderWhere();
216
            if ($criteria->groupby != '') {
217
                $sql .= $criteria->getGroupby();
218
            }
219
            if ($criteria->getSort() != '') {
220
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
221
            } elseif ($this->identifierName != '' && $autoSort) {
222
                $sql .= ' ORDER BY ' . $this->identifierName;
223
            }
224
            $limit = $criteria->getLimit();
225
            $start = $criteria->getStart();
226
        }
227
        //$Cache_Lite = new oledrion_Cache_Lite($this->cacheOptions);
228
        $id = $this->_getIdForCache($sql, $start, $limit);
229
        //$cacheData = $Cache_Lite->get($id);
230
        //if ($cacheData === false) {
231
        $result = $this->db->query($sql, $limit, $start);
232
        if (!$result) {
233
            return $ret;
234
        }
235
        $ret = $this->convertResultSet($result, $id_as_key, $as_object, $fields);
236
237
        //$Cache_Lite->save($ret);
238
        return $ret;
239
        //} else {
240
        //return $cacheData;
241
        //}
242
    }
243
244
    /**
245
     * Convert a database resultset to a returnable array
246
     *
247
     * @param object  $result    database resultset
248
     * @param boolean $id_as_key - should NOT be used with joint keys
249
     * @param boolean $as_object
250
     * @param string  $fields    Requested fields from the query
251
     *
252
     * @return array
253
     */
254
    protected function convertResultSet($result, $id_as_key = false, $as_object = true, $fields = '*')
255
    {
256
        $ret = array();
257
        while ($myrow = $this->db->fetchArray($result)) {
258
            $obj = $this->create(false);
259
            $obj->assignVars($myrow);
260
            if (!$id_as_key) {
261 View Code Duplication
                if ($as_object) {
262
                    $ret[] = $obj;
263
                } else {
264
                    $row     = array();
265
                    $vars    = $obj->getVars();
266
                    $tbl_tmp = array_keys($vars);
267
                    foreach ($tbl_tmp as $i) {
268
                        $row[$i] = $obj->getVar($i);
269
                    }
270
                    $ret[] = $row;
271
                }
272
            } else {
273
                if ($as_object) {
274
                    if ($fields === '*') {
275
                        $ret[$myrow[$this->keyName]] = $obj;
276
                    } else {
277
                        $ret[] = $obj;
278
                    }
279 View Code Duplication
                } else {
280
                    $row     = array();
281
                    $vars    = $obj->getVars();
282
                    $tbl_tmp = array_keys($vars);
283
                    foreach ($tbl_tmp as $i) {
284
                        $row[$i] = $obj->getVar($i);
285
                    }
286
                    $ret[$myrow[$this->keyName]] = $row;
287
                }
288
            }
289
            unset($obj);
290
        }
291
292
        return $ret;
293
    }
294
295
    /**
296
     * get IDs of objects matching a condition
297
     *
298
     * @param  object $criteria {@link CriteriaElement} to match
299
     * @return array  of object IDs
300
     */
301
    public function getIds($criteria = null)
302
    {
303
        //require_once __DIR__ . '/lite.php';
304
        $limit = $start = 0;
305
306
        //$Cache_Lite = new oledrion_Cache_Lite($this->cacheOptions);
307
        $sql = 'SELECT ' . $this->keyName . ' FROM ' . $this->table;
308 View Code Duplication
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
309
            $sql .= ' ' . $criteria->renderWhere();
310
            if ($criteria->groupby != '') {
311
                $sql .= $criteria->getGroupby();
312
            }
313
            if ($criteria->getSort() != '') {
314
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
315
            } elseif ($this->identifierName != '') {
316
                $sql .= ' ORDER BY ' . $this->identifierName;
317
            }
318
            $limit = $criteria->getLimit();
319
            $start = $criteria->getStart();
320
        }
321
322
        $id = $this->_getIdForCache($sql, $start, $limit);
323
        //$cacheData = $Cache_Lite->get($id);
324
        //if ($cacheData === false) {
325
        $result = $this->db->query($sql, $limit, $start);
326
        $ret    = array();
327
        while ($myrow = $this->db->fetchArray($result)) {
328
            $ret[] = $myrow[$this->keyName];
329
        }
330
331
        //$Cache_Lite->save($ret);
332
        return $ret;
333
        //} else {
334
        //  return $cacheData;
335
        //}
336
    }
337
338
    /**
339
     * Retrieve a list of objects as arrays - DON'T USE WITH JOINT KEYS
340
     *
341
     * @param  object $criteria {@link CriteriaElement} conditions to be met
342
     * @return array
343
     */
344
    public function getList($criteria = null)
345
    {
346
        //require_once __DIR__ . '/lite.php';
347
        $limit = $start = 0;
348
        //$Cache_Lite = new oledrion_Cache_Lite($this->cacheOptions);
349
350
        $ret = array();
351
352
        $sql = 'SELECT ' . $this->keyName;
353
        if (!empty($this->identifierName)) {
354
            $sql .= ', ' . $this->identifierName;
355
        }
356
        $sql .= ' FROM ' . $this->table;
357 View Code Duplication
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
358
            $sql .= ' ' . $criteria->renderWhere();
359
            if ($criteria->groupby != '') {
360
                $sql .= $criteria->getGroupby();
361
            }
362
            if ($criteria->getSort() != '') {
363
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
364
            } elseif ($this->identifierName != '') {
365
                $sql .= ' ORDER BY ' . $this->identifierName;
366
            }
367
            $limit = $criteria->getLimit();
368
            $start = $criteria->getStart();
369
        }
370
371
        $id = $this->_getIdForCache($sql, $start, $limit);
372
        // $cacheData = $Cache_Lite->get($id);
373
        //if ($cacheData === false) {
374
        $result = $this->db->query($sql, $limit, $start);
375
        if (!$result) {
376
            //$Cache_Lite->save($ret);
377
            return $ret;
378
        }
379
380
        $myts = MyTextSanitizer::getInstance();
381
        while ($myrow = $this->db->fetchArray($result)) {
382
            // identifiers should be textboxes, so sanitize them like that
383
            $ret[$myrow[$this->keyName]] = empty($this->identifierName) ? 1 : $myts->htmlSpecialChars($myrow[$this->identifierName]);
384
        }
385
386
        //$Cache_Lite->save($ret);
387
        return $ret;
388
        //} else {
389
        //return $cacheData;
390
        // }
391
    }
392
393
    /**
394
     * Retourne des éléments selon leur ID
395
     *
396
     * @param  array $ids Les ID des éléments à retrouver
397
     * @return array Tableau d'objets (clé = id key name)
398
     */
399
    public function getItemsFromIds($ids)
400
    {
401
        $ret = array();
402
        if (is_array($ids) && count($ids) > 0) {
403
            $criteria = new Criteria($this->keyName, '(' . implode(',', $ids) . ')', 'IN');
404
            $ret      = $this->getObjects($criteria, true);
405
        }
406
407
        return $ret;
408
    }
409
410
    /**
411
     * count objects matching a condition
412
     *
413
     * @param  object $criteria {@link CriteriaElement} to match
414
     * @return int    count of objects
415
     */
416
    public function getCount($criteria = null)
417
    {
418
        $field   = '';
419
        $groupby = false;
420
        $limit   = $start = 0;
421
        //require_once __DIR__ . '/lite.php';
422
423
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
424
            if ($criteria->groupby != '') {
425
                $groupby = true;
426
                $field   = $criteria->groupby . ', '; //Not entirely secure unless you KNOW that no criteria's groupby clause is going to be mis-used
427
            }
428
        }
429
        $sql = 'SELECT ' . $field . 'COUNT(*) FROM ' . $this->table;
430 View Code Duplication
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
431
            $sql .= ' ' . $criteria->renderWhere();
432
            if ($criteria->groupby != '') {
433
                $sql .= $criteria->getGroupby();
434
            }
435
            $limit = $criteria->getLimit();
436
            $start = $criteria->getStart();
437
        }
438
        //$Cache_Lite = new oledrion_Cache_Lite($this->cacheOptions);
439
        $id = $this->_getIdForCache($sql, $start, $limit);
440
        //$cacheData = $Cache_Lite->get($id);
441
        //if ($cacheData === false) {
442
        $result = $this->db->query($sql, $limit, $start);
443
        if (!$result) {
444
            $ret = 0;
445
            $Cache_Lite->save($ret);
446
447
            return $ret;
448
        }
449
        if (false === $groupby) {
450
            list($count) = $this->db->fetchRow($result);
451
452
            //$Cache_Lite->save($count);
453
            return $count;
454
        } else {
455
            $ret = array();
456
            while (list($id, $count) = $this->db->fetchRow($result)) {
457
                $ret[$id] = $count;
458
            }
459
460
            //  $Cache_Lite->save($ret);
461
            return $ret;
462
        }
463
        //} else {
464
        //return $cacheData;
465
        //}
466
    }
467
468
    /**
469
     * Retourne le total d'un champ
470
     *
471
     * @param  string $field    Le champ dont on veut calculer le total
472
     * @param  object $criteria {@link CriteriaElement} to match
473
     * @return integer le total
474
     */
475
    public function getSum($field, $criteria = null)
476
    {
477
        $limit = $start = 0;
478
        //require_once __DIR__ . '/lite.php';
479
480
        $sql = 'SELECT Sum(' . $field . ') as cpt FROM ' . $this->table;
481 View Code Duplication
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
482
            $sql .= ' ' . $criteria->renderWhere();
483
            if ($criteria->groupby != '') {
484
                $sql .= $criteria->getGroupby();
485
            }
486
            $limit = $criteria->getLimit();
487
            $start = $criteria->getStart();
488
        }
489
        //$Cache_Lite = new oledrion_Cache_Lite($this->cacheOptions);
490
        $id = $this->_getIdForCache($sql, $start, $limit);
491
        //$cacheData = $Cache_Lite->get($id);
492
        //if ($cacheData === false) {
493
        $result = $this->db->query($sql, $limit, $start);
494
        if (!$result) {
495
            $ret = 0;
496
497
            //$Cache_Lite->save($ret);
498
            return $ret;
499
        }
500
        $row   = $this->db->fetchArray($result);
501
        $count = $row['cpt'];
502
503
        //$Cache_Lite->save($count);
504
        return $count;
505
        //} else {
506
        //  return $cacheData;
507
        // }
508
    }
509
510
    /**
511
     * delete an object from the database
512
     *
513
     * @param  XoopsObject $obj reference to the object to delete
514
     * @param  bool        $force
515
     * @return bool   FALSE if failed.
516
     */
517
    public function delete(XoopsObject $obj, $force = false)
518
    {
519
        if (is_array($this->keyName)) {
520
            $clause = array();
521
            $vnb    = count($this->keyName);
522
            for ($i = 0; $i < $vnb; ++$i) {
523
                $clause[] = $this->keyName[$i] . ' = ' . $obj->getVar($this->keyName[$i]);
524
            }
525
            $whereclause = implode(' AND ', $clause);
526
        } else {
527
            $whereclause = $this->keyName . ' = ' . $obj->getVar($this->keyName);
528
        }
529
        $sql = 'DELETE FROM ' . $this->table . ' WHERE ' . $whereclause;
530 View Code Duplication
        if (false !== $force) {
531
            $result = $this->db->queryF($sql);
532
        } else {
533
            $result = $this->db->query($sql);
534
        }
535
        // Clear cache
536
        $this->forceCacheClean();
537
538
        if (!$result) {
539
            return false;
540
        }
541
542
        return true;
543
    }
544
545
    /**
546
     * Quickly insert a record like this $myobjectHandler->quickInsert('field1' => field1value, 'field2' => $field2value)
547
     *
548
     * @param  array $vars  Array containing the fields name and value
549
     * @param  bool  $force whether to force the query execution despite security settings
550
     * @return bool  @link insert's value
551
     */
552
    public function quickInsert($vars = null, $force = true)
553
    {
554
        $object = $this->create(true);
555
        $object->setVars($vars);
556
        $retval = $this->insert($object, $force);
557
        unset($object);
558
559
        // Clear cache
560
        $this->forceCacheClean();
561
562
        return $retval;
563
    }
564
565
    /**
566
     * insert a new object in the database
567
     *
568
     * @param  XoopsObject $obj         reference to the object
569
     * @param  bool        $force       whether to force the query execution despite security settings
570
     * @param  bool        $checkObject check if the object is dirty and clean the attributes
571
     * @return bool   FALSE if failed, TRUE if already present and unchanged or successful
572
     */
573
574
    public function insert(XoopsObject $obj, $force = false, $checkObject = true)
575
    {
576
        if (false !== $checkObject) {
577
            if (!is_object($obj)) {
578
                trigger_error('Error, not object');
579
580
                return false;
581
            }
582
            /**
583
             * @TODO: Change to if (!(class_exists($this->className) && $obj instanceof $this->className)) when going fully PHP5
584
             */
585
            if (!is_a($obj, $this->className)) {
586
                $obj->setErrors(get_class($obj) . ' Differs from ' . $this->className);
587
588
                return false;
589
            }
590
            if (!$obj->isDirty()) {
591
                $obj->setErrors('Not dirty'); //will usually not be outputted as errors are not displayed when the method returns true, but it can be helpful when troubleshooting code - Mith
592
593
                return true;
594
            }
595
        }
596
        if (!$obj->cleanVars()) {
597
            foreach ($obj->getErrors() as $oneerror) {
598
                trigger_error($oneerror);
599
            }
600
601
            return false;
602
        }
603
        foreach ($obj->cleanVars as $k => $v) {
604
            if ($obj->vars[$k]['data_type'] == XOBJ_DTYPE_INT) {
605
                $cleanvars[$k] = (int)$v;
606
            } elseif (is_array($v)) {
607
                $cleanvars[$k] = $this->db->quoteString(implode(',', $v));
608
            } else {
609
                $cleanvars[$k] = $this->db->quoteString($v);
610
            }
611
        }
612
        if (isset($cleanvars['dohtml'])) { // Modification Hervé to be able to use dohtml
613
            unset($cleanvars['dohtml']);
614
        }
615
        if ($obj->isNew()) {
616
            if (!is_array($this->keyName)) {
617
                if ($cleanvars[$this->keyName] < 1) {
618
                    $cleanvars[$this->keyName] = $this->db->genId($this->table . '_' . $this->keyName . '_seq');
619
                }
620
            }
621
            $sql = 'INSERT INTO ' . $this->table . ' (' . implode(',', array_keys($cleanvars)) . ') VALUES (' . implode(',', array_values($cleanvars)) . ')';
622
        } else {
623
            $sql = 'UPDATE ' . $this->table . ' SET';
624
            foreach ($cleanvars as $key => $value) {
625
                if ((!is_array($this->keyName) && $key == $this->keyName)
626
                    || (is_array($this->keyName)
627
                        && in_array($key, $this->keyName))) {
628
                    continue;
629
                }
630
                if (isset($notfirst)) {
631
                    $sql .= ',';
632
                }
633
                $sql      .= ' ' . $key . ' = ' . $value;
634
                $notfirst = true;
635
            }
636
            if (is_array($this->keyName)) {
637
                $whereclause = '';
638
                $vnb         = count($this->keyName);
639
                for ($i = 0; $i < $vnb; ++$i) {
640
                    if ($i > 0) {
641
                        $whereclause .= ' AND ';
642
                    }
643
                    $whereclause .= $this->keyName[$i] . ' = ' . $obj->getVar($this->keyName[$i]);
644
                }
645
            } else {
646
                $whereclause = $this->keyName . ' = ' . $obj->getVar($this->keyName);
647
            }
648
            $sql .= ' WHERE ' . $whereclause;
649
        }
650
651 View Code Duplication
        if (false !== $force) {
652
            $result = $this->db->queryF($sql);
653
        } else {
654
            $result = $this->db->query($sql);
655
        }
656
657
        // Clear cache
658
        $this->forceCacheClean();
659
660
        if (!$result) {
661
            return false;
662
        }
663
        if ($obj->isNew() && !is_array($this->keyName)) {
664
            $obj->assignVar($this->keyName, $this->db->getInsertId());
665
        }
666
667
        return true;
668
    }
669
670
    /**
671
     * Change a value for objects with a certain criteria
672
     *
673
     * @param string $fieldname  Name of the field
674
     * @param string $fieldvalue Value to write
675
     * @param object $criteria   {@link CriteriaElement}
676
     *
677
     * @param  bool  $force
678
     * @return bool
679
     */
680
    public function updateAll($fieldname, $fieldvalue, $criteria = null, $force = false)
681
    {
682
        $set_clause = $fieldname . ' = ';
683
        if (is_numeric($fieldvalue)) {
684
            $set_clause .= $fieldvalue;
685
        } elseif (is_array($fieldvalue)) {
686
            $set_clause .= $this->db->quoteString(implode(',', $fieldvalue));
687
        } else {
688
            $set_clause .= $this->db->quoteString($fieldvalue);
689
        }
690
        $sql = 'UPDATE ' . $this->table . ' SET ' . $set_clause;
691
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
692
            $sql .= ' ' . $criteria->renderWhere();
693
        }
694
        if ($force) {
695
            $result = $this->db->queryF($sql);
696
        } else {
697
            $result = $this->db->query($sql);
698
        }
699
700
        // Clear cache
701
        $this->forceCacheClean();
702
703
        if (!$result) {
704
            return false;
705
        }
706
707
        return true;
708
    }
709
710
    //  check if target object is attempting to use duplicated info
711
712
    /**
713
     * @param         $obj
714
     * @param  string $field
715
     * @param  string $error
716
     * @return bool
717
     */
718
    public function isDuplicated($obj, $field = '', $error = '')
719
    {
720
        if (empty($field)) {
721
            return false;
722
        }
723
        $criteria = new CriteriaCompo();
724
        $criteria->add(new Criteria($field, $obj->getVar($field)));
725
        //  one more condition if target object exisits in database
726
        if (!$obj->isNew()) {
727
            $criteria->add(new Criteria($this->_key, $obj->getVar($this->_key), '!='));
728
        }
729
        if ($this->getCount($criteria)) {
730
            $obj->setErrors($error);
731
732
            return true;
733
        }
734
735
        return false;
736
    }
737
738
    /**
739
     * delete all objects meeting the conditions
740
     *
741
     * @param  object $criteria {@link CriteriaElement} with conditions to meet
742
     * @return bool
743
     */
744
    public function deleteAll($criteria = null)
745
    {
746
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
747
            $sql = 'DELETE FROM ' . $this->table;
748
            $sql .= ' ' . $criteria->renderWhere();
749
            if (!$this->db->queryF($sql)) {
750
                return false;
751
            }
752
            $rows = $this->db->getAffectedRows();
753
754
            // Clear cache
755
            $this->forceCacheClean();
756
757
            return $rows > 0 ? $rows : true;
758
        }
759
760
        return false;
761
    }
762
763
    /**
764
     * Compare two objects and returns, in an array, the differences
765
     *
766
     * @param  XoopsObject $old_object The first object to compare
767
     * @param  XoopsObject $new_object The new object
768
     * @return array       differences    key = fieldname, value = array('old_value', 'new_value')
769
     */
770
    public function compareObjects($old_object, $new_object)
771
    {
772
        $ret       = array();
773
        $vars_name = array_keys($old_object->getVars());
774
        foreach ($vars_name as $one_var) {
775
            if ($old_object->getVar($one_var, 'f') == $new_object->getVar($one_var, 'f')) {
776
            } else {
777
                $ret[$one_var] = array($old_object->getVar($one_var), $new_object->getVar($one_var));
778
            }
779
        }
780
781
        return $ret;
782
    }
783
784
    /**
785
     * Get distincted values of a field in the table
786
     *
787
     * @param  string $field    Field's name
788
     * @param  object $criteria {@link CriteriaElement} conditions to be met
789
     * @param  string $format   Format in wich we want the datas
790
     * @return array  containing the distinct values
791
     */
792
    public function getDistincts($field, $criteria = null, $format = 's')
793
    {
794
        //require_once __DIR__ . '/lite.php';
795
        $limit = $start = 0;
796
        $sql   = 'SELECT ' . $this->keyName . ', ' . $field . ' FROM ' . $this->table;
797
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
798
            $sql   .= ' ' . $criteria->renderWhere();
799
            $limit = $criteria->getLimit();
800
            $start = $criteria->getStart();
801
        }
802
        $sql .= ' GROUP BY ' . $field . ' ORDER BY ' . $field;
803
804
        //$Cache_Lite = new oledrion_Cache_Lite($this->cacheOptions);
805
        $id = $this->_getIdForCache($sql, $start, $limit);
806
        //$cacheData = $Cache_Lite->get($id);
807
        //if ($cacheData === false) {
808
        $result = $this->db->query($sql, $limit, $start);
809
        $ret    = array();
810
        $obj    = new $this->className();
811
        while ($myrow = $this->db->fetchArray($result)) {
812
            $obj->setVar($field, $myrow[$field]);
813
            $ret[$myrow[$this->keyName]] = $obj->getVar($field, $format);
814
        }
815
816
        //$Cache_Lite->save($ret);
817
        return $ret;
818
        //} else {
819
        //return $cacheData;
820
        // }
821
    }
822
823
    /**
824
     * A generic shortcut to getObjects
825
     *
826
     * @author Herve Thouzard - Instant Zero
827
     *
828
     * @param  integer $start   Starting position
829
     * @param  integer $limit   Maximum count of elements to return
830
     * @param  string  $sort    Field to use for the sort
831
     * @param  string  $order   Sort order
832
     * @param  boolean $idAsKey Do we have to return an array whoses keys are the record's ID ?
833
     * @return array   Array of current objects
834
     */
835
    public function getItems($start = 0, $limit = 0, $sort = '', $order = 'ASC', $idAsKey = true)
836
    {
837
        if (trim($order) == '') {
838
            if (isset($this->identifierName) && trim($this->identifierName) != '') {
839
                $order = $this->identifierName;
840
            } else {
841
                $order = $this->keyName;
842
            }
843
        }
844
        $items   = array();
845
        $critere = new Criteria($this->keyName, 0, '<>');
846
        $critere->setLimit($limit);
847
        $critere->setStart($start);
848
        $critere->setSort($sort);
849
        $critere->setOrder($order);
850
        $items = $this->getObjects($critere, $idAsKey);
851
852
        return $items;
853
    }
854
855
    /**
856
     * Forces the cache to be cleaned
857
     */
858
    public function forceCacheClean()
859
    {
860
        //require_once __DIR__ . '/lite.php';
861
        //$Cache_Lite = new oledrion_Cache_Lite($this->cacheOptions);
862
        //$Cache_Lite->clean();
863
    }
864
}
865