Complex classes like JsonStorage 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 JsonStorage, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
12 | class JsonStorage implements Storage |
||
13 | { |
||
14 | private $storagePath; |
||
15 | private $repository; |
||
16 | |||
17 | /** |
||
18 | * JsonStorage constructor. |
||
19 | * |
||
20 | * @param $storagePath |
||
21 | */ |
||
22 | public function __construct($storagePath) |
||
27 | |||
28 | /** |
||
29 | * Retrieve the data from the storagepath |
||
30 | * so it can be interacted with |
||
31 | * |
||
32 | * @throws \Exception |
||
33 | */ |
||
34 | private function config() |
||
45 | |||
46 | /** |
||
47 | * @return array |
||
48 | */ |
||
49 | public function getApplicationComponents() |
||
53 | |||
54 | /** |
||
55 | * Get user by username |
||
56 | * |
||
57 | * @param $username |
||
58 | * |
||
59 | * @return array |
||
60 | */ |
||
61 | public function getUserByUsername($username) |
||
75 | |||
76 | public function getUserBySlug($slug) |
||
90 | |||
91 | public function getUsers() |
||
95 | |||
96 | public function saveUser($slug, $postValues) |
||
115 | |||
116 | public function addUser($postValues) |
||
127 | |||
128 | public function deleteUserBySlug($slug) |
||
143 | |||
144 | private function createUserFromPostValues($postValues) |
||
169 | |||
170 | /* |
||
171 | * |
||
172 | * Documents |
||
173 | * |
||
174 | */ |
||
175 | /** |
||
176 | * Get documents |
||
177 | * |
||
178 | * @return array |
||
179 | */ |
||
180 | public function getDocuments() |
||
184 | |||
185 | /** |
||
186 | * @param string $slug |
||
187 | * @return mixed |
||
188 | * @throws \Exception |
||
189 | */ |
||
190 | public function getDocumentBySlug($slug) |
||
191 | { |
||
192 | $documentContainer = $this->getDocumentContainerByPath('/' . $slug); |
||
193 | $indices = $documentContainer['indices']; |
||
194 | |||
195 | if ($indices === null) { |
||
196 | $emptyReturn = new \stdClass(); |
||
197 | $emptyReturn->title = 'Not found'; |
||
198 | $emptyReturn->type = null; |
||
199 | $emptyReturn->state = 'published'; |
||
200 | return $emptyReturn; |
||
201 | } |
||
202 | |||
203 | $folder = $this->repository->documents; |
||
204 | foreach ($indices as $index) { |
||
205 | if ($folder === $this->repository->documents) { |
||
206 | $folder = $folder[$index]; |
||
207 | } else { |
||
208 | $folder = $folder->content[$index]; |
||
209 | } |
||
210 | } |
||
211 | |||
212 | return $folder; |
||
213 | } |
||
214 | |||
215 | public function saveDocument($postValues) |
||
216 | { |
||
217 | $documentFolderObject = $this->createDocumentFromPostValues($postValues); |
||
218 | |||
219 | $documentContainer = $this->getDocumentContainerByPath($_GET['slug']); |
||
220 | $indices = $documentContainer['indices']; |
||
221 | |||
222 | $folder = $this->repository->documents; |
||
223 | $previousFolder = $this->repository->documents; |
||
224 | foreach ($indices as $index) { |
||
225 | if ($folder === $this->repository->documents) { |
||
226 | $folder = $folder[$index]; |
||
227 | } else { |
||
228 | $previousFolder = $folder; |
||
229 | $folder = $folder->content[$index]; |
||
230 | } |
||
231 | } |
||
232 | |||
233 | if ($previousFolder === $this->repository->documents) { |
||
234 | // Check for duplicates |
||
235 | foreach ($this->repository->documents as $index => $document) { |
||
236 | if (end($indices) !== $index && $document->slug == $documentFolderObject->slug && $document->type == 'document') { |
||
237 | throw new \Exception('Duplicate slug: ' . $document->slug . ' in folder ' . $postValues['path']); |
||
238 | } |
||
239 | } |
||
240 | $this->repository->documents[end($indices)] = $documentFolderObject; |
||
241 | } else { |
||
242 | // Check for duplicates |
||
243 | foreach ($previousFolder->content as $index => $document) { |
||
244 | if (end($indices) !== $index && $document->slug == $documentFolderObject->slug && $document->type == 'document') { |
||
245 | throw new \Exception('Duplicate slug: ' . $document->slug . ' in folder ' . $postValues['path']); |
||
246 | } |
||
247 | } |
||
248 | $previousFolder->content[end($indices)] = $documentFolderObject ; |
||
249 | } |
||
250 | |||
251 | $this->save(); |
||
252 | } |
||
253 | |||
254 | public function addDocument($postValues) |
||
255 | { |
||
256 | $documentFolderObject = $this->createDocumentFromPostValues($postValues); |
||
257 | if ($postValues['path'] == '' || $postValues['path'] == '/') { |
||
258 | // Check folder duplicate child |
||
259 | foreach ($this->repository->documents as $document) { |
||
260 | if ($document->slug == $documentFolderObject->slug && $document->type == 'document') { |
||
261 | // TODO make it so it doesnt throw an exception, but instead shows a warning |
||
262 | throw new \Exception('Duplicate slug: ' . $document->slug . ' in folder ' . $postValues['path']); |
||
263 | } |
||
264 | } |
||
265 | $this->repository->documents[] = $documentFolderObject; |
||
266 | } else { |
||
267 | // Check folder duplicate child |
||
268 | $containerFolder = $this->getDocumentFolderBySlug($postValues['path']); |
||
269 | if (isset($containerFolder->content)) { |
||
270 | foreach ($containerFolder->content as $document) { |
||
271 | if ($document->slug == $documentFolderObject->slug && $document->type == 'document') { |
||
272 | // TODO make it so it doesnt throw an exception, but instead shows a warning |
||
273 | throw new \Exception('Duplicate slug: ' . $document->slug . ' in folder ' . $postValues['path']); |
||
274 | } |
||
275 | } |
||
276 | } |
||
277 | $containerFolder->content[] = $documentFolderObject; |
||
278 | } |
||
279 | $this->save(); |
||
280 | } |
||
281 | |||
282 | public function deleteDocumentBySlug($slug) |
||
308 | |||
309 | private function createDocumentFromPostValues($postValues) |
||
310 | { |
||
311 | $documentType = $this->getDocumentTypeBySlug($postValues['documentType']); |
||
372 | |||
373 | /** |
||
374 | * Add new document in given path |
||
375 | * |
||
376 | * @param array $postValues |
||
377 | * |
||
378 | * @throws \Exception |
||
379 | */ |
||
380 | public function addDocumentFolder($postValues) |
||
416 | |||
417 | /** |
||
418 | * Delete a folder by its compound slug |
||
419 | * |
||
420 | * @param $slug |
||
421 | * |
||
422 | * @throws \Exception |
||
423 | */ |
||
424 | public function deleteDocumentFolderBySlug($slug) |
||
450 | |||
451 | /** |
||
452 | * Retrieve a folder by its compound slug |
||
453 | * |
||
454 | * @param $slug |
||
455 | * |
||
456 | * @return mixed |
||
457 | * @throws \Exception |
||
458 | */ |
||
459 | public function getDocumentFolderBySlug($slug) |
||
475 | |||
476 | /** |
||
477 | * Save changes to folder |
||
478 | * |
||
479 | * @param $postValues |
||
480 | * |
||
481 | * @throws \Exception |
||
482 | */ |
||
483 | public function saveDocumentFolder($postValues) |
||
521 | |||
522 | /** |
||
523 | * Convert path to indeces |
||
524 | * |
||
525 | * @param $path |
||
526 | * |
||
527 | * @return array |
||
528 | * @throws \Exception |
||
529 | */ |
||
530 | private function getDocumentContainerByPath($path) |
||
589 | |||
590 | /** |
||
591 | * Create folder from post values |
||
592 | * |
||
593 | * @param $postValues |
||
594 | * |
||
595 | * @return \stdClass |
||
596 | * @throws \Exception |
||
597 | */ |
||
598 | private function createDocumentFolderFromPostValues($postValues) |
||
612 | |||
613 | /* |
||
614 | * |
||
615 | * Sitemap |
||
616 | * |
||
617 | */ |
||
618 | /** |
||
619 | * @return array |
||
620 | */ |
||
621 | public function getSitemap() |
||
625 | |||
626 | /** |
||
627 | * Add a sitemap item |
||
628 | * |
||
629 | * @param $postValues |
||
630 | * |
||
631 | * @throws \Exception |
||
632 | */ |
||
633 | public function addSitemapItem($postValues) |
||
640 | |||
641 | /** |
||
642 | * Save changes to a sitemap item |
||
643 | * |
||
644 | * @param $slug |
||
645 | * @param $postValues |
||
646 | * |
||
647 | * @throws \Exception |
||
648 | */ |
||
649 | public function saveSitemapItem($slug, $postValues) |
||
662 | |||
663 | /** |
||
664 | * Delete a sitemap item by its slug |
||
665 | * |
||
666 | * @param $slug |
||
667 | * |
||
668 | * @throws \Exception |
||
669 | */ |
||
670 | public function deleteSitemapItemBySlug($slug) |
||
682 | |||
683 | /** |
||
684 | * Create a sitemap item from post values |
||
685 | * |
||
686 | * @param $postValues |
||
687 | * |
||
688 | * @return \stdClass |
||
689 | * @throws \Exception |
||
690 | */ |
||
691 | private function createSitemapItemFromPostValues($postValues) |
||
712 | |||
713 | /** |
||
714 | * Save changes to a sitemap item |
||
715 | * |
||
716 | * @param $postValues |
||
717 | * |
||
718 | * @throws \Exception |
||
719 | */ |
||
720 | public function saveSitemap($postValues) |
||
735 | |||
736 | /** |
||
737 | * Get a sitemap item by its slug |
||
738 | * |
||
739 | * @param $slug |
||
740 | * |
||
741 | * @return mixed |
||
742 | */ |
||
743 | public function getSitemapItemBySlug($slug) |
||
753 | |||
754 | /* |
||
755 | * |
||
756 | * Images |
||
757 | * |
||
758 | */ |
||
759 | /** |
||
760 | * Get all images |
||
761 | * |
||
762 | * @return array |
||
763 | */ |
||
764 | public function getImages() |
||
768 | |||
769 | public function addImage($postValues) |
||
796 | |||
797 | public function deleteImageByName($filename) |
||
820 | |||
821 | /** |
||
822 | * @param $filename |
||
823 | * @return null |
||
824 | */ |
||
825 | public function getImageByName($filename) |
||
835 | |||
836 | /* |
||
837 | * |
||
838 | * Files |
||
839 | * |
||
840 | */ |
||
841 | /** |
||
842 | * Get all files |
||
843 | * |
||
844 | * @return array |
||
845 | */ |
||
846 | public function getFiles() |
||
852 | |||
853 | private function compareFiles($a, $b) |
||
857 | |||
858 | public function addFile($postValues) |
||
881 | |||
882 | private function validateFilename($filename, $path) |
||
910 | |||
911 | /** |
||
912 | * @param $filename |
||
913 | * @return null |
||
914 | */ |
||
915 | public function getFileByName($filename) |
||
925 | |||
926 | /** |
||
927 | * @param $filename |
||
928 | * @throws \Exception |
||
929 | */ |
||
930 | public function deleteFileByName($filename) |
||
949 | |||
950 | /* |
||
951 | * |
||
952 | * Configuration |
||
953 | * |
||
954 | */ |
||
955 | /** |
||
956 | * @return array |
||
957 | */ |
||
958 | public function getDocumentTypes() |
||
962 | |||
963 | /** |
||
964 | * Add a document type from post values |
||
965 | * |
||
966 | * @param $postValues |
||
967 | * |
||
968 | * @throws \Exception |
||
969 | */ |
||
970 | public function addDocumentType($postValues) |
||
977 | |||
978 | /** |
||
979 | * Create a document type from post values |
||
980 | * |
||
981 | * @param $postValues |
||
982 | * |
||
983 | * @return \stdClass |
||
984 | * @throws \Exception |
||
985 | */ |
||
986 | public function createDocumentTypeFromPostValues($postValues) |
||
1023 | |||
1024 | /** |
||
1025 | * Delete document type |
||
1026 | * |
||
1027 | * @param $slug |
||
1028 | * |
||
1029 | * @throws \Exception |
||
1030 | */ |
||
1031 | public function deleteDocumentTypeBySlug($slug) |
||
1043 | |||
1044 | /** |
||
1045 | * Get document type by its slug |
||
1046 | * |
||
1047 | * @param $slug |
||
1048 | * @param bool $getBricks |
||
1049 | * |
||
1050 | * @return mixed |
||
1051 | */ |
||
1052 | public function getDocumentTypeBySlug($slug, $getBricks = false) |
||
1072 | |||
1073 | /** |
||
1074 | * Save changes to a document type |
||
1075 | * |
||
1076 | * @param $slug |
||
1077 | * @param $postValues |
||
1078 | * |
||
1079 | * @throws \Exception |
||
1080 | */ |
||
1081 | public function saveDocumentType($slug, $postValues) |
||
1094 | |||
1095 | /* |
||
1096 | * |
||
1097 | * Bricks |
||
1098 | * |
||
1099 | */ |
||
1100 | /** |
||
1101 | * @return array |
||
1102 | */ |
||
1103 | public function getBricks() |
||
1107 | |||
1108 | /** |
||
1109 | * Add a brick |
||
1110 | * |
||
1111 | * @param $postValues |
||
1112 | * |
||
1113 | * @throws \Exception |
||
1114 | */ |
||
1115 | public function addBrick($postValues) |
||
1122 | |||
1123 | /** |
||
1124 | * Create a brick from post values |
||
1125 | * |
||
1126 | * @param $postValues |
||
1127 | * |
||
1128 | * @return \stdClass |
||
1129 | * @throws \Exception |
||
1130 | */ |
||
1131 | public function createBrickFromPostValues($postValues) |
||
1155 | |||
1156 | /** |
||
1157 | * Get a brick by its slug |
||
1158 | * |
||
1159 | * @param $slug |
||
1160 | * |
||
1161 | * @return \stdClass |
||
1162 | */ |
||
1163 | public function getBrickBySlug($slug) |
||
1173 | |||
1174 | /** |
||
1175 | * Save changes to a brick |
||
1176 | * |
||
1177 | * @param $slug |
||
1178 | * @param $postValues |
||
1179 | * |
||
1180 | * @throws \Exception |
||
1181 | */ |
||
1182 | public function saveBrick($slug, $postValues) |
||
1195 | |||
1196 | /** |
||
1197 | * Delete a brick by its slug |
||
1198 | * |
||
1199 | * @param $slug |
||
1200 | * |
||
1201 | * @throws \Exception |
||
1202 | */ |
||
1203 | public function deleteBrickBySlug($slug) |
||
1216 | |||
1217 | /* |
||
1218 | * |
||
1219 | * Misc |
||
1220 | * |
||
1221 | */ |
||
1222 | /** |
||
1223 | * Save changes made to the repository |
||
1224 | * in the storagepath |
||
1225 | * |
||
1226 | * @throws \Exception |
||
1227 | */ |
||
1228 | private function save() { |
||
1236 | |||
1237 | /* |
||
1238 | * |
||
1239 | * Image Set |
||
1240 | * |
||
1241 | */ |
||
1242 | |||
1243 | /** |
||
1244 | * Get the image set |
||
1245 | * |
||
1246 | * @return array |
||
1247 | */ |
||
1248 | public function getImageSet() |
||
1252 | |||
1253 | /** |
||
1254 | * Get Image by slug |
||
1255 | * |
||
1256 | * @param $slug |
||
1257 | * |
||
1258 | * @return \stdClass |
||
1259 | */ |
||
1260 | public function getImageSetBySlug($slug) |
||
1270 | |||
1271 | /** |
||
1272 | * Save Image Set by it's slug |
||
1273 | * |
||
1274 | * @param $slug |
||
1275 | * @param $postValues |
||
1276 | * |
||
1277 | * @throws \Exception |
||
1278 | */ |
||
1279 | public function saveImageSet($slug, $postValues) |
||
1292 | |||
1293 | /** |
||
1294 | * Ceate image set from post values |
||
1295 | * |
||
1296 | * @param $postValues |
||
1297 | * |
||
1298 | * @return \stdClass |
||
1299 | * @throws \Exception |
||
1300 | */ |
||
1301 | private function createImageSetFromPostValues($postValues) |
||
1317 | |||
1318 | /** |
||
1319 | * Add image set |
||
1320 | * |
||
1321 | * @param $postValues |
||
1322 | * |
||
1323 | * @throws \Exception |
||
1324 | */ |
||
1325 | public function addImageSet($postValues) |
||
1333 | |||
1334 | /** |
||
1335 | * Delete Image Set by its slug |
||
1336 | * |
||
1337 | * @param $slug |
||
1338 | * |
||
1339 | * @throws \Exception |
||
1340 | */ |
||
1341 | public function deleteImageSetBySlug($slug) |
||
1354 | |||
1355 | /** |
||
1356 | * Get the image set with the smallest size |
||
1357 | * |
||
1358 | * @return \stdClass |
||
1359 | */ |
||
1360 | public function getSmallestImageSet() |
||
1382 | } |
||
1383 | } |
It seems like you are relying on a variable being defined by an iteration: