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 |
||
39 | abstract class AbstractPathMappingRepository extends AbstractEditableRepository |
||
40 | { |
||
41 | /** |
||
42 | * @var KeyValueStore |
||
43 | */ |
||
44 | protected $store; |
||
45 | |||
46 | /** |
||
47 | * @var string |
||
48 | */ |
||
49 | protected $baseDirectory; |
||
50 | |||
51 | /** |
||
52 | * Creates a new repository. |
||
53 | * |
||
54 | * @param KeyValueStore $store The store of all the paths. |
||
55 | * @param string $baseDirectory The base directory of the resources of this repository. |
||
56 | * @param ChangeStream|null $changeStream If provided, the repository will log |
||
57 | * resources changes in this change stream. |
||
58 | */ |
||
59 | 177 | public function __construct(KeyValueStore $store, $baseDirectory, ChangeStream $changeStream = null) |
|
60 | { |
||
61 | 177 | parent::__construct($changeStream); |
|
62 | |||
63 | 177 | $this->store = $store; |
|
64 | 177 | $this->baseDirectory = $baseDirectory; |
|
65 | |||
66 | 177 | $this->createRoot(); |
|
67 | 177 | } |
|
68 | |||
69 | /** |
||
70 | * {@inheritdoc} |
||
71 | */ |
||
72 | 150 | public function add($path, $resource) |
|
92 | |||
93 | /** |
||
94 | * Add the resource (internal method after checks of add()). |
||
95 | * |
||
96 | * @param string $path |
||
97 | * @param PuliResource $resource |
||
98 | */ |
||
99 | 144 | private function addResource($path, $resource) |
|
100 | { |
||
101 | 144 | if (!($resource instanceof FilesystemResource || $resource instanceof LinkResource)) { |
|
102 | 2 | throw new UnsupportedResourceException(sprintf( |
|
103 | 2 | 'PathMapping repositories only supports FilesystemResource and LinkedResource. Got: %s', |
|
104 | 2 | is_object($resource) ? get_class($resource) : gettype($resource) |
|
105 | 2 | )); |
|
106 | } |
||
107 | |||
108 | // Don't modify resources attached to other repositories |
||
109 | 142 | if ($resource->isAttached()) { |
|
110 | 4 | $resource = clone $resource; |
|
111 | 4 | } |
|
112 | |||
113 | 142 | if ($resource instanceof LinkResource) { |
|
114 | 4 | $this->addLinkResource($path, $resource); |
|
115 | 142 | } elseif (Path::isBasePath($this->baseDirectory, $resource->getFilesystemPath())) { |
|
116 | 140 | $this->addFilesystemResource($path, $resource); |
|
117 | 140 | } else { |
|
118 | 2 | throw new UnsupportedResourceException(sprintf( |
|
119 | 2 | 'Can only add resources from %s. Tried to add %s.', |
|
120 | 2 | $this->baseDirectory, |
|
121 | 2 | $resource->getFilesystemPath() |
|
122 | 2 | )); |
|
123 | } |
||
124 | |||
125 | 140 | $this->appendToChangeStream($resource); |
|
126 | 140 | } |
|
127 | |||
128 | /** |
||
129 | * Add the filesystem resource. |
||
130 | * |
||
131 | * @param string $path |
||
132 | * @param FilesystemResource $resource |
||
133 | */ |
||
134 | abstract protected function addFilesystemResource($path, FilesystemResource $resource); |
||
135 | |||
136 | /** |
||
137 | * Add the link resource. |
||
138 | * |
||
139 | * @param string $path |
||
140 | * @param LinkResource $resource |
||
141 | */ |
||
142 | abstract protected function addLinkResource($path, LinkResource $resource); |
||
143 | |||
144 | /** |
||
145 | * {@inheritdoc} |
||
146 | */ |
||
147 | 2 | public function clear() |
|
157 | |||
158 | /** |
||
159 | * Recursively creates a directory for a path. |
||
160 | * |
||
161 | * @param string $path A directory path. |
||
162 | */ |
||
163 | 144 | protected function ensureDirectoryExists($path) |
|
176 | |||
177 | /** |
||
178 | * Create the repository root. |
||
179 | */ |
||
180 | 177 | protected function createRoot() |
|
188 | |||
189 | /** |
||
190 | * Count the number of elements in the store. |
||
191 | * |
||
192 | * @return int |
||
193 | */ |
||
194 | 9 | protected function countStore() |
|
202 | |||
203 | /** |
||
204 | * Sort the store by keys. |
||
205 | */ |
||
206 | 140 | protected function sortStore() |
|
214 | |||
215 | /** |
||
216 | * Create a filesystem or generic resource. |
||
217 | * |
||
218 | * @param string|null $filesystemPath |
||
219 | * |
||
220 | * @return DirectoryResource|FileResource|GenericResource |
||
221 | */ |
||
222 | 90 | protected function createResource($filesystemPath, $path = null) |
|
223 | { |
||
224 | // Link resource |
||
225 | 90 | if (0 === strpos($filesystemPath, 'l:')) { |
|
226 | 4 | return $this->createLinkResource(substr($filesystemPath, 2), $path); |
|
227 | } |
||
228 | |||
229 | // Filesystem resource |
||
230 | 90 | if (is_string($filesystemPath)) { |
|
231 | 88 | $filesystemPath = $this->resolveRelativePath($filesystemPath); |
|
232 | |||
233 | 88 | if (file_exists($filesystemPath)) { |
|
234 | 88 | return $this->createFilesystemResource($filesystemPath, $path); |
|
235 | } |
||
236 | 1 | } |
|
237 | |||
238 | 12 | return $this->createVirtualResource($path); |
|
239 | } |
||
240 | |||
241 | /** |
||
242 | * Create a link resource to another resource of the repository. |
||
243 | * |
||
244 | * @param string $targetPath The target path. |
||
245 | * @param string|null $path The repository path. |
||
246 | * |
||
247 | * @return LinkResource The link resource. |
||
248 | * |
||
249 | * @throws RuntimeException If the targeted resource does not exist. |
||
250 | */ |
||
251 | 4 | protected function createLinkResource($targetPath, $path = null) |
|
258 | |||
259 | /** |
||
260 | * Create a resource using its filesystem path. |
||
261 | * |
||
262 | * If the filesystem path is a directory, a DirectoryResource will be created. |
||
263 | * If the filesystem path is a file, a FileResource will be created. |
||
264 | * If the filesystem does not exists, a GenericResource will be created. |
||
265 | * |
||
266 | * @param string $filesystemPath The filesystem path. |
||
267 | * @param string|null $path The repository path. |
||
268 | * |
||
269 | * @return DirectoryResource|FileResource The created resource. |
||
270 | * |
||
271 | * @throws RuntimeException If the file / directory does not exist. |
||
272 | */ |
||
273 | 88 | protected function createFilesystemResource($filesystemPath, $path = null) |
|
294 | |||
295 | /** |
||
296 | * @param string|null $path |
||
297 | * |
||
298 | * @return GenericResource |
||
299 | */ |
||
300 | 12 | protected function createVirtualResource($path = null) |
|
307 | |||
308 | /** |
||
309 | * Transform a relative path into an absolute path. |
||
310 | * |
||
311 | * @param string $relativePath |
||
312 | * |
||
313 | * @return string |
||
314 | */ |
||
315 | 93 | protected function resolveRelativePath($relativePath) |
|
324 | |||
325 | /** |
||
326 | * Transform a collection of relative paths into a collection of absolute paths. |
||
327 | * |
||
328 | * @param string[] $relativePaths |
||
329 | * |
||
330 | * @return string[] |
||
331 | */ |
||
332 | 58 | protected function resolveRelativePaths($relativePaths) |
|
340 | } |
||
341 |