Completed
Push — test ( dd676d...2ee69c )
by Temitope
02:42
created

DatabaseHandler::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 0 Features 3
Metric Value
c 7
b 0
f 3
dl 0
loc 13
rs 9.4285
cc 2
eloc 6
nc 2
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
		//$this->dbHelperInstance = new DatabaseHelper($this->dbConnection);
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% 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...
36
37
		//$this->tableFields = $this->dbHelperInstance->getColumnNames($modelClassName, $dbConn);
0 ignored issues
show
Unused Code Comprehensibility introduced by
62% 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...
38
	}
39
40
	/**
41
	 * This method create a record and store it in a table row
42
	 * @params associative array, string tablename
43
	 * @return boolean true or false
44
	 */
45
	public function create($associative1DArray, $tableName, $dbConn = Null)
46
	{
47
		$unexpectedFields = self::checkIfMagicSetterContainsIsSameAsClassModel($this->getColumnNames($this->model, $this->dbConnection),$associative1DArray);
0 ignored issues
show
Bug introduced by
It seems like $this->getColumnNames($t...l, $this->dbConnection) targeting Laztopaz\potatoORM\Datab...ndler::getColumnNames() can also be of type null; however, Laztopaz\potatoORM\Datab...insIsSameAsClassModel() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
48
49
		if (count($unexpectedFields) > 0)
50
		{
51
			throw TableFieldUndefinedException::fieldsNotDefinedException($unexpectedFields,"needs to be created as table field");
52
		}
53
54
		unset($this->getColumnNames($this->model, $this->dbConnection)[0]);
55
56
		if (is_null($dbConn)) {
57
			$dbConn = $this->dbConnection;
58
		}
59
60
		$insertQuery = 'INSERT INTO '.$tableName;
61
62
		$TableValues = implode(',',array_keys($associative1DArray));
63
64
		foreach ($associative1DArray as $field => $value) {
65
66
			$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...
67
		}
68
		$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...
69
70
		$insertQuery.= ' ('.$TableValues.')';
71
72
		$insertQuery.= ' VALUES ('.$splittedTableValues.')';
73
74
		$executeQuery = $dbConn->exec($insertQuery);
75
76
		return $executeQuery ? : false;
77
	}
78
79
	/*
80
	 * This method updates any table by supplying 3 parameter
81
	 * @params: $updateParams, $tableName, $associative1DArray
82
	 * @return boolean true or false
83
	 */
84
	public function update(array $updateParams, $tableName, $associative1DArray, $dbConn = Null)
85
	{
86
		$sql = "";
87
88
		if (is_null($dbConn)) {
89
90
			$dbConn = $this->dbConnection;
91
		}
92
93
		$updateSql = "UPDATE `$tableName` SET ";
94
95
		unset($associative1DArray['id']);
96
97
		$unexpectedFields = self::checkIfMagicSetterContainsIsSameAsClassModel($this->getColumnNames($this->model, $this->dbConnection),$associative1DArray);
0 ignored issues
show
Bug introduced by
It seems like $this->getColumnNames($t...l, $this->dbConnection) targeting Laztopaz\potatoORM\Datab...ndler::getColumnNames() can also be of type null; however, Laztopaz\potatoORM\Datab...insIsSameAsClassModel() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
98
99
		if (count($unexpectedFields) > 0) {
100
101
			throw TableFieldUndefinedException::fieldsNotDefinedException($unexpectedFields,"needs to be created as table field");
102
		}
103
104
105
		foreach($associative1DArray as $field => $value)
106
		{
107
			$sql .= "`$field` = '$value'".",";
108
		}
109
110
		$updateSql .= $this->prepareUpdateQuery($sql);
111
112
		foreach ($updateParams as $key => $val) {
113
114
			$updateSql .= " WHERE $key = $val";
115
		}
116
117
		$stmt = $dbConn->prepare($updateSql);
118
119
		$boolResponse = $stmt->execute();
120
121
		return $boolResponse ?  : false;
122
	}
123
124
	/**
125
	 * This method retrieves record from a table
126
	 * @params int id, string tableName
127
	 * @return array
128
	 */
129
	public static function read($id, $tableName, $dbConn = Null)
