Completed
Push — master ( 1b3be6...409e1d )
by Adeola
02:57
created

DataBaseQuery::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 8
Bugs 1 Features 0
Metric Value
c 8
b 1
f 0
dl 0
loc 8
ccs 6
cts 6
cp 1
rs 9.4285
cc 2
eloc 5
nc 2
nop 1
crap 2
1
<?php
2
3
/**
4
 * Class DataBase:
5
 * This class performs the basic CRUD operations which compose of
6
 * various methods such as create, read, update, and delete.
7
 * This class class query the database to achieve its function.
8
 *
9
 * @author: Raimi Ademola <[email protected]>
10
 * @copyright: 2016 Andela
11
 */
12
namespace Demo;
13
14
use PDO;
15
16
/**
17
 * This is a constructor; a default method  that will be called automatically during class instantiation.
18
 */
19
class DataBaseQuery
20
{
21
    protected $tableName;
22
    protected $splitTableField;
23
    protected $formatTableValues;
24
    protected $dbConnection;
25
26
    /**
27
     * This method create or insert new users to the table.
28
     *
29
     * @param $associativeArray
30
     * @param $tableName
31
     *
32
     * @return array
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...
33
     */
34 72
    public function __construct($dbConn = null)
35
    {
36 72
        if (is_null($dbConn)) {
37 51
            $this->dbConnection = new DataBaseConnection();
38 34
        } else {
39 72
            $this->dbConnection = $dbConn;
40
        }
41 72
    }
42
43
    /**
44
     * This method create or insert new users to the table.
45
     *
46
     * @param $associativeArray
47
     * @param $tableName
48
     *
49
     * @return array
50
     */
51 6
    public function create($associativeArrayToCreate, $tableName)
52
    {
53 6
        $tableFields = [];
54 6
        $tableValues = [];
55
56 6
        foreach ($associativeArrayToCreate as $key => $val) {
57 6
            $tableFields[] = $key;
58 6
            $tableValues[] = $val;
59 4
        }
60
        
61 6
        $unexpectedArray = array_diff($tableFields, $this->getColumnNames($tableName));
62
63 6
        if (count($unexpectedArray) < 1) {
64 3
            $sql = 'INSERT INTO '.$tableName;
65 3
            $sql .= '('.$this->splitTableField($tableFields).') ';
66 3
            $sql .= 'VALUES ('.$this->formatTableValues($tableValues).')';
67
68 3
            $bool = $this->dbConnection->exec($sql);
69
70 3
            return $bool;
71
        }
72
        
73 3
        throw new FieldUndefinedException('Oops, '.$this->splitTableField($unexpectedArray).' is not defined as a field');
74
    }
75
76
    /**
77
     * This method read the data in the table name of the id being passed to it.
78
     *
79
     * @param $id
80
     * @param $tableName
81
     *
82
     * @return array
83
     */
84 9
    public static function read($id, $tableName, $dbConn = null)
85
    {
86 9
        if (is_null($dbConn)) {
87
            $dbConn = new DataBaseConnection();
88
        }
89
90 9
        $sql = $id ? 'SELECT * FROM '.$tableName.' WHERE id = '.$id : 'SELECT * FROM '.$tableName;
91 9
        $statement = $dbConn->prepare($sql);
92 9
        $statement->execute();
93
        
94 9
        $results = $statement->fetchAll(PDO::FETCH_ASSOC);
95
96 9
        if (count($results) < 1) {
97 3
            throw new IdNotFoundException('Oops, the id '.$id.' is not in the table, try another id');
98
        }
99
100 6
        return $results;
101
    }
102
103
    /**
104
     * This method delete the table name of the id being passed to it.
105
     *
106
     * @param $update Params
107
     * @param $associativeArrayToUpdate
108
     * @param $tableName
109
     *
110
     * @return bool
111
     */
112 6
    public function update($updateParams, $associativeArrayToUpdate, $tableName)
113
    {
114 6
        $updateSql = "UPDATE `$tableName` SET ";
115
116 6
        unset($associativeArrayToUpdate['id']);
117
118 6
        foreach ($associativeArrayToUpdate as $key => $val) {
119 6
            $tableFields[] = $key;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$tableFields was never initialized. Although not strictly required by PHP, it is generally a good practice to add $tableFields = 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...
120 4
        }
121
122 6
        $unexpectedArray = array_diff($tableFields, $this->getColumnNames($tableName));
0 ignored issues
show
Bug introduced by
The variable $tableFields 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...
123
124 6
        if (count($unexpectedArray) < 1) {
125 3
            $updateSql .= $this->updateArraySql($associativeArrayToUpdate);
126
            
127 3
            foreach ($updateParams as $field => $value) {
128 3
                $updateSql .= " WHERE $field = $value";
129 2
            }
130
131 3
            $statement = $this->dbConnection->exec($updateSql);
132
            
133 3
            return $statement;
134
        }
135
136 3
        throw new FieldUndefinedException('Oops, '.$this->splitTableField($unexpectedArray).' is not defined as a field');
137
    }
138
139
    /**
140
     * This method delete the table name of the id passed to it.
141
     *
142
     * @param $id
143
     * @param $tableName
144
     *
145
     * @return bool
146
     */
147 9
    public static function delete($id, $tableName, $dbConn = null)
148
    {
149 9
        if (is_null($dbConn)) {
150
            $dbConn = new DataBaseConnection();
151
        }
152
153 9
        $sql = 'SELECT * FROM '.$tableName.' WHERE id = '.$id;
154 9
        $statement = $dbConn->prepare($sql);
155 9
        $statement->execute();
156 9
        $results = $statement->fetchAll(PDO::FETCH_ASSOC);
157
158 9
        if (count($results) < 1) {
159 3
            throw new IdNotFoundException('Oops, the id '.$id.' is not in the database, try another id');
160
        }
161
162 6
        $sql = 'DELETE FROM '.$tableName.' WHERE id = '.$id;
163 6
        $statement = $dbConn->exec($sql);
0 ignored issues
show
Unused Code introduced by
$statement 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...
164
165 6
        return true;
166
    }
167
168
    /**
169
     * This method returns a string form an array by making us of the implode function.
170
     *
171
     * @param $tableField
172
     *
173
     * @return string
174
     */
175 12
    public function splitTableField($tableField)
176
    {
177 12
        $splitTableField = implode(', ', $tableField);
178
179 12
        return $splitTableField;
180
    }
181
182
    /**
183
     * This method returns a string formed fron an array, It format the array.
184
     *
185
     * @param $tableValues
186
     *
187
     * @return string
188
     */
189 3
    public function formatTableValues($tableValues)
190
    {
191 3
        $formattedValues = [];
192
193 3
        foreach ($tableValues as $key => $value) {
194 3
            $formattedValues[] = "'".$value."'";
195 2
        }
196
197 3
        $ValueSql = implode(',', $formattedValues);
198
199 3
        return $ValueSql;
200
    }
201
202
    /**
203
     * This method returns a string formed from an array.
204
     *
205
     * @param $array
206
     *
207
     * @return string
208
     */
209 6
    public function updateArraySql($array)
210
    {
211 6
        $updatedValues = [];
212
213 6
        foreach ($array as $key => $val) {
214 6
            $updatedValues[] = "`$key` = '$val'";
215 4
        }
216
217 6
        $valueSql = implode(',', $updatedValues);
218
219 6
        return $valueSql;
220
    }
221
222
    /**
223
     * This method returns column fields of a particular table.
224
     *
225
     * @param $table
226
     *
227
     * @return array
228
     */
229 15
    public function getColumnNames($table)
230
    {
231 15
        $tableFields = [];
232
233 15
        $sql = 'SHOW COLUMNS FROM '.$table;
234 15
        $stmt = $this->dbConnection->prepare($sql);
235 15
        $stmt->bindValue(':table', $table, PDO::PARAM_STR);
236 15
        $stmt->execute();
237 15
        $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
238
        
239 15
        foreach ($results as $result) {
240 15
            array_push($tableFields, $result['Field']);
241 10
        }
242
243 15
        return $tableFields;
244
    }
245
}
246