Issues (180)

Security Analysis    no request data  

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.

src/Query.php (7 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
 * Fwk
4
 *
5
 * Copyright (c) 2011-2012, Julien Ballestracci <[email protected]>.
6
 * All rights reserved.
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
12
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
13
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
15
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
16
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
17
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
19
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
21
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
22
 * POSSIBILITY OF SUCH DAMAGE.
23
 *
24
 * PHP Version 5.3
25
 *
26
 * @package    Fwk
27
 * @subpackage Db
28
 * @author     Julien Ballestracci <[email protected]>
29
 * @copyright  2011-2012 Julien Ballestracci <[email protected]>
30
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
31
 * @link       http://www.phpfwk.com
32
 */
33
namespace Fwk\Db;
34
35
/**
36
 * Represents an Object-Oriented SQL-like query interface.
37
 *
38
 */
39
class Query extends \ArrayObject
40
{
41
    const TYPE_SELECT   = 'select';
42
    const TYPE_DELETE   = 'delete';
43
    const TYPE_INSERT   = 'insert';
44
    const TYPE_UPDATE   = 'update';
45
46
    const JOIN_INNER    = 'inner';
47
    const JOIN_LEFT     = 'left';
48
49
    const WHERE_AND     = 'and';
50
    const WHERE_OR      = 'or';
51
52
    const FETCH_SPECIAL = 0;
53
    const FETCH_OPT     = 1;
54
55
    protected $fetchMode = self::FETCH_SPECIAL;
56
57
    /**
58
     *
59
     * @var string
60
     */
61
    protected $type;
62
63
    protected $options;
64
65
    /**
66
     *
67
     * @param array $options
68
     *
69
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
70
     */
71
    public function __construct(array $options = array())
72
    {
73
        parent::__construct($options);
74
        $this->setFlags(self::ARRAY_AS_PROPS);
75
    }
76
77
    /**
78
     *
79
     * @param mixed $columns
80
     *
81
     * @return Query
82
     */
83
    public function select($columns = null)
84
    {
85
        $this->type = self::TYPE_SELECT;
86
        $this['select'] = $columns;
87
88
        return $this;
89
    }
90
91
    public function from($table, $alias = null)
92
    {
93
        if (\strpos($table, ' ') !== false) {
94
            list($table, $alias) = explode(' ', $table);
95
        }
96
97
        $this['from']   = trim($table) . ($alias !== null ? ' '. trim($alias) : null);
98
99
        return $this;
100
    }
101
102
    public function setFetchMode($mode)
103
    {
104
        $this->fetchMode     = $mode;
105
106
        return $this;
107
    }
108
109
    public function getFetchMode()
0 ignored issues
show
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
110
    {
111
112
        return $this->fetchMode;
113
    }
114
115
    /**
116
     *
117
     * @param mixed $table
118
     *
119
     * @return Query
120
     */
121
    public function delete($table)
122
    {
123
        $this->type         = self::TYPE_DELETE;
124
        $this['delete']     = (string) $table;
125
126
        return $this;
127
    }
128
129
    /**
130
     *
131
     * @param mixed $table
132
     *
133
     * @return Query
134
     */
135
    public function insert($table)
136
    {
137
        $this->type         = self::TYPE_INSERT;
138
        $this['insert']     = (string) $table;
139
140
        return $this;
141
    }
142
143
    /**
144
     *
145
     * @param mixed $table
146
     *
147
     * @return Query
148
     */
149
    public function update($table)
150
    {
151
        $this->type         = self::TYPE_UPDATE;
152
        $this['update']     = (string) $table;
153
154
        return $this;
155
    }
156
157
    /**
158
     *
159
     * @param  string $condition
160
     * @return Query
161
     */
162
    public function where($condition)
163
    {
164
        $this['where']     = $condition;
165
166
        return $this;
167
    }
168
169
    /**
170
     *
171
     * @param string $condition
172
     *
173
     * @return Query
174
     */
175
    public function andWhere($condition)
176
    {
177
        if(!is_array($this['wheres']))
0 ignored issues
show
Please always use braces to surround the code block of IF statements.
Loading history...
178
                $this['wheres']     = array();
179
180
        $arr    = $this['wheres'];
181
        array_push($arr, array('condition' => $condition, 'type' => self::WHERE_AND));
182
        $this['wheres'] = $arr;
183
184
        return $this;
185
    }
186
187
    /**
188
     *
189
     * @param string $condition
190
     *
191
     * @return Query
192
     */
193
    public function orWhere($condition)
194
    {
195
        if(!is_array($this['wheres']))
0 ignored issues
show
Please always use braces to surround the code block of IF statements.
Loading history...
196
                $this['wheres']     = array();
197
198
        $arr    = $this['wheres'];
199
        array_push($arr, array('condition' => $condition, 'type' => self::WHERE_OR));
200
        $this['wheres'] = $arr;
201
202
        return $this;
203
    }
204
205
    /**
206
     *
207
     * @param mixed $limit
0 ignored issues
show
There is no parameter named $limit. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
208
     *
209
     * @return Query
210
     */
211
    public function limit($max, $offset = null)
212
    {
213
        $this['limit'] = array('first' => $offset, 'max' => $max);
214
215
        return $this;
216
    }
217
218
    /**
219
     *
220
     * @param string $group
221
     *
222
     * @return Query
223
     */
224
    public function groupBy($group)
225
    {
226
        $this['groupBy']   = $group;
227
228
        return $this;
229
    }
230
231
    public function orderBy($column, $order = null)
232
    {
233
        $this['orderBy']    = array('column' => $column, 'order' => $order);
234
235
        return $this;
236
    }
237
238
    /**
239
     *
240
     * @return Query
241
     */
242
    public static function factory()
243
    {
244
        return new Query();
245
    }
246
247
    public function set($key, $value)
248
    {
249
        $vals           = $this['values'];
250
        $vals[$key]     = $value;
251
        $this['values'] = $vals;
252
253
        return $this;
254
    }
255
256
    public function values(array $values)
257
    {
258
        $vals           = $this['values'];
259
        $this['values'] = array_merge((is_array($vals) ? $vals : array()), $values);
260
261
        return $this;
262
    }
263
264
    public function join($table, $localColumn, $foreignColumn = null, $type = Query::JOIN_LEFT, $options = array())
0 ignored issues
show
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
265
    {
266
        if (\strpos($table, ' ') !== false) {
267
            list($columnName, ) = \explode(' ', $table);
268
        } else {
269
            $columnName = $table;
270
        }
271
272
        $opts = array_merge(array(
273
            'column'    => $columnName,
274
            'relation'  => false,
275
            'skipped'   => false,
276
            'reference' => null,
277
            'entity'    => '\stdClass',
278
            'entityListeners' => array()
279
        ), $options);
280
281
        $join = array(
282
            'table'     => $table,
283
            'local'     => $localColumn,
284
            'foreign'   => (is_null($foreignColumn) ? $localColumn : $foreignColumn),
285
            'type'      => $type,
286
            'options'   => $opts
287
        );
288
289
        $joins = $this['joins'];
290
        if(!is_array($joins))
0 ignored issues
show
Please always use braces to surround the code block of IF statements.
Loading history...
291
            $joins = array();
292
293
        array_push($joins, $join);
294
        $this['joins'] = $joins;
295
296
        return $this;
297
    }
298
299
    public function getType()
300
    {
301
        return $this->type;
302
    }
303
304
    /**
305
     *
306
     *
307
     * @param  string $entityClass
308
     * @return Query
309
     */
310
    public function entity($entityClass, array $listeners = array())
311
    {
312
        $this['entity']             = $entityClass;
313
        $this['entityListeners']    = $listeners;
314
315
        return $this;
316
    }
317
318
    /**
319
     * Prevent 'undefined index' errors
320
     *
321
     * @param  string $key
322
     * @return mixed
323
     */
324
    public function offsetGet($key)
325
    {
326
        if(!$this->offsetExists($key)) {
327
            return null;
328
        }
329
330
        return parent::offsetGet($key);
331
    }
332
}
333