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
@return
annotation as described here.