130
	{
131
		$tableData = array();
132
133
		if (is_null($dbConn)) {
134
135
			$dbConn = new DatabaseConnection();
136
137
		}
138
139
		$sql = $id  ? 'SELECT * FROM '.$tableName.' WHERE id = '.$id : 'SELECT * FROM '.$tableName;
140
141
		try {
142
			$stmt = $dbConn->prepare($sql);
143
			$stmt->bindValue(':table', $tableName);
144
			$stmt->bindValue(':id', $id);
145
			$stmt->execute();
146
147
		} 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...
148
149
			return  $e->getMessage();
150
		}
151
		$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
152
153
		foreach($results as $result) {
154
155
			array_push($tableData, $result);
156
		}
157
158
		return $tableData;
159
	}
160
161
	/**
162
	 * This method deletes a record  from a table row
163
	 * @params int id, string tableName
164
	 * @return boolean true or false
165
	 */
166
	public static function delete($id, $tableName, $dbConn = Null)
167
	{
168
		if (is_null($dbConn)) {
169
170
			$dbConn = new DatabaseConnection();
171
172
		}
173
174
		$sql = 'DELETE FROM '.$tableName.' WHERE id = '.$id;
175
176
		$boolResponse = $dbConn->exec($sql);
177
178
		return $boolResponse ? : false;
179
	}
180
181
	/**
182
	 * This method checks if the magic setters array is the same as the table columns
183
	 * @param array $tableColumn
184
	 * @param array $userSetterArray
185
	 * @return array $unexpectedFields
186
	 */
187
	public static function checkIfMagicSetterContainsIsSameAsClassModel(array $tableColumn, array $userSetterArray)
188
	{
189
		$unexpectedFields = [];
190
191
		foreach ($userSetterArray as $key => $val)
192
		{
193
			if (!in_array($key,$tableColumn)) {
194
195
				$unexpectedFields[] = $key;
196
			}
197
		}
198
199
		return $unexpectedFields;
200
	}
201
202
	/**
203
	 * This method returns sql query
204
	 * @param $sql
205
	 * @return string
206
	 */
207
	private function prepareUpdateQuery($sql)
208
	{
209
		$splittedQuery = explode(",",$sql);
210
211
		array_pop($splittedQuery);
212
213
		$mergeData = implode(",",$splittedQuery);
214
215
		return $mergeData;
216
	}
217
218
	/**
219
	 * @param array $params
220
	 * @param $tableName
221
	 * @param $dbConn
222
	 * @return bool
223
	 * @throws EmptyArrayException
224
	 */
225
	public function findAndWhere($params, $tableName, $dbConn)
226
	{
227
		if (is_null($dbConn)) {
228
229
			$dbConn = $this->dbConnection;
230
		}
231
232
		if (is_array($params) && !empty($params)) {
233
234
			$sql = "SELECT * FROM ".$tableName;
235
236
			foreach ($params as $key => $val) {
237
238
				$sql .= " WHERE $key = $val";
239
			}
240
241
			$statement = $dbConn->prepare($sql);
242
243
			$statement->execute();
244
245
			$returnedRowNumbers = $statement->rowCount();
246
247
			return $returnedRowNumbers  ? true : false;
248
		}
249
250
		throw EmptyArrayException::checkEmptyArrayException("Array Expected: parameter passed to this function is not an array");
251
	}
252
253
	/**
254
	 * This method returns column fields of a particular table
255
	 * @param $table
256
	 * @param $conn
257
	 * @return array
258
	 */
259
	public function getColumnNames($table, $dbConn = Null){
260
261
		$tableFields = [];
262
263
		try {
264
265
			if (is_null($dbConn)) {
266
267
				$dbConn = $this->dbConnection;
268
			}
269
270
			$sql = "SHOW COLUMNS FROM ".$table;
271
272
			$stmt = $dbConn->prepare($sql);
273
			$stmt->bindValue(':table', $table, PDO::PARAM_STR);
274
			$stmt->execute();
275
276
			$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
277
278
			foreach($results as $result) {
279
				array_push($tableFields, $result['Field']);
280
			}
281
282
			return $tableFields;
283
284
		} 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...
285
286
			trigger_error('Could not connect to MySQL database. ' . $e->getMessage() , E_USER_ERROR);
287
		}
288
	}
289
290
291
}
292