andela-cganga /
potato-orm
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | namespace Ganga\Potato; |
||
| 4 | |||
| 5 | use ReflectionClass; |
||
| 6 | use PDO; |
||
| 7 | |||
| 8 | /** |
||
| 9 | * Class that defines Potato ORM |
||
| 10 | * Will be extended by Model Classes |
||
| 11 | */ |
||
| 12 | class Potato |
||
| 13 | { |
||
| 14 | protected $tableName; |
||
| 15 | protected static $id = null; |
||
| 16 | protected static $table; |
||
| 17 | protected $props = []; |
||
| 18 | |||
| 19 | /** |
||
| 20 | * Constructor |
||
| 21 | * TableName is set when the class is extended |
||
| 22 | */ |
||
| 23 | public function __construct() |
||
| 24 | { |
||
| 25 | /** |
||
| 26 | * Tests if the Model has defined a table name |
||
| 27 | * if not it assigns it to the name of the class |
||
| 28 | */ |
||
| 29 | if (!$this->tableName) { |
||
| 30 | $ref = new ReflectionClass($this); |
||
| 31 | $tableName = strtolower($ref->getShortName()).'s'; |
||
| 32 | } |
||
| 33 | |||
| 34 | // Test if table exists else throw an exception |
||
| 35 | if (!self::tableExists($tableName)) { |
||
| 36 | throw new PotatoException("Table $tableName does not exist."); |
||
| 37 | } else { |
||
| 38 | $this->tableName = $tableName; |
||
|
0 ignored issues
–
show
|
|||
| 39 | self::$table = $tableName; |
||
| 40 | } |
||
| 41 | } |
||
| 42 | |||
| 43 | public function __set($key, $value) |
||
| 44 | { |
||
| 45 | $this->props[$key] = $value; |
||
| 46 | } |
||
| 47 | |||
| 48 | /** |
||
| 49 | * Checks if a given table exists in the database |
||
| 50 | * @param string $tableName name of the table to be checked |
||
| 51 | * @return bool true if table is found, false otherwise |
||
| 52 | */ |
||
| 53 | public static function tableExists($tableName) |
||
| 54 | { |
||
| 55 | $query = "SELECT 1 FROM $tableName LIMIT 1"; |
||
| 56 | |||
| 57 | try { |
||
| 58 | $result = Connection::db()->query($query); |
||
| 59 | } catch (Exception $e) { |
||
|
0 ignored issues
–
show
The class
Ganga\Potato\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?
Scrutinizer analyzes your 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...
|
|||
| 60 | return false; |
||
| 61 | } |
||
| 62 | |||
| 63 | return $result !== false; |
||
| 64 | } |
||
| 65 | |||
| 66 | /** |
||
| 67 | * Get the name of the current table |
||
| 68 | * @return String table name |
||
| 69 | */ |
||
| 70 | public function getTableName() |
||
| 71 | { |
||
| 72 | return $this->tableName; |
||
| 73 | } |
||
| 74 | |||
| 75 | /** |
||
| 76 | * Getting table names from a class |
||
| 77 | * This is important when no instance of the class is defined |
||
| 78 | * Like User::getAll() |
||
| 79 | * @return string table name |
||
| 80 | */ |
||
| 81 | public static function getTableNameFromClass() |
||
| 82 | { |
||
| 83 | $instance = new static(); |
||
| 84 | $ref = new ReflectionClass($instance); |
||
| 85 | $name = $ref->getShortName(); |
||
| 86 | $table = strtolower($name) . 's'; |
||
| 87 | |||
| 88 | if (!self::tableExists($table)) { |
||
| 89 | throw new PotatoException("Table $table does not exist."); |
||
| 90 | } |
||
| 91 | |||
| 92 | return $table; |
||
| 93 | } |
||
| 94 | |||
| 95 | /** |
||
| 96 | * Get all records from the record table |
||
| 97 | * @param array $fields array of fields to be retrieved |
||
| 98 | * @return array associative array of the records received from the database |
||
| 99 | */ |
||
| 100 | public static function getAll($fields = null) |
||
| 101 | { |
||
| 102 | $table = self::getTableNameFromClass(); |
||
| 103 | |||
| 104 | View Code Duplication | if ($fields != null && is_array($fields)) { |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 105 | $query = "SELECT ". implode(', ', $fields) ." FROM $table"; |
||
| 106 | } else { |
||
| 107 | $query = "SELECT * FROM $table"; |
||
| 108 | } |
||
| 109 | |||
| 110 | $res = []; |
||
| 111 | |||
| 112 | $results = Connection::db()->query($query); |
||
| 113 | $results->setFetchMode(PDO::FETCH_ASSOC); |
||
| 114 | |||
| 115 | while ($row = $results->fetch()) { |
||
| 116 | array_push($res, $row); |
||
| 117 | } |
||
| 118 | |||
| 119 | return $res; |
||
| 120 | } |
||
| 121 | |||
| 122 | /** |
||
| 123 | * Get one record from the table based on the id provided |
||
| 124 | * @param integer $id id of the record to be retrieved |
||
| 125 | * @param array $fields array of fields to be retrieved |
||
| 126 | * @return array associative array of the record retrieved |
||
| 127 | */ |
||
| 128 | public static function getOne($id, $fields = null) |
||
| 129 | { |
||
| 130 | $table = self::getTableNameFromClass(); |
||
| 131 | |||
| 132 | View Code Duplication | if ($fields != null && is_array($fields)) { |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 133 | $query = "SELECT ". implode(', ', $fields) ." FROM $table WHERE id = $id"; |
||
| 134 | } else { |
||
| 135 | $query = "SELECT * FROM $table WHERE id = $id"; |
||
| 136 | } |
||
| 137 | |||
| 138 | $res = []; |
||
| 139 | |||
| 140 | $results = Connection::db()->query($query); |
||
| 141 | $results->setFetchMode(PDO::FETCH_ASSOC); |
||
| 142 | |||
| 143 | while ($row = $results->fetch()) { |
||
| 144 | array_push($res, $row); |
||
| 145 | } |
||
| 146 | |||
| 147 | if (!empty($res)) { |
||
| 148 | return $res; |
||
| 149 | } else { |
||
| 150 | throw new PotatoException('There is no user with id '. $id); |
||
| 151 | } |
||
| 152 | } |
||
| 153 | |||
| 154 | /** |
||
| 155 | * Save either a new or existing record |
||
| 156 | * @return integer 1 is successful, 0 if false |
||
| 157 | */ |
||
| 158 | public function save() |
||
| 159 | { |
||
| 160 | $result; |
||
|
0 ignored issues
–
show
The variable
$result seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?
This error can happen if you refactor code and forget to move the variable initialization. Let’s take a look at a simple example: function someFunction() {
$x = 5;
echo $x;
}
The above code is perfectly fine. Now imagine that we re-order the statements: function someFunction() {
echo $x;
$x = 5;
}
In that case, Loading history...
|
|||
| 161 | if (! self::$id) { |
||
| 162 | // new record so we insert |
||
| 163 | $query = "INSERT INTO $this->tableName (".implode(", ", array_keys($this->props)).") VALUES("; |
||
| 164 | |||
| 165 | for ($i = 0; $i < count($this->props); $i++) { |
||
|
0 ignored issues
–
show
It seems like you are calling the size function
count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}
// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
|
|||
| 166 | $query .= "?"; |
||
| 167 | |||
| 168 | if ($i != count($this->props) - 1) { |
||
| 169 | $query .= ","; |
||
| 170 | } |
||
| 171 | } |
||
| 172 | |||
| 173 | $query .= ");"; |
||
| 174 | |||
| 175 | $insert = Connection::db()->prepare($query); |
||
| 176 | $result = $insert->execute(array_values($this->props)); |
||
| 177 | } else { |
||
| 178 | // existing record, se we update |
||
| 179 | $query = "UPDATE $this->tableName SET "; |
||
| 180 | |||
| 181 | $count = 0; |
||
| 182 | foreach ($this->props as $key => $value) { |
||
| 183 | $query .= "$key = '$value'"; |
||
| 184 | |||
| 185 | if ($count != count($this->props) - 1) { |
||
| 186 | $query .= ","; |
||
| 187 | } |
||
| 188 | $count++; |
||
| 189 | } |
||
| 190 | |||
| 191 | $query .= " WHERE id = ".self::$id; |
||
| 192 | $result = Connection::db()->query($query); |
||
| 193 | } |
||
| 194 | |||
| 195 | if (! $result) { |
||
| 196 | return false; |
||
| 197 | } else { |
||
| 198 | return true; |
||
| 199 | } |
||
| 200 | } |
||
| 201 | |||
| 202 | /** |
||
| 203 | * Find a record by id and change static id param |
||
| 204 | * @param int $id id of the record to be found |
||
| 205 | * @return ClassInstance an instance of the TableClass so that properties can be assigned automatically |
||
| 206 | */ |
||
| 207 | public static function find($id) |
||
| 208 | { |
||
| 209 | self::getOne($id); |
||
| 210 | self::$id = $id; |
||
| 211 | return new static(); |
||
| 212 | } |
||
| 213 | |||
| 214 | /** |
||
| 215 | * Delete a record by id from the table in context |
||
| 216 | * @param id $id the id of the record to be deleted |
||
| 217 | * @return [type] [description] |
||
|
0 ignored issues
–
show
The doc-type
[type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types. Loading history...
|
|||
| 218 | */ |
||
| 219 | public static function destroy($id) |
||
| 220 | { |
||
| 221 | $table = self::getTableNameFromClass(); |
||
| 222 | |||
| 223 | self::getOne($id); |
||
| 224 | |||
| 225 | $query = "DELETE FROM $table WHERE id = ".$id; |
||
| 226 | |||
| 227 | try { |
||
| 228 | Connection::db()->query($query); |
||
| 229 | return true; |
||
| 230 | } catch (Exception $e) { |
||
|
0 ignored issues
–
show
The class
Ganga\Potato\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?
Scrutinizer analyzes your 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...
|
|||
| 231 | return false; |
||
| 232 | } |
||
| 233 | } |
||
| 234 | } |
||
| 235 |
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:
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
Check for existence of the variable explicitly:
Define a default value for the variable:
Add a value for the missing path: