Issues (733)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

class/object.php (29 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
//  ------------------------------------------------------------------------ //
4
//                XOOPS - PHP Content Management System                      //
5
//                  Copyright (c) 2000-2016 XOOPS.org                        //
6
//                       <http://xoops.org/>                             //
7
//  ------------------------------------------------------------------------ //
8
//  This program is free software; you can redistribute it and/or modify     //
9
//  it under the terms of the GNU General Public License as published by     //
10
//  the Free Software Foundation; either version 2 of the License, or        //
11
//  (at your option) any later version.                                      //
12
//                                                                           //
13
//  You may not change or alter any portion of this comment or credits       //
14
//  of supporting developers from this source code or any supporting         //
15
//  source code which is considered copyrighted (c) material of the          //
16
//  original comment or credit authors.                                      //
17
//                                                                           //
18
//  This program is distributed in the hope that it will be useful,          //
19
//  but WITHOUT ANY WARRANTY; without even the implied warranty of           //
20
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            //
21
//  GNU General Public License for more details.                             //
22
//                                                                           //
23
//  You should have received a copy of the GNU General Public License        //
24
//  along with this program; if not, write to the Free Software              //
25
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA //
26
//  ------------------------------------------------------------------------ //
27
// Author: Kazumi Ono (AKA onokazu)                                          //
28
// URL: http://www.myweb.ne.jp/, http://xoops.org/, http://jp.xoops.org/ //
29
// Project: XOOPS Project                                                    //
30
// ------------------------------------------------------------------------- //
31
32
/**
33
 * Persistable Object Handler class.
34
 * This class is responsible for providing data access mechanisms to the data source
35
 * of derived class objects.
36
 *
37
 * @author    Jan Keller Pedersen <[email protected]> - IDG Danmark A/S <www.idg.dk>
38
 * @copyright copyright (c) 2000-2004 XOOPS.org
39
 * @package   Kernel
40
 */
41
class smartpartner_PersistableObjectHandler extends XoopsObjectHandler
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
42
{
43
    /**#@+
44
     * Information about the class, the handler is managing
45
     *
46
     * @var string
47
     */
48
    public $table;
49
    public $keyName;
50
    public $className;
51
    public $identifierName;
52
53
    /**#@-*/
54
55
    /**
56
     * Constructor - called from child classes
57
     * @param object|XoopsDatabase $db        {@link XoopsDatabase}
58
     *                                        object
59
     * @param string               $tablename Name of database table
60
     * @param string               $classname Name of Class, this handler is managing
61
     * @param string               $keyname   Name of the property, holding the key
62
     *
63
     * @param bool                 $idenfierName
64
     */
65
    public function __construct(XoopsDatabase $db, $tablename, $classname, $keyname, $idenfierName = false)
66
    {
67
        parent::__construct($db);
68
        $this->table     = $db->prefix($tablename);
69
        $this->keyName   = $keyname;
70
        $this->className = $classname;
71
        if ($idenfierName != false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison !== instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
72
            $this->identifierName = $idenfierName;
73
        }
74
    }
75
76
    /**
77
     * create a new user
78
     *
79
     * @param bool $isNew Flag the new objects as "new"?
80
     *
81
     * @return object
82
     */
83
    public function &create($isNew = true)
84
    {
85
        $obj = new $this->className();
86
        if ($isNew === true) {
87
            $obj->setNew();
88
        }
89
90
        return $obj;
91
    }
92
93
    /**
94
     * retrieve an object
95
     *
96
     * @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
97
     * @param  bool  $as_object whether to return an object or an array
98
     * @return mixed reference to the object, FALSE if failed
99
     */
100
    public function get($id, $as_object = true)
101
    {
102
        if (is_array($this->keyName)) {
103
            $criteria = new CriteriaCompo();
104
            for ($i = 0, $iMax = count($this->keyName); $i < $iMax; ++$i) {
105
                $criteria->add(new Criteria($this->keyName[$i], (int)$id[$i]));
106
            }
107
        } else {
108
            $criteria = new Criteria($this->keyName, (int)$id);
109
        }
110
        $criteria->setLimit(1);
111
        $obj_array = $this->getObjects($criteria, false, $as_object);
112
        if (count($obj_array) != 1) {
113
            $obj =& $this->create();
114
115
            return $obj;
116
        }
117
118
        return $obj_array[0];
119
    }
120
121
    /**
122
     * retrieve objects from the database
123
     *
124
     * @param object $criteria  {@link CriteriaElement} conditions to be met
0 ignored issues
show
Should the type for parameter $criteria not be object|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...
125
     * @param bool   $id_as_key use the ID as key for the array?
126
     * @param bool   $as_object return an array of objects?
127
     *
128
     * @return array
129
     */
130
    public function getObjects($criteria = null, $id_as_key = false, $as_object = true)
131
    {
132
        $ret   = array();
133
        $limit = $start = 0;
134
        $sql   = 'SELECT * FROM ' . $this->table;
135 View Code Duplication
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
0 ignored issues
show
Due to PHP Bug #53727, is_subclass_of returns inconsistent results on some PHP versions for interfaces; you could instead use ReflectionClass::implementsInterface.
Loading history...
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
136
            $sql .= ' ' . $criteria->renderWhere();
137
            if ($criteria->getSort() != '') {
138
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
139
            }
140
            $limit = $criteria->getLimit();
141
            $start = $criteria->getStart();
142
        }
143
        $result = $this->db->query($sql, $limit, $start);
144
        if (!$result) {
145
            return $ret;
146
        }
147
148
        return $this->convertResultSet($result, $id_as_key, $as_object);
149
    }
150
151
    /**
152
     * Convert a database resultset to a returnable array
153
     *
154
     * @param object $result    database resultset
155
     * @param bool   $id_as_key - should NOT be used with joint keys
156
     * @param bool   $as_object
157
     *
158
     * @return array
159
     */
160
    public function convertResultSet($result, $id_as_key = false, $as_object = true)
161
    {
162
        $ret = array();
163
        while ($myrow = $this->db->fetchArray($result)) {
164
            $obj =& $this->create(false);
165
            $obj->assignVars($myrow);
166
            if (!$id_as_key) {
167 View Code Duplication
                if ($as_object) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
168
                    $ret[] =& $obj;
169
                } else {
170
                    $row  = array();
171
                    $vars = $obj->getVars();
172
                    foreach (array_keys($vars) as $i) {
173
                        $row[$i] = $obj->getVar($i);
174
                    }
175
                    $ret[] = $row;
176
                }
177
            } else {
178
                if ($as_object) {
179
                    $ret[$myrow[$this->keyName]] =& $obj;
180 View Code Duplication
                } else {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
181
                    $row  = array();
182
                    $vars = $obj->getVars();
183
                    foreach (array_keys($vars) as $i) {
184
                        $row[$i] = $obj->getVar($i);
185
                    }
186
                    $ret[$myrow[$this->keyName]] = $row;
187
                }
188
            }
189
            unset($obj);
190
        }
191
192
        return $ret;
193
    }
