Complex classes like SyncRepositoryPath often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use SyncRepositoryPath, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
31 | class SyncRepositoryPath implements AtomicOperation |
||
32 | { |
||
33 | /** |
||
34 | * @var string |
||
35 | */ |
||
36 | private $repositoryPath; |
||
37 | |||
38 | /** |
||
39 | * @var EditableRepository |
||
40 | */ |
||
41 | private $repo; |
||
42 | |||
43 | /** |
||
44 | * @var PathMappingCollection |
||
45 | */ |
||
46 | private $mappings; |
||
47 | |||
48 | /** |
||
49 | * @var DependencyGraph |
||
50 | */ |
||
51 | private $overrideGraph; |
||
52 | |||
53 | /** |
||
54 | * @var string[][][] |
||
55 | */ |
||
56 | private $enabledFilesystemPathsBefore; |
||
57 | |||
58 | /** |
||
59 | * @var string[][][] |
||
60 | */ |
||
61 | private $enabledFilesystemPathsAfter; |
||
62 | |||
63 | /** |
||
64 | * @param string $repositoryPath |
||
65 | * @param EditableRepository $repo |
||
66 | * @param PathMappingCollection $mappings |
||
67 | * @param DependencyGraph $overrideGraph |
||
68 | */ |
||
69 | 26 | public function __construct($repositoryPath, EditableRepository $repo, PathMappingCollection $mappings, DependencyGraph $overrideGraph) |
|
76 | |||
77 | /** |
||
78 | * Records which mappings are currently enabled for the repository path. |
||
79 | */ |
||
80 | 26 | public function takeSnapshot() |
|
81 | { |
||
82 | 26 | $this->enabledFilesystemPathsBefore = $this->getEnabledFilesystemPaths($this->repositoryPath); |
|
83 | 26 | } |
|
84 | |||
85 | /** |
||
86 | * {@inheritdoc} |
||
87 | */ |
||
88 | 25 | public function execute() |
|
89 | { |
||
90 | 25 | if (null === $this->enabledFilesystemPathsBefore) { |
|
91 | throw new LogicException('takeSnapshot() was not called'); |
||
92 | } |
||
93 | |||
94 | 25 | $this->enabledFilesystemPathsAfter = $this->getEnabledFilesystemPaths($this->repositoryPath); |
|
95 | |||
96 | 25 | $this->sync($this->enabledFilesystemPathsBefore, $this->enabledFilesystemPathsAfter); |
|
97 | 25 | } |
|
98 | |||
99 | /** |
||
100 | * {@inheritdoc} |
||
101 | */ |
||
102 | 6 | public function rollback() |
|
103 | { |
||
104 | 6 | $this->sync($this->enabledFilesystemPathsAfter, $this->enabledFilesystemPathsBefore); |
|
105 | 6 | } |
|
106 | |||
107 | 25 | private function sync(array $filesystemPathsBefore, array $filesystemPathsAfter) |
|
108 | { |
||
109 | 25 | if (!$filesystemPathsBefore && $filesystemPathsAfter) { |
|
110 | 6 | $this->add($this->repositoryPath, $filesystemPathsAfter); |
|
111 | 20 | } elseif ($filesystemPathsBefore && !$filesystemPathsAfter) { |
|
112 | 5 | $this->remove($this->repositoryPath); |
|
113 | 15 | } elseif ($filesystemPathsBefore && $filesystemPathsAfter) { |
|
114 | 14 | $this->replace($filesystemPathsBefore, $filesystemPathsAfter); |
|
115 | } |
||
116 | 25 | } |
|
117 | |||
118 | 14 | private function remove($repositoryPath) |
|
119 | { |
||
120 | 14 | $this->repo->remove($repositoryPath); |
|
121 | 14 | } |
|
122 | |||
123 | 15 | private function add($repositoryPath, array $filesystemPaths) |
|
124 | { |
||
125 | try { |
||
126 | 15 | $this->addInOrder($filesystemPaths); |
|
127 | } catch (Exception $e) { |
||
128 | $this->repo->remove($repositoryPath); |
||
129 | |||
130 | throw $e; |
||
131 | } |
||
132 | 15 | } |
|
133 | |||
134 | 20 | private function addInOrder(array $filesystemPaths) |
|
135 | { |
||
136 | 20 | foreach ($filesystemPaths as $moduleName => $filesystemPathsByRepoPath) { |
|
137 | 20 | foreach ($filesystemPathsByRepoPath as $repoPath => $filesystemPaths) { |
|
138 | 20 | foreach ($filesystemPaths as $filesystemPath) { |
|
139 | 20 | $this->repo->add($repoPath, $this->createResource($filesystemPath)); |
|
140 | } |
||
141 | } |
||
142 | } |
||
143 | 20 | } |
|
144 | |||
145 | 14 | private function replace(array $filesystemPathsBefore, array $filesystemPathsAfter) |
|
178 | |||
179 | 20 | private function createResource($filesystemPath) |
|
180 | { |
||
181 | 20 | return is_dir($filesystemPath) |
|
182 | 19 | ? new DirectoryResource($filesystemPath) |
|
183 | 20 | : new FileResource($filesystemPath); |
|
184 | } |
||
185 | |||
186 | 9 | private function getShortestRepositoryPath(array $filesystemPathsBefore, array $filesystemPathsAfter) |
|
187 | { |
||
188 | 9 | $repositoryPaths = array(); |
|
189 | |||
190 | 9 | foreach ($filesystemPathsBefore as $filesystemPathsByRepoPaths) { |
|
191 | 9 | foreach ($filesystemPathsByRepoPaths as $repoPath => $filesystemPath) { |
|
192 | 9 | $repositoryPaths[$repoPath] = true; |
|
193 | } |
||
194 | } |
||
195 | |||
196 | 9 | foreach ($filesystemPathsAfter as $filesystemPathsByRepoPaths) { |
|
197 | 9 | foreach ($filesystemPathsByRepoPaths as $repoPath => $filesystemPath) { |
|
198 | 9 | $repositoryPaths[$repoPath] = true; |
|
199 | } |
||
200 | } |
||
201 | |||
202 | 9 | ksort($repositoryPaths); |
|
203 | 9 | reset($repositoryPaths); |
|
204 | |||
205 | 9 | return key($repositoryPaths); |
|
206 | } |
||
207 | |||
208 | 26 | private function getEnabledFilesystemPaths($repositoryPath) |
|
239 | |||
240 | /** |
||
241 | * @param string $repositoryPath |
||
242 | * @param PathMapping[][] $inMappings |
||
243 | * @param PathMapping[][] $outMappings |
||
244 | * @param bool[] $processedPaths |
||
245 | */ |
||
246 | 26 | private function filterEnabledMappings($repositoryPath, array &$inMappings, array &$outMappings, array &$processedPaths = array()) |
|
291 | } |
||
292 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.