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 |
||
| 50 | class OptimizedPathMappingRepository extends AbstractPathMappingRepository implements EditableRepository |
||
| 51 | { |
||
| 52 | /** |
||
| 53 | * {@inheritdoc} |
||
| 54 | */ |
||
| 55 | 47 | public function get($path) |
|
| 65 | |||
| 66 | /** |
||
| 67 | * {@inheritdoc} |
||
| 68 | */ |
||
| 69 | 11 | public function find($query, $language = 'glob') |
|
| 70 | { |
||
| 71 | 11 | $this->validateSearchLanguage($language); |
|
| 72 | |||
| 73 | 10 | $query = $this->sanitizePath($query); |
|
| 74 | 7 | $resources = new ArrayResourceCollection(); |
|
| 75 | |||
| 76 | 7 | if (Glob::isDynamic($query)) { |
|
| 77 | 5 | $resources = $this->iteratorToCollection($this->getGlobIterator($query)); |
|
| 78 | 2 | } elseif ($this->store->exists($query)) { |
|
| 79 | 2 | $resources = new ArrayResourceCollection(array( |
|
| 80 | 2 | $this->createResource($this->store->get($query), $query), |
|
| 81 | )); |
||
| 82 | } |
||
| 83 | |||
| 84 | 7 | return $resources; |
|
| 85 | } |
||
| 86 | |||
| 87 | /** |
||
| 88 | * {@inheritdoc} |
||
| 89 | */ |
||
| 90 | 19 | public function contains($query, $language = 'glob') |
|
| 107 | |||
| 108 | /** |
||
| 109 | * {@inheritdoc} |
||
| 110 | */ |
||
| 111 | 13 | public function remove($query, $language = 'glob') |
|
| 112 | { |
||
| 113 | 13 | $this->validateSearchLanguage($language); |
|
| 114 | |||
| 115 | 12 | $query = $this->sanitizePath($query); |
|
| 116 | |||
| 117 | 9 | Assert::notEmpty(trim($query, '/'), 'The root directory cannot be removed.'); |
|
| 118 | |||
| 119 | // Find resources to remove |
||
| 120 | // (more efficient that find() as we do not need to unserialize them) |
||
| 121 | 7 | $paths = array(); |
|
| 122 | |||
| 123 | 7 | if (Glob::isDynamic($query)) { |
|
| 124 | 2 | $paths = $this->getGlobIterator($query); |
|
| 125 | 5 | } elseif ($this->store->exists($query)) { |
|
| 126 | 5 | $paths = array($query); |
|
| 127 | } |
||
| 128 | |||
| 129 | // Remove the resources found |
||
| 130 | 7 | $nbOfResources = $this->countStore(); |
|
| 131 | |||
| 132 | 7 | foreach ($paths as $path) { |
|
| 133 | 7 | $this->removePath($path); |
|
| 134 | } |
||
| 135 | |||
| 136 | 7 | return $nbOfResources - $this->countStore(); |
|
| 137 | } |
||
| 138 | |||
| 139 | /** |
||
| 140 | * {@inheritdoc} |
||
| 141 | */ |
||
| 142 | 11 | public function listChildren($path) |
|
| 148 | |||
| 149 | /** |
||
| 150 | * {@inheritdoc} |
||
| 151 | */ |
||
| 152 | 7 | public function hasChildren($path) |
|
| 159 | |||
| 160 | /** |
||
| 161 | * @param string $path |
||
| 162 | * @param FilesystemResource $resource |
||
| 163 | */ |
||
| 164 | 68 | protected function addFilesystemResource($path, FilesystemResource $resource) |
|
| 165 | { |
||
| 166 | // Read children before attaching the resource to this repository |
||
| 167 | 68 | $children = $resource->listChildren(); |
|
| 168 | |||
| 169 | 68 | $resource->attachTo($this, $path); |
|
| 170 | |||
| 171 | // Add the resource before adding its children, so that the array stays sorted |
||
| 172 | 68 | $this->store->set($path, Path::makeRelative($resource->getFilesystemPath(), $this->baseDirectory)); |
|
| 173 | |||
| 174 | 68 | $basePath = '/' === $path ? $path : $path.'/'; |
|
| 175 | |||
| 176 | 68 | foreach ($children as $name => $child) { |
|
| 177 | 31 | $this->addFilesystemResource($basePath.$name, $child); |
|
| 178 | } |
||
| 179 | 68 | } |
|
| 180 | |||
| 181 | /** |
||
| 182 | * {@inheritdoc} |
||
| 183 | */ |
||
| 184 | 2 | protected function addLinkResource($path, LinkResource $resource) |
|
| 189 | |||
| 190 | /** |
||
| 191 | * @param string $path |
||
| 192 | */ |
||
| 193 | 7 | private function removePath($path) |
|
| 209 | |||
| 210 | /** |
||
| 211 | * Returns an iterator for the children paths of a resource. |
||
| 212 | * |
||
| 213 | * @param PuliResource $resource The resource. |
||
| 214 | * |
||
| 215 | * @return RegexFilterIterator The iterator of paths. |
||
| 216 | */ |
||
| 217 | 9 | View Code Duplication | private function getChildIterator(PuliResource $resource) |
| 228 | |||
| 229 | /** |
||
| 230 | * Returns a recursive iterator for the children paths under a given path. |
||
| 231 | * |
||
| 232 | * @param string $path The path. |
||
| 233 | * |
||
| 234 | * @return RegexFilterIterator The iterator of paths. |
||
| 235 | */ |
||
| 236 | 7 | View Code Duplication | private function getRecursivePathChildIterator($path) |
| 247 | |||
| 248 | /** |
||
| 249 | * Returns an iterator for a glob. |
||
| 250 | * |
||
| 251 | * @param string $glob The glob. |
||
| 252 | * |
||
| 253 | * @return GlobFilterIterator The iterator of paths. |
||
| 254 | */ |
||
| 255 | 8 | private function getGlobIterator($glob) |
|
| 262 | |||
| 263 | /** |
||
| 264 | * Transform an iterator of paths into a collection of resources. |
||
| 265 | * |
||
| 266 | * @param Iterator $iterator |
||
| 267 | * |
||
| 268 | * @return ArrayResourceCollection |
||
| 269 | */ |
||
| 270 | 12 | private function iteratorToCollection(Iterator $iterator) |
|
| 281 | } |
||
| 282 |