194
195
    /**
196
     * Retrieve a list of objects as arrays - DON'T USE WITH JOINT KEYS
197
     *
198
     * @param CriteriaElement $criteria {@link CriteriaElement} conditions to be met
0 ignored issues
show
Should the type for parameter $criteria not be null|CriteriaElement?

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...
199
     * @param int             $limit    Max number of objects to fetch
200
     * @param int             $start    Which record to start at
201
     *
202
     * @return array
203
     */
204
    public function getList(CriteriaElement $criteria = null, $limit = 0, $start = 0)
205
    {
206
        $ret = array();
207
        if ($criteria == null) {
208
            $criteria = new CriteriaCompo();
209
        }
210
211
        if ($criteria->getSort() == '') {
212
            $criteria->setSort($this->identifierName);
213
        }
214
215
        $sql = 'SELECT ' . $this->keyName;
216
        if (!empty($this->identifierName)) {
217
            $sql .= ', ' . $this->identifierName;
218
        }
219
        $sql .= ' FROM ' . $this->table;
220 View Code Duplication
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
0 ignored issues
show
Due to PHP Bug #53727, is_subclass_of returns inconsistent results on some PHP versions for interfaces; you could instead use ReflectionClass::implementsInterface.
Loading history...
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
221
            $sql .= ' ' . $criteria->renderWhere();
222
            if ($criteria->getSort() != '') {
223
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
224
            }
225
            $limit = $criteria->getLimit();
226
            $start = $criteria->getStart();
227
        }
228
        $result = $this->db->query($sql, $limit, $start);
229
        if (!$result) {
230
            return $ret;
231
        }
232
233
        $myts = MyTextSanitizer::getInstance();
234
        while ($myrow = $this->db->fetchArray($result)) {
235
            //identifiers should be textboxes, so sanitize them like that
236
            $ret[$myrow[$this->keyName]] = empty($this->identifierName) ? 1 : $myts->htmlSpecialChars($myrow[$this->identifierName]);
237
        }
238
239
        return $ret;
240
    }
