Completed
Push — master ( fa85af...17ec4b )
by Adeniyi
8s
created

DatabaseQuery::stripclassName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 1
eloc 4
nc 1
nop 0
1
<?php
2
/**
3
 * This class handles building sql query statement and check
4
 * that the table exist in the database.
5
 *
6
 * @package Ibonly\PotatoORM\DatabaseQuery
7
 * @author  Ibraheem ADENIYI <[email protected]>
8
 * @license MIT <https://opensource.org/licenses/MIT>
9
 */
10
11
namespace Ibonly\PotatoORM;
12
13
use PDOException;
14
use Ibonly\PotatoORM\DataNotFoundException;
15
use Ibonly\PotatoORM\DatabaseQueryInterface;
16
use Ibonly\PotatoORM\ColumnNotExistExeption;
17
use Ibonly\PotatoORM\InvalidConnectionException;
18
use Ibonly\PotatoORM\TableDoesNotExistException;
19
20
class DatabaseQuery implements DatabaseQueryInterface
21
{
22
    //Inject the inflector trait, file upload trait
23
    use Inflector, Upload;
24
25
    /**
26
     * connect Setup database connection
27
     */
28
    protected static function connect()
29
    {
30
        return new DBConfig();
31
    }
32
33
    /**
34
     * stripclassName()
35
     *
36
     * @return string
37
     */
38
    public static function stripclassName()
39
    {
40
        $className = strtolower(get_called_class());
41
        $nameOfClass = explode("\\", $className);
42
43
        return end($nameOfClass);
44
    }
45
46
    /**
47
     * Get the table name if defined in the model
48
     * 
49
     * @return string
50
     */
51
    public function tableName()
52
    {
53
        return (isset($this->table)) ? $this->table : null;
0 ignored issues
show
Bug introduced by
The property table does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
54
    }
55
56
    /**
57
     * Get the fields to be fillables defined in the model
58
     * 
59
     * @return string
60
     */
61
    public function fields()
62
    {
63
        if (isset($this->fillables)) {
64
            $this->output = (sizeof($this->fillables) > 0) ? implode(", ", $this->fillables) : '*';
0 ignored issues
show
Bug introduced by
The property output does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
Bug introduced by
The property fillables does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
65
        } else {
66
            $this->output = '*';
67
        }
68
69
        return $this->output;
70
    }
71
72
    /**
73
     * getClassName()
74
     *
75
     * @return string
76
     */
77
    public function getClassName()
78
    {
79
        return ($this->tableName() === null) ? self::pluralize(self::stripclassName()) : $this->tableName();
80
    }
81
82
    /**
83
     * getTableName()
84
     *
85
     * @return string
86
     */
87
    protected function getTableName($connection)
88
    {
89
        return DatabaseQuery::checkTableName($this->getClassName(), $connection);
90
    }
91
92
93
    /**
94
     * sanitize(argument) Removes unwanted characters
95
     *
96
     * @param  $value
97
     *
98
     * @return  string
99
     */
100
    protected static function sanitize($value)
101
    {
102
        $value = trim($value);
103
        $value = htmlentities($value);
104
        return $value;
105
    }
106
107
    /**
108
     * checkConnection
109
     *
110
     * @param  $con
111
     *
112
     * @return string
113
     */
114
    protected static function checkConnection($con)
115
    {
116
        return ($con === null) ? self::connect() : $con;
117
    }
118
119
    /**
120
     * checkTableExist Check if table already in the database
121
     *
122
     * @param  $tablename
123
     * @param  $con
124
     *
125
     * @return bool
126
     */
127 View Code Duplication
    public function checkTableExist($table, $con=NULL)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
128
    {
129
        $connection = $this->checkConnection($con);
130
        $query = $connection->query("SELECT 1 FROM {$table} LIMIT 1");
0 ignored issues
show
Bug introduced by
The method query cannot be called on $connection (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
131
        if($query !== false)
132
        {
133
            return true;
134
        }
135
    }
136
137
    /**
138
     * checkTableName Return the table name
139
     *
140
     * @param  $tablename
141
     * @param  $con
142
     *
143
     * @return string
144
     */
145 View Code Duplication
    protected static function checkTableName($tableName, $con=NULL)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
146
    {
147
        $connection = self::checkConnection($con);
148
149
        $query = $connection->query("SELECT 1 FROM {$tableName} LIMIT 1");
0 ignored issues
show
Bug introduced by
The method query cannot be called on $connection (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
150
        if($query !== false)
151
        {
152
            return $tableName;
153
        }
154
        throw new TableDoesNotExistException();
155
    }
156
157
    /**
158
     * checkColumn Check if column exist in table
159
     *
160
     * @param  $tableName
161
     * @param  $columnName
162
     * @param  $con
163
     *
164
     * @return string
165
     */
166
    protected static function checkColumn($tableName, $columnName, $con=NULL)
167
    {
168
        $connection = self::checkConnection($con);
169
170
            $result = $connection->prepare("SELECT {$columnName} FROM {$tableName}");
0 ignored issues
show
Bug introduced by
The method prepare cannot be called on $connection (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
171
            $result->execute();
172
            if (! $result->columnCount())
173
            {
174
                throw new ColumnNotExistExeption();
175
            }
176
            return $columnName;
177
    }
178
179
    /**
180
     * Get the variables declared in the Model
181
     * 
182
     * @return Array
183
     */
184
    protected static function getParentClassVar()
185
    {
186
        return get_class_vars(get_called_class());
187
    }
188
189
    /**
190
     * Get the difference in variables between model and column definition
191
     * 
192
     * @param  $getClassVars
193
     * 
194
     * @return Array
195
     */
196
    protected static function getColumns($getClassVars)
197
    {
198
        return array_diff($getClassVars, self::getParentClassVar());
199
    }
200
201
    /**
202
     * buildColumn  Build the column name
203
     *
204
     * @param  $data
205
     *
206
     * @return string
207
     */
208
    protected static function buildColumn($getClassVars)
209
    {
210
        $counter = 0;
211
        $insertQuery = "";
212
        $columnNames = self::getColumns($getClassVars);
213
        $arraySize = count($columnNames);
214
215
        foreach ($columnNames as $key => $value)
216
        {
217
            $counter++;
218
            $insertQuery .= self::sanitize($key);
219
            if($arraySize > $counter)
220
                $insertQuery .= ", ";
221
        }
222
223
        return $insertQuery;
224
    }
225
226
    /**
227
     * buildValues  Build the column values
228
     *
229
     * @param  $data
230
     *
231
     * @return string
232
     */
233 View Code Duplication
    protected static function buildValues($getClassVars)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
234
    {
235
        $counter = 0;
236
        $insertQuery = "";
237
        $columnNames = self::getColumns($getClassVars);
238
        $arraySize = count($columnNames);
239
240
        foreach ($columnNames as $key => $value)
241
        {
242
            $counter++;
243
            $insertQuery .= "'".self::sanitize($value) ."'";
244
            if($arraySize > $counter)
245
                $insertQuery .= ", ";
246
        }
247
        return $insertQuery;
248
    }
249
250
    /**
251
     * buildClause  Build the clause value
252
     *
253
     * @param  $data
254
     *
255
     * @return string
256
     */
257 View Code Duplication
    protected static function buildClause($tableName, $data)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
258
    {
259
        $counter = 0;
260
        $updateQuery = "";
261
        $arraySize = count($data);
262
263
        foreach ($data as $key => $value)
264
        {
265
            $counter++;
266
            $columnName = self::checkColumn($tableName, self::sanitize($key));
267
            $updateQuery .= $columnName ." = '".self::sanitize($value)."'";
268
            if ($arraySize > $counter)
269
            {
270
                $updateQuery .= ", ";
271
            }
272
        }
273
        return $updateQuery;
274
    }
275
276
    /**
277
     * selectAllQuery
278
     *
279
     * @return string
280
     */
281
    public static function selectAllQuery($tableName, $field)
282
    {
283
        return "SELE3CT {$field} FROM {$tableName}";
284
    }
285
286
    /**
287
     * whereAndClause
288
     *
289
     * @return string
290
     */
291
    public static function whereAndClause($tableName, $data, $condition)
292
    {
293
        $where = "";
294
        $counter = 0;
295
        $arraySize = count($data);
296
297
        if ($data !== null) {
298
            foreach ($data as $key => $value)
299
            {
300
                $counter++;
301
                $columnName = self::checkColumn($tableName, self::sanitize($key));
302
                $where .= $tableName.'.'.$columnName ." = '".self::sanitize($value)."'";
303
                if ($arraySize > $counter)
304
                {
305
                    $where .= " " . $condition . " ";
306
                }
307
            }
308
        } else {
309
            $where = "";
310
        }
311
312
        return $where;
313
    }
314
315
    /**
316
     * selectQuery
317
     *
318
     * @return string
319
     */
320
    public static function selectQuery($tableName, $fields, $data, $condition, $connection)
321
    {
322
        $query = "";
0 ignored issues
show
Unused Code introduced by
$query 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...
323
        try
324
        {
325
            $arraySize = count($data);
326
            if($arraySize > 1 && $condition == NULL)
327
            {
328
                $query = "Please Supply the condition";
329
            }
330
            else
331
            {
332
                $columnName = self::whereAndClause($tableName, $data, $condition);
333
                $query =  "SELECT $fields FROM $tableName WHERE $columnName";
334
            }
335
        } catch (PDOException $e) {
336
            $query = $e->getMessage();
337
        }
338
339
        return $query;
340
    }
341
342
    /**
343
     * insertQuery
344
     *
345
     * @return string
346
     */
347
    public function insertQuery($tableName)
348
    {
349
        $data = (array)$this;
350
        array_shift($data);
351
352
        $columnNames = self::buildColumn($data);
353
        $values = self::buildValues($data);
354
355
        return "INSERT INTO $tableName ({$columnNames}) VALUES ({$values})";
356
    }
357
358
    /**
359
     * updateQuery
360
     *
361
     * @return string
362
     */
363
    public function updateQuery($tableName)
364
    {
365
        $data = (array) $this;
366
        $data = array_slice($data, 2);
367
368
        $values = self::buildClause($tableName, $data);
369
        $updateQuery = "UPDATE $tableName SET {$values} WHERE id = ". self::sanitize($this->id);
0 ignored issues
show
Bug introduced by
The property id does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
370
371
        return $updateQuery;
372
    }
373
374
    /**
375
     * query($query, $dbCOnnection)
376
     * Raw sql query
377
     *
378
     * @return object
379
     */
380 View Code Duplication
    public function query($query, $con = NULL)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
381
    {
382
        $connection = self::checkConnection($con);
383
384
        $query = $connection->prepare($query);
0 ignored issues
show
Bug introduced by
The method prepare cannot be called on $connection (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
385
        $query->execute();
386
        if ($query->rowCount())
387
        {
388
            return new GetData($query->fetchAll($connection::FETCH_ASSOC));
389
        }
390
        throw new DataNotFoundException();
391
    }
392
}