Completed
Push — test ( 7b9055...71549d )
by Temitope
02:34
created

DatabaseHandler   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 227
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 12
Bugs 1 Features 7
Metric Value
wmc 30
c 12
b 1
f 7
lcom 1
cbo 4
dl 0
loc 227
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
B create() 0 35 5
B update() 0 36 6
B read() 0 32 5
A delete() 0 15 3
A checkIfMagicSetterContainsIsSameAsClassModel() 0 14 3
A prepareUpdateQuery() 0 10 1
B findAndWhere() 0 26 6
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;
19
	private $dbHelperInstance;
20
	private $dbConnection;
21
22
	/**
23
	 * This is a constructor; a default method  that will be called automatically during class instantiation
24
	 */
25
	public function __construct($modelClassName)
26
	{
27
		$databaseConn = new DatabaseConnection();
28
29
		$this->dbConnection = $databaseConn->connect();
30
31
		$this->dbHelperInstance = new DatabaseHelper($this->dbConnection);
32
33
		$this->tableFields = $this->dbHelperInstance->getColumnNames($modelClassName);
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->tableFields,$associative1DArray);
0 ignored issues
show
Bug introduced by
It seems like $this->tableFields can also be of type null; however, Laztopaz\potatoORM\Datab...insIsSameAsClassModel() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
44
45
		if (count($unexpectedFields) > 0)
46
		{
47
			throw TableFieldUndefinedException::fieldsNotDefinedException($unexpectedFields,"needs to be created as table field");
48
		}
49
50
		unset($this->tableFields[0]);
51
52
		if (is_null($dbConn)) {
53
54
			$dbhandle = new DatabaseConnection();
55
			$dbConn = $dbhandle->connect();
56
		}
57
58
		$insertQuery = 'INSERT INTO '.$tableName;
59
60
		$TableValues = implode(',',array_keys($associative1DArray));
61
62
		foreach ($associative1DArray as $field => $value) {
63
64
			$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...
65
		}
66
		$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...
67
68
		$insertQuery.= ' ('.$TableValues.')';
69
70
		$insertQuery.= ' VALUES ('.$splittedTableValues.')';
71
72
		$executeQuery = $dbConn->exec($insertQuery);
73
74
		return $executeQuery ? : false;
75
	}
76
77
	/*
78
	 * This method updates any table by supplying 3 parameter
79
	 * @params: $updateParams, $tableName, $associative1DArray
80
	 * @return boolean true or false
81
	 */
82
	public function update(array $updateParams, $tableName, $associative1DArray, $dbConn = Null)
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->tableFields,$associative1DArray);
0 ignored issues
show
Bug introduced by
It seems like $this->tableFields can also be of type null; however, Laztopaz\potatoORM\Datab...insIsSameAsClassModel() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
94
95
		if (count($unexpectedFields) > 0) {
96
97
			throw TableFieldUndefinedException::fieldsNotDefinedException($unexpectedFields,"needs to be created as table field");
98
		}
99
100
		foreach($associative1DArray as $field => $value)
101
		{
102
			$sql = "`$field` = '$value'".",";
103
		}
104
105
		$updateSql.= $this->prepareUpdateQuery($sql);
0 ignored issues
show
Bug introduced by
The variable $sql 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...
106
107
		foreach ($updateParams as $key => $val) {
108
109
			$updateSql .= " WHERE $key = $val";
110
		}
111
112
		$stmt = $dbConn->prepare($updateSql);
113
114
		$boolResponse = $stmt->execute();
115
116
		return $boolResponse ?  : false;
117
	}
118
119
	/**
120
	 * This method retrieves record from a table
121
	 * @params int id, string tableName
122
	 * @return array
123
	 */
124
	public static function read($id, $tableName, $dbConn = Null)
125
	{
126
		$tableData = array();
127
128
		if (is_null($dbConn)) {
129
130
			$dhl = new DatabaseConnection();
131
132
			$dbConn = $dhl->connect();
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
			$dbhandle = new DatabaseConnection();
167
168
			$dbConn = $dbhandle->connect();
169
		}
170
171
		$sql = 'DELETE FROM '.$tableName.' WHERE id = '.$id;
172
173
		$boolResponse = $dbConn->exec($sql);
174
175
		return $boolResponse ? : false;
176
	}
177
178
	/**
179
	 * This method checks if the magic setters array is the same as the table columns
180
	 * @param array $tableColumn
181
	 * @param array $userSetterArray
182
	 * @return array $unexpectedFields
183
	 */
184
	public static function checkIfMagicSetterContainsIsSameAsClassModel(array $tableColumn, array $userSetterArray)
185
	{
186
		$unexpectedFields = [];
187
188
		foreach ($userSetterArray as $key => $val)
189
		{
190
			if (!in_array($key,$tableColumn)) {
191
192
				$unexpectedFields[] = $key;
193
			}
194
		}
195
196
		return $unexpectedFields;
197
	}
198
199
	/**
200
	 * This method returns sql query
201
	 * @param $sql
202
	 * @return string
203
	 */
204
	private function prepareUpdateQuery($sql)
205
	{
206
		$splittedQuery = explode(",",$sql);
207
208
		array_pop($splittedQuery);
209
210
		$mergeData = implode(",",$splittedQuery);
211
212
		return $mergeData;
213
	}
214
215
	public function findAndWhere(array $params, $tableName, $dbConn)
216
	{
217
		if (is_null($dbConn)) {
218
219
			$dbConn = $this->dbConnection;
220
		}
221
222
		if (is_array($params) && !empty($params)) {
223
224
			$sql = "SELECT * FROM ".$tableName." WHERE";
225
226
			foreach ($params as $key => $val) {
227
228
				$sql .= " WHERE $key = $val";
229
			}
230
231
			$statement = $dbConn->prepare($sql);
232
233
			$statement->execute();
234
235
			$returnedRowNumbers = $statement->rowCount();
236
237
			return $returnedRowNumbers >= 1 ? true : false;
238
		}
239
		throw EmptyArrayException::checkEmptyArrayException("Array Expected: parameter passed to this function is not an array");
240
	}
241
242
}
243