zortje /
mvc
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 | declare(strict_types = 1); |
||
| 3 | |||
| 4 | namespace Zortje\MVC\Model\Table; |
||
| 5 | |||
| 6 | use Zortje\MVC\Model\SQLCommand; |
||
| 7 | use Zortje\MVC\Model\Table\Entity\Entity; |
||
| 8 | use Zortje\MVC\Model\Table\Entity\EntityFactory; |
||
| 9 | use Zortje\MVC\Model\Table\Entity\EntityProperty; |
||
| 10 | use Zortje\MVC\Model\Table\Entity\Exception\EntityClassInvalidSuperclassException; |
||
| 11 | use Zortje\MVC\Model\Table\Entity\Exception\EntityClassNonexistentException; |
||
| 12 | use Zortje\MVC\Model\Table\Entity\Exception\EntityClassNotDefinedException; |
||
| 13 | use Zortje\MVC\Model\Table\Entity\Exception\InvalidEntityPropertyException; |
||
| 14 | use Zortje\MVC\Model\Table\Exception\TableNameNotDefinedException; |
||
| 15 | |||
| 16 | /** |
||
| 17 | * Class Table |
||
| 18 | * |
||
| 19 | * @package Zortje\MVC\Model\Table |
||
| 20 | */ |
||
| 21 | abstract class Table |
||
| 22 | { |
||
| 23 | |||
| 24 | /** |
||
| 25 | * @var \PDO Connection |
||
| 26 | */ |
||
| 27 | protected $pdo; |
||
| 28 | |||
| 29 | /** |
||
| 30 | * @var string Table name |
||
| 31 | */ |
||
| 32 | protected $tableName; |
||
| 33 | |||
| 34 | /** |
||
| 35 | * @var String Entity class |
||
| 36 | */ |
||
| 37 | protected $entityClass; |
||
| 38 | |||
| 39 | /** |
||
| 40 | * @var SQLCommand SQL Command |
||
| 41 | */ |
||
| 42 | protected $sqlCommand; |
||
| 43 | |||
| 44 | /** |
||
| 45 | * @param \PDO $pdo |
||
| 46 | * |
||
| 47 | * @throws TableNameNotDefinedException If table name is not defined in subclass |
||
| 48 | * @throws EntityClassNotDefinedException If entity class is not defined in subclass |
||
| 49 | * @throws EntityClassNonexistentException If entity class is nonexistent |
||
| 50 | * @throws EntityClassInvalidSuperclassException If entity class is not extending base entity class |
||
| 51 | */ |
||
| 52 | 5 | public function __construct(\PDO $pdo) |
|
| 53 | { |
||
| 54 | 5 | if ($this->tableName === null) { |
|
| 55 | 1 | throw new TableNameNotDefinedException([get_class($this)]); |
|
| 56 | } |
||
| 57 | |||
| 58 | 4 | if ($this->entityClass === null) { |
|
| 59 | 1 | throw new EntityClassNotDefinedException([get_class($this)]); |
|
| 60 | 3 | } elseif (!class_exists($this->entityClass)) { |
|
| 61 | 1 | throw new EntityClassNonexistentException([get_class($this), $this->entityClass]); |
|
| 62 | 2 | } elseif (!is_subclass_of($this->entityClass, Entity::class)) { |
|
| 63 | 1 | throw new EntityClassInvalidSuperclassException([$this->entityClass]); |
|
| 64 | } |
||
| 65 | |||
| 66 | 1 | $this->pdo = $pdo; |
|
| 67 | |||
| 68 | 1 | $this->sqlCommand = $this->createCommand(); |
|
| 69 | 1 | } |
|
| 70 | |||
| 71 | /** |
||
| 72 | * Get table name |
||
| 73 | * |
||
| 74 | * @return string Table name |
||
| 75 | */ |
||
| 76 | 1 | public function getTableName(): string |
|
| 77 | { |
||
| 78 | 1 | return $this->tableName; |
|
| 79 | } |
||
| 80 | |||
| 81 | /** |
||
| 82 | * Find all entities |
||
| 83 | * |
||
| 84 | * @return Entity[] Entities |
||
| 85 | */ |
||
| 86 | 1 | public function findAll(): array |
|
| 87 | { |
||
| 88 | 1 | $stmt = $this->pdo->prepare($this->sqlCommand->selectFrom()); |
|
| 89 | 1 | $stmt->execute(); |
|
| 90 | |||
| 91 | 1 | return $this->createEntitiesFromStatement($stmt); |
|
| 92 | } |
||
| 93 | |||
| 94 | /** |
||
| 95 | * Find all entities for given conditions |
||
| 96 | * |
||
| 97 | * ``` |
||
| 98 | * [ |
||
| 99 | * '{entity_property}' => '{property_value}' |
||
| 100 | * ] |
||
| 101 | * ``` |
||
| 102 | * |
||
| 103 | * @param array $conditions |
||
| 104 | * |
||
| 105 | * @throws InvalidEntityPropertyException If entity does not have that property |
||
| 106 | * |
||
| 107 | * @return Entity[] Entities |
||
| 108 | */ |
||
| 109 | 4 | public function findBy(array $conditions): array |
|
| 110 | { |
||
| 111 | /** |
||
| 112 | * Check if entity have the properties in conditions |
||
| 113 | * |
||
| 114 | * @var Entity $entity |
||
| 115 | */ |
||
| 116 | 4 | $reflector = new \ReflectionClass($this->entityClass); |
|
| 117 | |||
| 118 | 4 | $entity = $reflector->newInstanceWithoutConstructor(); |
|
| 119 | |||
| 120 | 4 | foreach (array_keys($conditions) as $key) { |
|
| 121 | 4 | if (!isset($entity::getColumns()[$key])) { |
|
| 122 | 4 | throw new InvalidEntityPropertyException([$this->entityClass, $key]); |
|
| 123 | } |
||
| 124 | } |
||
| 125 | |||
| 126 | /** |
||
| 127 | * Validate values in conditions |
||
| 128 | */ |
||
| 129 | 3 | foreach ($conditions as $key => $value) { |
|
| 130 | 3 | $entityProperty = new EntityProperty($entity::getColumns()[$key]); |
|
| 131 | 3 | $entityProperty->validateValue($value); |
|
| 132 | } |
||
| 133 | |||
| 134 | /** |
||
| 135 | * Execute with key-value condition |
||
| 136 | */ |
||
| 137 | 2 | $parameters = []; |
|
| 138 | |||
| 139 | 2 | foreach ($conditions as $key => $value) { |
|
| 140 | 2 | $parameters[":$key"] = $value; |
|
| 141 | } |
||
| 142 | |||
| 143 | 2 | $stmt = $this->pdo->prepare($this->sqlCommand->selectFromWhere(array_keys($conditions))); |
|
| 144 | 2 | $stmt->execute($parameters); |
|
| 145 | |||
| 146 | 2 | return $this->createEntitiesFromStatement($stmt); |
|
| 147 | } |
||
| 148 | |||
| 149 | /** |
||
| 150 | * Insert entity into database |
||
| 151 | * |
||
| 152 | * @param Entity $entity Entity object |
||
| 153 | * |
||
| 154 | * @return Entity Inserted entity |
||
| 155 | */ |
||
| 156 | 1 | public function insert(Entity $entity): Entity |
|
| 157 | { |
||
| 158 | 1 | $stmt = $this->pdo->prepare($this->sqlCommand->insertInto()); |
|
| 159 | |||
| 160 | 1 | $now = (new \DateTime())->format('Y-m-d H:i:s'); |
|
| 161 | |||
| 162 | 1 | $array = array_merge($entity->toArray(), [ |
|
| 163 | 1 | 'modified' => $now, |
|
| 164 | 1 | 'created' => $now |
|
| 165 | ]); |
||
| 166 | |||
| 167 | 1 | $stmt->execute($array); |
|
| 168 | |||
| 169 | 1 | return $entity; |
|
| 170 | } |
||
| 171 | |||
| 172 | /** |
||
| 173 | * Update entity in the database |
||
| 174 | * |
||
| 175 | * @param Entity $entity Entity object |
||
| 176 | * |
||
| 177 | * @return bool True if row was affected, otherwise false |
||
| 178 | */ |
||
| 179 | 1 | public function update(Entity $entity): bool |
|
| 180 | { |
||
| 181 | 1 | if ($entity->isAltered()) { |
|
| 182 | /** |
||
| 183 | * Set modified to now |
||
| 184 | */ |
||
| 185 | 1 | $entity->set('modified', new \DateTime()); |
|
| 186 | |||
| 187 | /** |
||
| 188 | * Get altered columns for SQL command |
||
| 189 | */ |
||
| 190 | 1 | $alteredColumns = array_keys($entity->getAlteredColumns()); |
|
| 191 | |||
| 192 | 1 | $stmt = $this->pdo->prepare($this->sqlCommand->updateSetWhere($alteredColumns)); |
|
| 193 | |||
| 194 | /** |
||
| 195 | * Execute with altered array |
||
| 196 | */ |
||
| 197 | 1 | $stmt->execute($entity->alteredToArray(true)); |
|
| 198 | |||
| 199 | // @todo return true if row is altered |
||
| 200 | } |
||
| 201 | |||
| 202 | 1 | return false; |
|
| 203 | } |
||
| 204 | |||
| 205 | public function delete(Entity $entity) |
||
|
0 ignored issues
–
show
|
|||
| 206 | { |
||
| 207 | // @todo Implement |
||
| 208 | } |
||
| 209 | |||
| 210 | /** |
||
| 211 | * Creates an array of Entity objects from statement |
||
| 212 | * |
||
| 213 | * @param \PDOStatement $statement |
||
| 214 | * |
||
| 215 | * @return Entity[] Entities from statement |
||
| 216 | */ |
||
| 217 | protected function createEntitiesFromStatement(\PDOStatement $statement): array |
||
| 218 | { |
||
| 219 | $entities = []; |
||
| 220 | |||
| 221 | $entityFactory = new EntityFactory($this->entityClass); |
||
| 222 | |||
| 223 | foreach ($statement as $row) { |
||
| 224 | $entities[] = $entityFactory->createFromArray($row); |
||
| 225 | } |
||
| 226 | |||
| 227 | return $entities; |
||
| 228 | } |
||
| 229 | |||
| 230 | /** |
||
| 231 | * Create SQLCommand for this Table with provided Entity |
||
| 232 | * |
||
| 233 | * @return SQLCommand |
||
| 234 | */ |
||
| 235 | 1 | protected function createCommand(): SQLCommand |
|
| 236 | { |
||
| 237 | 1 | $reflector = new \ReflectionClass($this->entityClass); |
|
| 238 | |||
| 239 | 1 | $entity = $reflector->newInstanceWithoutConstructor(); |
|
| 240 | |||
| 241 | 1 | $columns = $entity::getColumns(); |
|
| 242 | |||
| 243 | 1 | return new SQLCommand($this->tableName, $columns); |
|
| 244 | } |
||
| 245 | } |
||
| 246 |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.