Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 9 | class ArrayHydrator |
||
| 10 | { |
||
| 11 | /** |
||
| 12 | * The keys in the data array are entity field names |
||
| 13 | */ |
||
| 14 | const HYDRATE_BY_FIELD = 1; |
||
| 15 | |||
| 16 | /** |
||
| 17 | * The keys in the data array are database column names |
||
| 18 | */ |
||
| 19 | const HYDRATE_BY_COLUMN = 2; |
||
| 20 | |||
| 21 | /** |
||
| 22 | * @var EntityManagerInterface |
||
| 23 | */ |
||
| 24 | protected $entityManager; |
||
| 25 | |||
| 26 | /** |
||
| 27 | * If true, then associations are filled only with reference proxies. This is faster than querying them from |
||
| 28 | * database, but if the associated entity does not really exist, it will cause: |
||
| 29 | * * The insert/update to fail, if there is a foreign key defined in database |
||
| 30 | * * The record ind database also pointing to a non-existing record |
||
| 31 | * |
||
| 32 | * @var bool |
||
| 33 | */ |
||
| 34 | protected $hydrateAssociationReferences = true; |
||
| 35 | |||
| 36 | /** |
||
| 37 | * Tells whether the input data array keys are entity field names or database column names |
||
| 38 | * |
||
| 39 | * @var int one of ArrayHydrator::HIDRATE_BY_* constants |
||
| 40 | */ |
||
| 41 | protected $hydrateBy = self::HYDRATE_BY_FIELD; |
||
| 42 | |||
| 43 | /** |
||
| 44 | * If true, hydrate the primary key too. Useful if the primary key is not automatically generated by the database |
||
| 45 | * |
||
| 46 | * @var bool |
||
| 47 | */ |
||
| 48 | protected $hydrateId = false; |
||
| 49 | |||
| 50 | /** |
||
| 51 | * @param EntityManagerInterface $entityManager |
||
| 52 | */ |
||
| 53 | public function __construct(EntityManagerInterface $entityManager) |
||
| 57 | |||
| 58 | /** |
||
| 59 | * @param $entity |
||
| 60 | * @param array $data |
||
| 61 | * @return mixed|object |
||
| 62 | * @throws Exception |
||
| 63 | */ |
||
| 64 | public function hydrate($entity, array $data) |
||
| 77 | |||
| 78 | /** |
||
| 79 | * @param boolean $hydrateAssociationReferences |
||
| 80 | */ |
||
| 81 | public function setHydrateAssociationReferences($hydrateAssociationReferences) |
||
| 85 | |||
| 86 | /** |
||
| 87 | * @param bool $hydrateId |
||
| 88 | */ |
||
| 89 | public function setHydrateId($hydrateId) |
||
| 93 | |||
| 94 | /** |
||
| 95 | * @param int $hydrateBy |
||
| 96 | */ |
||
| 97 | public function setHydrateBy($hydrateBy) |
||
| 101 | |||
| 102 | /** |
||
| 103 | * @param object $entity the doctrine entity |
||
| 104 | * @param array $data |
||
| 105 | * @return object |
||
| 106 | */ |
||
| 107 | protected function hydrateProperties($entity, $data) |
||
| 138 | |||
| 139 | /** |
||
| 140 | * @param $entity |
||
| 141 | * @param $data |
||
| 142 | * @return mixed |
||
| 143 | */ |
||
| 144 | protected function hydrateAssociations($entity, $data) |
||
| 162 | |||
| 163 | /** |
||
| 164 | * Retrieves the associated entity's id from $data |
||
| 165 | * |
||
| 166 | * @param string $fieldName name of field that stores the associated entity |
||
| 167 | * @param array $mapping doctrine's association mapping array for the field |
||
| 168 | * @param array $data the hydration data |
||
| 169 | * |
||
| 170 | * @return mixed null, if the association is not found |
||
| 171 | */ |
||
| 172 | protected function getAssociatedId($fieldName, $mapping, $data) |
||
| 191 | |||
| 192 | /** |
||
| 193 | * @param $entity |
||
| 194 | * @param $propertyName |
||
| 195 | * @param $mapping |
||
| 196 | * @param $value |
||
| 197 | * @return mixed |
||
| 198 | */ |
||
| 199 | protected function hydrateToOneAssociation($entity, $propertyName, $mapping, $value) |
||
| 210 | |||
| 211 | /** |
||
| 212 | * @param $entity |
||
| 213 | * @param $propertyName |
||
| 214 | * @param $mapping |
||
| 215 | * @param $value |
||
| 216 | * @return mixed |
||
| 217 | */ |
||
| 218 | protected function hydrateToManyAssociation($entity, $propertyName, $mapping, $value) |
||
| 237 | |||
| 238 | /** |
||
| 239 | * @param $entity |
||
| 240 | * @param $propertyName |
||
| 241 | * @param $value |
||
| 242 | * @param null $reflectionObject |
||
| 243 | * @return mixed |
||
| 244 | */ |
||
| 245 | protected function setProperty($entity, $propertyName, $value, $reflectionObject = null) |
||
| 253 | |||
| 254 | /** |
||
| 255 | * @param $className |
||
| 256 | * @param $id |
||
| 257 | * @return bool|\Doctrine\Common\Proxy\Proxy|null|object |
||
| 258 | * @throws \Doctrine\ORM\ORMException |
||
| 259 | * @throws \Doctrine\ORM\OptimisticLockException |
||
| 260 | * @throws \Doctrine\ORM\TransactionRequiredException |
||
| 261 | */ |
||
| 262 | protected function fetchAssociationEntity($className, $id) |
||
| 270 | } |
||
| 271 |
If you access a property on an interface, you most likely code against a concrete implementation of the interface.
Available Fixes
Adding an additional type check:
Changing the type hint: