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 |
||
| 31 | class QueryOperations { |
||
| 32 | |||
| 33 | /** |
||
| 34 | * |
||
| 35 | * @var RecordWrapper |
||
| 36 | */ |
||
| 37 | private $wrapper; |
||
| 38 | private $adapter; |
||
| 39 | private $queryParameters; |
||
| 40 | private $pendingMethod; |
||
| 41 | private $dynamicMethods = [ |
||
| 42 | "/(?<method>filterBy)(?<variable>[A-Z][A-Za-z]+){1}/", |
||
| 43 | "/(?<method>sort)(?<direction>Asc|Desc)?(By)(?<variable>[A-Z][A-Za-z]+){1}/", |
||
| 44 | "/(?<method>fetch)(?<first>First)?(With)(?<variable>[A-Za-z]+)/" |
||
| 45 | ]; |
||
| 46 | private $dataOperations; |
||
| 47 | private $driver; |
||
| 48 | |||
| 49 | /** |
||
| 50 | * |
||
| 51 | * @param RecordWrapper $wrapper |
||
| 52 | * @param DriverAdapter $adapter |
||
| 53 | * @param DataOperations $dataOperations |
||
| 54 | */ |
||
| 55 | 35 | View Code Duplication | public function __construct(ORMContext $context, RecordWrapper $wrapper, DriverAdapter $adapter, $dataOperations) { |
| 61 | |||
| 62 | 25 | public function doFetch($id = null) { |
|
| 69 | |||
| 70 | 25 | private function getFetchQueryParameters($arg, $instantiate = true) { |
|
| 71 | 25 | if ($arg instanceof \ntentan\nibii\QueryParameters) { |
|
| 72 | 12 | return $arg; |
|
| 73 | } |
||
| 74 | |||
| 75 | 25 | $parameters = $this->getQueryParameters($instantiate); |
|
| 76 | |||
| 77 | 25 | if (is_numeric($arg)) { |
|
| 78 | 6 | $description = $this->wrapper->getDescription(); |
|
| 79 | 6 | $parameters->addFilter($description->getPrimaryKey()[0], $arg); |
|
| 80 | 6 | $parameters->setFirstOnly(true); |
|
| 81 | 21 | } else if (is_array($arg)) { |
|
| 82 | 6 | foreach ($arg as $field => $value) { |
|
| 83 | 6 | $parameters->addFilter($field, $value); |
|
| 84 | } |
||
| 85 | } |
||
| 86 | |||
| 87 | 25 | return $parameters; |
|
| 88 | } |
||
| 89 | |||
| 90 | /** |
||
| 91 | * |
||
| 92 | * @return \ntentan\nibii\QueryParameters |
||
| 93 | */ |
||
| 94 | 33 | private function getQueryParameters($instantiate = true) { |
|
| 100 | |||
| 101 | 31 | private function resetQueryParameters() { |
|
| 104 | |||
| 105 | 10 | public function doFetchFirst($id = null) { |
|
| 109 | |||
| 110 | 12 | public function doFields() { |
|
| 123 | |||
| 124 | 10 | private function getFilter($arguments) { |
|
| 134 | |||
| 135 | 6 | public function doFilter() { |
|
| 144 | |||
| 145 | 4 | public function doFilterBy() { |
|
| 151 | |||
| 152 | 6 | public function doUpdate($data) { |
|
| 159 | |||
| 160 | public function doDelete($args) { |
||
| 161 | $this->driver->beginTransaction(); |
||
| 162 | $parameters = $this->getFetchQueryParameters($args); |
||
| 163 | |||
| 164 | if ($parameters === null) { |
||
| 165 | $primaryKey = $this->wrapper->getDescription()->getPrimaryKey(); |
||
| 166 | $parameters = $this->getQueryParameters(); |
||
| 167 | $data = $this->wrapper->getData(); |
||
| 168 | $keys = []; |
||
| 169 | |||
| 170 | foreach ($data as $datum) { |
||
| 171 | if ($this->dataOperations->isItemDeletable($primaryKey, $datum)) { |
||
| 172 | $keys[] = $datum[$primaryKey[0]]; |
||
| 173 | } |
||
| 174 | } |
||
| 175 | |||
| 176 | $parameters->addFilter($primaryKey[0], $keys); |
||
| 177 | $this->adapter->delete($parameters); |
||
| 178 | } else { |
||
| 179 | $this->adapter->delete($parameters); |
||
| 180 | } |
||
| 181 | |||
| 182 | $this->driver->commit(); |
||
| 183 | $this->resetQueryParameters(); |
||
| 184 | } |
||
| 185 | |||
| 186 | 10 | public function runDynamicMethod($arguments) { |
|
| 204 | |||
| 205 | 10 | public function initDynamicMethod($method) { |
|
| 218 | |||
| 219 | public function doCount() { |
||
| 222 | |||
| 223 | public function doLimit($numItems) { |
||
| 227 | |||
| 228 | public function doOffset($offset) { |
||
| 232 | |||
| 233 | public function doWith($model) { |
||
| 237 | |||
| 238 | } |
||
| 239 |
Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a
@returnannotation as described here.