241
242
    /**
243
     * count objects matching a condition
244
     *
245
     * @param  object $criteria {@link CriteriaElement} to match
0 ignored issues
show
Should the type for parameter $criteria not be object|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...
246
     * @return int    count of objects
247
     */
248
    public function getCount($criteria = null)
249
    {
250
        $field   = '';
251
        $groupby = false;
252
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
0 ignored issues
show
Due to PHP Bug #53727, is_subclass_of returns inconsistent results on some PHP versions for interfaces; you could instead use ReflectionClass::implementsInterface.
Loading history...
253
            if ($criteria->groupby != '') {
254
                $groupby = true;
255
                $field   = $criteria->groupby . ', '; //Not entirely secure unless you KNOW that no criteria's groupby clause is going to be mis-used
256
            }
257
        }
258
        $sql = 'SELECT ' . $field . 'COUNT(*) FROM ' . $this->table;
259 View Code Duplication
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
0 ignored issues
show
Due to PHP Bug #53727, is_subclass_of returns inconsistent results on some PHP versions for interfaces; you could instead use ReflectionClass::implementsInterface.
Loading history...
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
260
            $sql .= ' ' . $criteria->renderWhere();
261
            if ($criteria->groupby != '') {
262
                $sql .= $criteria->getGroupby();
263
            }
264
        }
265
        $result = $this->db->query($sql);
266
        if (!$result) {
267
            return 0;
268
        }
269
        if ($groupby == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
270
            list($count) = $this->db->fetchRow($result);
271
272
            return $count;
273
        } else {
274
            $ret = array();
275
            while (list($id, $count) = $this->db->fetchRow($result)) {
276
                $ret[$id] = $count;
277
            }
278
279
            return $ret;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $ret; (array) is incompatible with the return type documented by smartpartner_PersistableObjectHandler::getCount of type integer.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
280
        }
281
    }
282
283
    /**
284
     * delete an object from the database
285
     *
286
     * @param  XoopsObject $obj reference to the object to delete
287
     * @param  bool        $force
288
     * @return bool        FALSE if failed.
289
     */
290
    public function delete(XoopsObject $obj, $force = false)
291
    {
292
        if (is_array($this->keyName)) {
293
            $clause = array();
294
            for ($i = 0, $iMax = count($this->keyName); $i < $iMax; ++$i) {
295
                $clause[] = $this->keyName[$i] . ' = ' . $obj->getVar($this->keyName[$i]);
296
            }
297
            $whereclause = implode(' AND ', $clause);
298
        } else {
299
            $whereclause = $this->keyName . ' = ' . $obj->getVar($this->keyName);
300
        }
301
        $sql = 'DELETE FROM ' . $this->table . ' WHERE ' . $whereclause;
302 View Code Duplication
        if (false != $force) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison !== instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
303
            $result = $this->db->queryF($sql);
304
        } else {
305
            $result = $this->db->query($sql);
306
        }
307
        if (!$result) {
308
            return false;
309
        }
310
311
        return true;
312
    }
313
314
    /**
315
     * insert a new object in the database
316
     *
317
     * @param  XoopsObject $obj         reference to the object
318
     * @param  bool        $force       whether to force the query execution despite security settings
319
     * @param  bool        $checkObject check if the object is dirty and clean the attributes
320
     * @return bool        FALSE if failed, TRUE if already present and unchanged or successful
321
     */
322
323
    public function insert(XoopsObject $obj, $force = false, $checkObject = true)
324
    {
325
        if ($checkObject != false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison !== instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
326
            if (!is_object($obj)) {
327
                return false;
328
            }
329
            /**
330
             * @TODO: Change to if (!(class_exists($this->className) && $obj instanceof $this->className)) when going fully PHP5
331
             */
332
            if (!is_a($obj, $this->className)) {
333
                $obj->setErrors(get_class($obj) . ' Differs from ' . $this->className);
334
335
                return false;
336
            }
337
            if (!$obj->isDirty()) {
338
                $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
339
340
                return true;
341
            }
342
        }
343
        if (!$obj->cleanVars()) {
344
            return false;
345
        }
346
347
        foreach ($obj->cleanVars as $k => $v) {
348
            if ($obj->vars[$k]['data_type'] == XOBJ_DTYPE_INT) {
349
                $cleanvars[$k] = (int)$v;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$cleanvars was never initialized. Although not strictly required by PHP, it is generally a good practice to add $cleanvars = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
350
            } elseif (is_array($v)) {
351
                $cleanvars[$k] = $this->db->quoteString(implode(',', $v));
0 ignored issues
show
The variable $cleanvars does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
352
            } else {
353
                $cleanvars[$k] = $this->db->quoteString($v);
354
            }
355
        }
356
        if ($obj->isNew()) {
357
            if (!is_array($this->keyName)) {
358
                if ($cleanvars[$this->keyName] < 1) {
359
                    $cleanvars[$this->keyName] = $this->db->genId($this->table . '_' . $this->keyName . '_seq');
360
                }
361
            }
362
            $sql = 'INSERT INTO ' . $this->table . ' (' . implode(',', array_keys($cleanvars)) . ') VALUES (' . implode(',', array_values($cleanvars)) . ')';
363
        } else {
364
            $sql = 'UPDATE ' . $this->table . ' SET';
365
            foreach ($cleanvars as $key => $value) {
366
                if ((!is_array($this->keyName) && $key == $this->keyName) || (is_array($this->keyName) && in_array($key, $this->keyName))) {
367
                    continue;
368
                }
369
                if (isset($notfirst)) {
370
                    $sql .= ',';
371
                }
372
                $sql .= ' ' . $key . ' = ' . $value;
373
                $notfirst = true;
374
            }
375
            if (is_array($this->keyName)) {
376
                $whereclause = '';
377
                for ($i = 0, $iMax = count($this->keyName); $i < $iMax; ++$i) {
378
                    if ($i > 0) {
379
                        $whereclause .= ' AND ';
380
                    }
381
                    $whereclause .= $this->keyName[$i] . ' = ' . $obj->getVar($this->keyName[$i]);
382
                }
383
            } else {
384
                $whereclause = $this->keyName . ' = ' . $obj->getVar($this->keyName);
385
            }
386
            $sql .= ' WHERE ' . $whereclause;
387
        }
388 View Code Duplication
        if (false != $force) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison !== instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
389
            $result = $this->db->queryF($sql);
390
        } else {
391
            $result = $this->db->query($sql);
392
        }
393
        if (!$result) {
394
            return false;
395
        }
396
        if ($obj->isNew() && !is_array($this->keyName)) {
397
            $obj->assignVar($this->keyName, $this->db->getInsertId());
398
        }
399
400
        return true;
401
    }
402
403
    /**
404
     * Change a value for objects with a certain criteria
405
     *
406
     * @param string $fieldname  Name of the field
407
     * @param string $fieldvalue Value to write
408
     * @param object $criteria   {@link CriteriaElement}
0 ignored issues
show
Should the type for parameter $criteria not be object|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...
409
     *
410
     * @param  bool  $force
411
     * @return bool
412
     */
413
    public function updateAll($fieldname, $fieldvalue, $criteria = null, $force = false)
414
    {
415
        $set_clause = $fieldname . ' = ';
416
        if (is_numeric($fieldvalue)) {
417
            $set_clause .= $fieldvalue;
418
        } elseif (is_array($fieldvalue)) {
419
            $set_clause .= $this->db->quoteString(implode(',', $fieldvalue));
420
        } else {
421
            $set_clause .= $this->db->quoteString($fieldvalue);
422
        }
423
        $sql = 'UPDATE ' . $this->table . ' SET ' . $set_clause;
424
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
0 ignored issues
show
Due to PHP Bug #53727, is_subclass_of returns inconsistent results on some PHP versions for interfaces; you could instead use ReflectionClass::implementsInterface.
Loading history...
425
            $sql .= ' ' . $criteria->renderWhere();
426
        }
427 View Code Duplication
        if (false != $force) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison !== instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
428
            $result = $this->db->queryF($sql);
429
        } else {
430
            $result = $this->db->query($sql);
431
        }
432
        if (!$result) {
433
            return false;
434
        }
435
436
        return true;
437
    }
438
439
    /**
440
     * delete all objects meeting the conditions
441
     *
442
     * @param  object $criteria {@link CriteriaElement} with conditions to meet
443
     * @return bool
0 ignored issues
show
Should the type for parameter $criteria not be object|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...
444
     */
445
446
    public function deleteAll($criteria = null)
447
    {
448
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
0 ignored issues
show
Due to PHP Bug #53727, is_subclass_of returns inconsistent results on some PHP versions for interfaces; you could instead use ReflectionClass::implementsInterface.
Loading history...
449
            $sql = 'DELETE FROM ' . $this->table;
450
            $sql .= ' ' . $criteria->renderWhere();
451
            if (!$this->db->query($sql)) {
452
                return false;
453
            }
454
            $rows = $this->db->getAffectedRows();
455
456
            return $rows > 0 ? $rows : true;
457
        }
458
459
        return false;
460
    }
461
}
462