Completed
Push — master ( 00e474...9d3fbd )
by Michael
04:26
created

class/PersistableObjectHandler.php (11 issues)

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 http://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');
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
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 $db           {@link XoopsDatabase} object
91
     * @param string $tablename    Name of database table
92
     * @param string $classname    Name of Class, this handler is managing
93
     * @param string $keyname      Name of the property, holding the key
94
     * @param string $idenfierName Name of the property, holding the label
95
     * @param array  $cacheOptions Optional, options for the cache
96
     *
97
     */
98
    public function __construct($db, $tablename, $classname, $keyname, $idenfierName = '', $cacheOptions = null)
99
    {
100
        //include_once dirname(__DIR__) . '/include/common.php';
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
101
        include_once XOOPS_ROOT_PATH . '/modules/oledrion/include/common.php';
102
        //        $this->XoopsObjectHandler($db);
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
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';
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
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';
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
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';
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
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';
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
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';
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
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);
0 ignored issues
show
$id 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...
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
                ) {
629
                    continue;
630
                }
631
                if (isset($notfirst)) {
632
                    $sql .= ',';
633
                }
634
                $sql .= ' ' . $key . ' = ' . $value;
635
                $notfirst = true;
636
            }
637
            if (is_array($this->keyName)) {
638
                $whereclause = '';
639
                $vnb         = count($this->keyName);
640
                for ($i = 0; $i < $vnb; ++$i) {
641
                    if ($i > 0) {
642
                        $whereclause .= ' AND ';
643
                    }
644
                    $whereclause .= $this->keyName[$i] . ' = ' . $obj->getVar($this->keyName[$i]);
645
                }
646
            } else {
647
                $whereclause = $this->keyName . ' = ' . $obj->getVar($this->keyName);
648
            }
649
            $sql .= ' WHERE ' . $whereclause;
650
        }
651
652 View Code Duplication
        if (false !== $force) {
653
            $result = $this->db->queryF($sql);
654
        } else {
655
            $result = $this->db->query($sql);
656
        }
657
658
        // Clear cache
659
        $this->forceCacheClean();
660
661
        if (!$result) {
662
            return false;
663
        }
664
        if ($obj->isNew() && !is_array($this->keyName)) {
665
            $obj->assignVar($this->keyName, $this->db->getInsertId());
666
        }
667
668
        return true;
669
    }
670
671
    /**
672
     * Change a value for objects with a certain criteria
673
     *
674
     * @param string $fieldname  Name of the field
675
     * @param string $fieldvalue Value to write
676
     * @param object $criteria   {@link CriteriaElement}
677
     *
678
     * @param  bool  $force
679
     * @return bool
680
     */
681
    public function updateAll($fieldname, $fieldvalue, $criteria = null, $force = false)
682
    {
683
        $set_clause = $fieldname . ' = ';
684
        if (is_numeric($fieldvalue)) {
685
            $set_clause .= $fieldvalue;
686
        } elseif (is_array($fieldvalue)) {
687
            $set_clause .= $this->db->quoteString(implode(',', $fieldvalue));
688
        } else {
689
            $set_clause .= $this->db->quoteString($fieldvalue);
690
        }
691
        $sql = 'UPDATE ' . $this->table . ' SET ' . $set_clause;
692
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
693
            $sql .= ' ' . $criteria->renderWhere();
694
        }
695
        if ($force) {
696
            $result = $this->db->queryF($sql);
697
        } else {
698
            $result = $this->db->query($sql);
699
        }
700
701
        // Clear cache
702
        $this->forceCacheClean();
703
704
        if (!$result) {
705
            return false;
706
        }
707
708
        return true;
709
    }
710
711
    //  check if target object is attempting to use duplicated info
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';
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
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';
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
861
        //$Cache_Lite = new oledrion_Cache_Lite($this->cacheOptions);
862
        //$Cache_Lite->clean();
863
    }
864
}
865