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 |
||
44 | class InMemoryRepository extends AbstractEditableRepository |
||
45 | { |
||
46 | /** |
||
47 | * @var PuliResource[] |
||
48 | */ |
||
49 | private $resources = array(); |
||
50 | |||
51 | /** |
||
52 | * Create the repository. |
||
53 | * |
||
54 | * @param ChangeStream|null $changeStream If provided, the repository will log |
||
55 | * resources changes in this change stream. |
||
56 | */ |
||
57 | 93 | public function __construct(ChangeStream $changeStream = null) |
|
58 | { |
||
59 | 93 | parent::__construct($changeStream); |
|
60 | |||
61 | 93 | $this->clear(); |
|
62 | 93 | } |
|
63 | |||
64 | /** |
||
65 | * {@inheritdoc} |
||
66 | */ |
||
67 | 46 | public function get($path) |
|
77 | |||
78 | /** |
||
79 | * {@inheritdoc} |
||
80 | */ |
||
81 | 24 | public function find($query, $language = 'glob') |
|
96 | |||
97 | /** |
||
98 | * {@inheritdoc} |
||
99 | */ |
||
100 | 16 | public function contains($query, $language = 'glob') |
|
115 | |||
116 | /** |
||
117 | * {@inheritdoc} |
||
118 | */ |
||
119 | 71 | public function add($path, $resource) |
|
149 | |||
150 | /** |
||
151 | * {@inheritdoc} |
||
152 | */ |
||
153 | 13 | public function remove($query, $language = 'glob') |
|
167 | |||
168 | /** |
||
169 | * {@inheritdoc} |
||
170 | */ |
||
171 | 93 | public function clear() |
|
183 | |||
184 | /** |
||
185 | * {@inheritdoc} |
||
186 | */ |
||
187 | 10 | public function listChildren($path) |
|
193 | |||
194 | /** |
||
195 | * {@inheritdoc} |
||
196 | */ |
||
197 | 6 | public function hasChildren($path) |
|
204 | |||
205 | /** |
||
206 | * Recursively creates a directory for a path. |
||
207 | * |
||
208 | * @param string $path A directory path. |
||
209 | */ |
||
210 | 67 | private function ensureDirectoryExists($path) |
|
211 | { |
||
212 | 67 | if (!isset($this->resources[$path])) { |
|
213 | // Recursively initialize parent directories |
||
214 | 20 | if ($path !== '/') { |
|
215 | 20 | $this->ensureDirectoryExists(Path::getDirectory($path)); |
|
216 | 20 | } |
|
217 | |||
218 | 20 | $this->resources[$path] = new GenericResource($path); |
|
219 | 20 | $this->resources[$path]->attachTo($this); |
|
220 | |||
221 | 20 | return; |
|
222 | } |
||
223 | 67 | } |
|
224 | |||
225 | 67 | private function addResource($path, PuliResource $resource) |
|
226 | { |
||
227 | // Don't modify resources attached to other repositories |
||
228 | 67 | if ($resource->isAttached()) { |
|
229 | 3 | $resource = clone $resource; |
|
230 | 3 | } |
|
231 | |||
232 | 67 | $basePath = '/' === $path ? $path : $path.'/'; |
|
233 | |||
234 | // Read children before attaching the resource to this repository |
||
235 | 67 | $children = $resource->listChildren(); |
|
236 | |||
237 | 67 | $resource->attachTo($this, $path); |
|
238 | |||
239 | // Add the resource before adding its children, so that the array |
||
240 | // stays sorted |
||
241 | 67 | $this->resources[$path] = $resource; |
|
242 | |||
243 | 67 | foreach ($children as $name => $child) { |
|
244 | 29 | $this->addResource($basePath.$name, $child); |
|
245 | 67 | } |
|
246 | |||
247 | 67 | $this->appendToChangeStream($resource); |
|
248 | 67 | } |
|
249 | |||
250 | 7 | private function removeResource(PuliResource $resource) |
|
269 | |||
270 | /** |
||
271 | * Returns an iterator for the children of a resource. |
||
272 | * |
||
273 | * @param PuliResource $resource The resource. |
||
274 | * |
||
275 | * @return RegexFilterIterator The iterator. |
||
276 | */ |
||
277 | 14 | View Code Duplication | private function getChildIterator(PuliResource $resource) |
289 | |||
290 | /** |
||
291 | * Returns an iterator for a glob. |
||
292 | * |
||
293 | * @param string $glob The glob. |
||
294 | * |
||
295 | * @return GlobFilterIterator The iterator. |
||
296 | */ |
||
297 | 8 | protected function getGlobIterator($glob) |
|
305 | } |
||
306 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.