Completed
Push — test ( 719145...2ec062 )
by Temitope
02:38
created

DatabaseHandler::getColumnNames()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 22
rs 9.2
cc 3
eloc 12
nc 4
nop 2
1
<?php
2
3
/**
4
 * @package  Laztopaz\potato-ORM
5
 * @author   Temitope Olotin <[email protected]>
6
 * @license  <https://opensource.org/license/MIT> MIT
7
 */
8
9
namespace Laztopaz\potatoORM;
10
11
use PDO;
12
use Laztopaz\potatoORM\DatabaseHelper;
13
use Laztopaz\potatoORM\TableFieldUndefinedException;
14
use Laztopaz\potatoORM\EmptyArrayException;
15
16
class DatabaseHandler {
17
18
	private $tableFields;
0 ignored issues
show
Unused Code introduced by
The property $tableFields is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
19
	private $dbHelperInstance;
0 ignored issues
show
Unused Code introduced by
The property $dbHelperInstance is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
20
	private $dbConnection;
21
	private $model;
22
23
	/**
24
	 * This is a constructor; a default method  that will be called automatically during class instantiation
25
	 */
26
	public function __construct($modelClassName, $dbConn = Null)
27
	{
28
		if (is_null($dbConn)) {
29
			$this->dbConnection = new DatabaseConnection();
30
		} else {
31
			$this->dbConnection = $dbConn;
32
			$this->model = $modelClassName;
33
		}
34
	}
35
36
	/**
37
	 * This method create a record and store it in a table row
38
	 * @params associative array, string tablename
39
	 * @return boolean true or false
40
	 */
41
	public function create($associative1DArray, $tableName, $dbConn = Null)
42
	{
43
		$unexpectedFields = self::checkIfMagicSetterContainsIsSameAsClassModel($this->getColumnNames($this->model, $this->dbConnection),$associative1DArray);
44
45
		if (count($unexpectedFields) > 0)
46
		{
47
			throw TableFieldUndefinedException::fieldsNotDefinedException($unexpectedFields,"needs to be created as table field");
48
		}
49
50
		unset($this->getColumnNames($this->model, $this->dbConnection)[0]);
51
52
		if (is_null($dbConn)) {
53
			$dbConn = $this->dbConnection;
54
		}
55
56
		$insertQuery = 'INSERT INTO '.$tableName;
57
58
		$TableValues = implode(',',array_keys($associative1DArray));
59
60
		foreach ($associative1DArray as $field => $value) {
61
62
			$FormValues[] = "'".trim(addslashes($value))."'";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$FormValues was never initialized. Although not strictly required by PHP, it is generally a good practice to add $FormValues = 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...
63
		}
64
		$splittedTableValues = implode(',', $FormValues);
0 ignored issues
show
Bug introduced by
The variable $FormValues 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...
65
66
		$insertQuery.= ' ('.$TableValues.')';
67
68
		$insertQuery.= ' VALUES ('.$splittedTableValues.')';
69
70
		$executeQuery = $dbConn->exec($insertQuery);
71
72
		return $executeQuery ? : false;
73
	}
74
75
	/*
76
	 * This method updates any table by supplying 3 parameter
77
	 * @params: $updateParams, $tableName, $associative1DArray
78
	 * @return boolean true or false
79
	 */
80
	public function update(array $updateParams, $tableName, $associative1DArray, $dbConn = Null)
81
	{
82
		$sql = "";
83
84
		if (is_null($dbConn)) {
85
86
			$dbConn = $this->dbConnection;
87
		}
88
89
		$updateSql = "UPDATE `$tableName` SET ";
90
91
		unset($associative1DArray['id']);
92
93
		$unexpectedFields = self::checkIfMagicSetterContainsIsSameAsClassModel($this->getColumnNames($this->model, $this->dbConnection),$associative1DArray);
94
95
		if (count($unexpectedFields) > 0) {
96
97
			throw TableFieldUndefinedException::fieldsNotDefinedException($unexpectedFields,"needs to be created as table field");
98
		}
99
100
101
		foreach($associative1DArray as $field => $value)
102
		{
103
			$sql .= "`$field` = '$value'".",";
104
		}
105
106
		$updateSql .= $this->prepareUpdateQuery($sql);
107
108
		foreach ($updateParams as $key => $val) {
109
110
			$updateSql .= " WHERE $key = $val";
111
		}
112
113
		$stmt = $dbConn->prepare($updateSql);
114
115
		$boolResponse = $stmt->execute();
116
117
		return $boolResponse ?  : false;
118
	}
119
120
	/**
121
	 * This method retrieves record from a table
122
	 * @params int id, string tableName
123
	 * @return array
124
	 */
125
	public static function read($id, $tableName, $dbConn = Null)
126
	{
127
		$tableData = array();
128
129
		if (is_null($dbConn)) {
130
131
			$dbConn = new DatabaseConnection();
132
133
		}
134
135
		$sql = $id  ? 'SELECT * FROM '.$tableName.' WHERE id = '.$id : 'SELECT * FROM '.$tableName;
136
137
		try {
138
			$stmt = $dbConn->prepare($sql);
139
			$stmt->bindValue(':table', $tableName);
140
			$stmt->bindValue(':id', $id);
141
			$stmt->execute();
142
143
		} catch (PDOException $e) {
0 ignored issues
show
Bug introduced by
The class Laztopaz\potatoORM\PDOException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
144
145
			return  $e->getMessage();
146
		}
147
		$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
148
149
		foreach($results as $result) {
150
151
			array_push($tableData, $result);
152
		}
153
154
		return $tableData;
155
	}
156
157
	/**
158
	 * This method deletes a record  from a table row
159
	 * @params int id, string tableName
160
	 * @return boolean true or false
161
	 */
162
	public static function delete($id, $tableName, $dbConn = Null)
163
	{
164
		if (is_null($dbConn)) {
165
166
			$dbConn = new DatabaseConnection();
167
168
		}
169
170
		$sql = 'DELETE FROM '.$tableName.' WHERE id = '.$id;
171
172
		$boolResponse = $dbConn->exec($sql);
173
174
		return $boolResponse ? : false;
175
	}
176
177
	/**
178
	 * This method checks if the magic setters array is the same as the table columns
179
	 * @param array $tableColumn
180
	 * @param array $userSetterArray
181
	 * @return array $unexpectedFields
182
	 */
183
	public static function checkIfMagicSetterContainsIsSameAsClassModel(array $tableColumn, array $userSetterArray)
184
	{
185
		$unexpectedFields = [];
186
187
		foreach ($userSetterArray as $key => $val)
188
		{
189
			if (!in_array($key,$tableColumn)) {
190
191
				$unexpectedFields[] = $key;
192
			}
193
		}
194
195
		return $unexpectedFields;
196
	}
197
198
	/**
199
	 * This method returns sql query
200
	 * @param $sql
201
	 * @return string
202
	 */
203
	public function prepareUpdateQuery($sql)
204
	{
205
		$splittedQuery = explode(",",$sql);
206
207
		array_pop($splittedQuery);
208
209
		$mergeData = implode(",",$splittedQuery);
210
211
		return $mergeData;
212
	}
213
214
	/**
215
	 * @param array $params
216
	 * @param $tableName
217
	 * @param $dbConn
218
	 * @return bool
219
	 * @throws EmptyArrayException
220
	 */
221
	public function findAndWhere($params, $tableName, $dbConn)
222
	{
223
		if (is_null($dbConn)) {
224
225
			$dbConn = $this->dbConnection;
226
		}
227
228
		if (is_array($params) && !empty($params)) {
229
230
			$sql = "SELECT * FROM ".$tableName;
231
232
			foreach ($params as $key => $val) {
233
234
				$sql .= " WHERE $key = $val";
235
			}
236
237
			$statement = $dbConn->prepare($sql);
238
239
			$statement->execute();
240
241
			$returnedRowNumbers = $statement->rowCount();
242
243
			return $returnedRowNumbers  ? true : false;
244
		}
245
246
		throw EmptyArrayException::checkEmptyArrayException("Array Expected: parameter passed to this function is not an array");
247
	}
248
249
	/**
250
	 * This method returns column fields of a particular table
251
	 * @param $table
252
	 * @param $conn
253
	 * @return array
254
	 */
255
	public function getColumnNames($table, $dbConn = Null) {
256
257
		$tableFields = [];
258
259
		if (is_null($dbConn)) {
260
			$dbConn = $this->dbConnection;
261
		}
262
		$sql = "SHOW COLUMNS FROM ".$table;
263
264
		$stmt = $dbConn->prepare($sql);
265
		$stmt->bindValue(':table', $table, PDO::PARAM_STR);
266
		$stmt->execute();
267
268
		$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
269
270
		foreach($results as $result) {
271
272
			array_push($tableFields, $result['Field']);
273
		}
274
			return $tableFields;
275
276
		}
277
278
279
}
280