Completed
Push — master ( f30db2...aac6d2 )
by Adeola
02:45
created

DataBaseQuery::read()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4.0961

Importance

Changes 7
Bugs 1 Features 0
Metric Value
c 7
b 1
f 0
dl 0
loc 18
ccs 9
cts 11
cp 0.8182
rs 9.2
cc 4
eloc 11
nc 8
nop 3
crap 4.0961
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 $dataBaseConnection;
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 39
    public function __construct($dbConn = null)
35
    {
36 39
        if (is_null($dbConn)) {
37
            $this->dataBaseConnection = new DataBaseConnection(); 
38
        } else {
39 39
            $dbConn = $this->dataBaseConnection;
0 ignored issues
show
Unused Code introduced by
$dbConn 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...
40
        }
41
    }
42 39
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
    public function create($associativeArray, $tableName, $dbConn = null)
52 9
    {
53
        $tableFields = [];
54 9
        $tableValues = [];
55
56
        foreach ($associativeArray as $key => $val) {
57 9
            $tableFields[] = $key;
58 9
            $tableValues[] = $val;
59
        }
60 9
        $unexpectedArray = array_diff($tableFields, $this->getColumnNames($tableName, $dbConn));
61 9
        
62 9
        if (count($unexpectedArray) < 1) {
63 6
            $sql = 'INSERT INTO '.$tableName;
64 9
            $sql .= '('.$this->splitTableField($tableFields).') ';
65
            $sql .= 'VALUES ('.$this->formatTableValues($tableValues).')';
66 9
            $statement = $dbConn->exec($sql);
67 3
68 3
            return $statement;
69 3
        }
70 3
71
        throw new FieldUndefinedException('Oops, please input the following field: NAME, SEX, OCCUPATION, ORGANISATION AND YEAR');
72 3
    }
73
74
    /**
75 6
     * This method read the data in the table name of the id being passed to it.
76
     *
77
     * @param $id
78
     * @param $tableName
79
     *
80
     * @return array
81
     */
82
    public static function read($id, $tableName, $dbConn = null)
83
    {
84
        $tableData = [];
85
        $sql = $id ? 'SELECT * FROM '.$tableName.' WHERE id = '.$id : 'SELECT * FROM '.$tableName;
86 12
        $statement = $dbConn->prepare($sql);
87
        $statement->execute();
88 12
        $results = $statement->fetchAll(PDO::FETCH_ASSOC);
89
90
        foreach ($results as $result) {
91
            array_push($tableData, $result);
92 12
        }
93 12
94 12
        if (count($tableData) < 1) {
95 12
            throw new IdNotFoundException('Oops, the id '.$id.' is not in the database, try another id');
96 12
        }
97
98 12
        return $tableData;
99 9
    }
100 8
101
    /**
102 12
     * This method delete the table name of the id being passed to it.
103 3
     *
104
     * @param $update Params
105
     * @param $associativeArray
106 9
     * @param $tableName
107
     *
108
     * @return bool
109
     */
110
    public function update($updateParams, $associativeArray, $tableName, $dbConn = null)
111
    {
112
        $sql = '';
0 ignored issues
show
Unused Code introduced by
$sql 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...
113
        $updateSql = "UPDATE `$tableName` SET ";
114
115
        unset($associativeArray['id']);
116
117
        foreach ($associativeArray as $key => $val) {
118 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...
119
        }
120 6
121
        $unexpectedArray = array_diff($tableFields, $this->getColumnNames($tableName, $dbConn));
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...
122
123 6
        if (count($unexpectedArray) < 1) {
124 6
            $updateSql .= $this->updateArraySql($associativeArray);
125
126 6
            foreach ($updateParams as $field => $value) {
127
                $updateSql .= " WHERE $field = $value";
128 6
            }
129 6
130 4
            $statement = $dbConn->exec($updateSql);
131
132 6
            return $statement ?: false;
133
        }
134 6
135 3
        throw new FieldUndefinedException('Oops, please input the following field: NAME, SEX, OCCUPATION, ORGANISATION AND YEAR');
136
    }
137 3
138 3
    /**
139 2
     * This method delete the table name of the id passed to it.
140
     *
141 3
     * @param $id
142
     * @param $tableName
143 3
     *
144
     * @return bool
145
     */
146 3
    public static function delete($id, $tableName, $dbConn = null)
147
    {
148
        $sql = 'DELETE FROM '.$tableName.' WHERE id = '.$id;
149
        $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...
150
151
        return true;
152
    }
153
154
    /**
155
     * This method returns a string form an array by making us of the implode function.
156
     *
157 6
     * @param $tableField
158
     *
159 6
     * @return string
160
     */
161
    public function splitTableField($tableField)
162 6
    {
163 6
        $splitTableField = implode(',', $tableField);
164
165 6
        return $splitTableField;
166
    }
167
168
    /**
169
     * This method returns a string formed fron an array, It format the array.
170
     *
171
     * @param $tableValues
172
     *
173
     * @return string
174
     */
175 3
    public function formatTableValues($tableValues)
176
    {
177 3
        $formattedValues = [];
178 3
179
        foreach ($tableValues as $key => $value) {
180
            $formattedValues[] = "'".$value."'";
181
        }
182
183
        $ValueSql = implode(',', $formattedValues);
184
        
185
        return $ValueSql;
186
    }
187
188 3
    /**
189
     * This method returns a string formed from an array.
190 3
     *
191
     * @param $array
192 3
     *
193 3
     * @return string
194 2
     */
195
    public function updateArraySql($array)
196 3
    {
197
        $updatedValues = [];
198 3
199
        foreach ($array as $key => $val) {
200
            $updatedValues[] = "`$key` = '$val'";
201
        }
202
    
203
        $valueSql = implode(',', $updatedValues);
204
205
        return $valueSql;
206
    }
207
208 3
    /**
209
     * This method returns column fields of a particular table.
210 3
     *
211
     * @param $table
212 3
     *
213 3
     * @return array
214 2
     */
215
    public function getColumnNames($table, $dbConn = null)
216 3
    {
217
        $tableFields = [];
218 3
219
        $sql = 'SHOW COLUMNS FROM '.$table;
220
        $stmt = $dbConn->prepare($sql);
221
        $stmt->bindValue(':table', $table, PDO::PARAM_STR);
222
        $stmt->execute();
223
        $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
224
225
        foreach ($results as $result) {
226
            array_push($tableFields, $result['Field']);
227
        }
228 18
229
        return $tableFields;
230 18
    }
231
}
232