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:
Complex classes like ReportingCloud 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 ReportingCloud, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
30 | class ReportingCloud extends AbstractReportingCloud |
||
31 | { |
||
32 | |||
33 | /** |
||
34 | * GET methods |
||
35 | * ================================================================================================================= |
||
36 | */ |
||
37 | |||
38 | /** |
||
39 | * Return an array of merge blocks and merge fields in a template file in template storage. |
||
40 | * |
||
41 | * @param string $templateName Template name |
||
42 | * |
||
43 | * @throws InvalidArgumentException |
||
44 | * |
||
45 | * @return array|null |
||
46 | */ |
||
47 | 1 | public function getTemplateInfo($templateName) |
|
67 | |||
68 | /** |
||
69 | * Return an array of binary data. |
||
70 | * Each record in the array is the binary data of a thumbnail image |
||
71 | * |
||
72 | * @param string $templateName Template name |
||
73 | * @param integer $zoomFactor Zoom factor |
||
74 | * @param integer $fromPage From page |
||
75 | * @param integer $toPage To page |
||
76 | * @param string $imageFormat Image format |
||
77 | * |
||
78 | * @throws InvalidArgumentException |
||
79 | * |
||
80 | * @return array|null |
||
81 | */ |
||
82 | 6 | public function getTemplateThumbnails($templateName, $zoomFactor, $fromPage, $toPage, $imageFormat) |
|
83 | { |
||
84 | 6 | $ret = null; |
|
85 | |||
86 | 6 | StaticValidator::execute($templateName, 'TemplateName'); |
|
87 | 5 | StaticValidator::execute($zoomFactor , 'ZoomFactor'); |
|
88 | 4 | StaticValidator::execute($fromPage , 'Page'); |
|
89 | 3 | StaticValidator::execute($toPage , 'Page'); |
|
90 | 2 | StaticValidator::execute($imageFormat , 'ImageFormat'); |
|
91 | |||
92 | $query = [ |
||
93 | 1 | 'templateName' => $templateName, |
|
94 | 1 | 'zoomFactor' => $zoomFactor, |
|
95 | 1 | 'fromPage' => $fromPage, |
|
96 | 1 | 'toPage' => $toPage, |
|
97 | 1 | 'imageFormat' => $imageFormat, |
|
98 | 1 | ]; |
|
99 | |||
100 | 1 | $records = $this->get('/templates/thumbnails', $query); |
|
101 | |||
102 | 1 | View Code Duplication | if (is_array($records) && count($records) > 0) { |
|
|||
103 | 1 | $ret = array_map('base64_decode', $records); |
|
104 | 1 | } |
|
105 | |||
106 | 1 | return $ret; |
|
107 | } |
||
108 | |||
109 | /** |
||
110 | * Return the number of templates in template storage |
||
111 | * |
||
112 | * @return integer |
||
113 | */ |
||
114 | 1 | public function getTemplateCount() |
|
118 | |||
119 | /** |
||
120 | * Return an array properties for the templates in template storage |
||
121 | * |
||
122 | * @return array|null |
||
123 | */ |
||
124 | 1 | View Code Duplication | public function getTemplateList() |
125 | { |
||
126 | 1 | $ret = null; |
|
127 | |||
128 | 1 | $propertyMap = new TemplateListPropertyMap(); |
|
129 | |||
130 | 1 | $records = $this->get('/templates/list'); |
|
131 | |||
132 | 1 | if (is_array($records) && count($records) > 0) { |
|
133 | 1 | $ret = $this->buildPropertyMapArray($records, $propertyMap); |
|
134 | 1 | array_walk($ret, function (&$record) { |
|
135 | 1 | $key = 'modified'; |
|
136 | 1 | if (isset($record[$key])) { |
|
137 | 1 | $record[$key] = StaticFilter::execute($record[$key], 'DateTimeToTimestamp'); |
|
138 | 1 | } |
|
139 | 1 | }); |
|
140 | 1 | } |
|
141 | |||
142 | 1 | return $ret; |
|
143 | } |
||
144 | |||
145 | /** |
||
146 | * Return the number of pages in a template in template storage |
||
147 | * |
||
148 | * @param string $templateName Template name |
||
149 | * |
||
150 | * @throws InvalidArgumentException |
||
151 | * |
||
152 | * @return integer |
||
153 | */ |
||
154 | 2 | View Code Duplication | public function getTemplatePageCount($templateName) |
164 | |||
165 | /** |
||
166 | * Return true, if the template exists in template storage |
||
167 | * |
||
168 | * @param string $templateName Template name |
||
169 | * |
||
170 | * @throws InvalidArgumentException |
||
171 | * |
||
172 | * @return bool |
||
173 | */ |
||
174 | 2 | View Code Duplication | public function templateExists($templateName) |
184 | |||
185 | /** |
||
186 | * Return an array of available fonts on the Reporting Cloud service |
||
187 | * |
||
188 | * @return array|null |
||
189 | */ |
||
190 | 1 | public function getFontList() |
|
202 | 1 | ||
203 | 1 | /** |
|
204 | 1 | * Return an array properties for the ReportingCloud account |
|
205 | * |
||
206 | 1 | * @return array|null |
|
207 | */ |
||
208 | View Code Duplication | public function getAccountSettings() |
|
226 | 1 | ||
227 | /** |
||
228 | 1 | * Download the binary data of a template from template storage |
|
229 | * |
||
230 | 1 | * @param string $templateName Template name |
|
231 | 1 | * |
|
232 | 1 | * @throws InvalidArgumentException |
|
233 | * |
||
234 | 1 | * @return null|resource |
|
235 | */ |
||
236 | public function downloadTemplate($templateName) |
||
254 | |||
255 | 8 | /** |
|
256 | 8 | * Execute a GET request via REST client |
|
257 | 8 | * |
|
258 | * @param string $uri URI |
||
259 | 8 | * @param array $query Query |
|
260 | * |
||
261 | * @return mixed|null |
||
262 | */ |
||
263 | protected function get($uri, $query = []) |
||
279 | 13 | ||
280 | |||
281 | 13 | /** |
|
282 | 10 | * POST methods |
|
283 | * ================================================================================================================= |
||
284 | 9 | */ |
|
285 | 9 | ||
286 | /** |
||
287 | * Upload a template to template storage |
||
288 | 9 | * |
|
289 | 9 | * @param string $templateFilename Template name |
|
290 | * |
||
291 | 9 | * @throws InvalidArgumentException |
|
292 | 9 | * |
|
293 | * @return bool |
||
294 | */ |
||
295 | 9 | public function uploadTemplate($templateFilename) |
|
325 | |||
326 | /** |
||
327 | 1 | * Convert a document on the local file system to a different format |
|
328 | 1 | * |
|
329 | * @param string $documentFilename Document filename |
||
330 | 1 | * @param string $returnFormat Return format |
|
331 | * |
||
332 | 1 | * @throws InvalidArgumentException |
|
333 | 1 | * |
|
334 | * @return null|resource |
||
335 | */ |
||
336 | 1 | public function convertDocument($documentFilename, $returnFormat) |
|
366 | |||
367 | 13 | /** |
|
368 | * Merge data into a template and return an array of binary data. |
||
369 | 13 | * Each record in the array is the binary data of one document |
|
370 | 13 | * |
|
371 | * @param array $mergeData Array of merge data |
||
372 | 12 | * @param string $returnFormat Return format |
|
373 | 2 | * @param string $templateName Template name |
|
374 | 1 | * @param string $templateFilename Template filename on local file system |
|
375 | * @param boolean $append Append flag |
||
376 | 11 | * @param array $mergeSettings Array of merge settings |
|
377 | 10 | * |
|
378 | 7 | * @throws InvalidArgumentException |
|
379 | 6 | * |
|
380 | 6 | * @return null|string |
|
381 | */ |
||
382 | 7 | public function mergeDocument($mergeData, $returnFormat, $templateName = null, $templateFilename = null, |
|
445 | |||
446 | 11 | /** |
|
447 | 11 | * Perform find and replace in document and return binary data. |
|
448 | * |
||
449 | 10 | * @param array $findAndReplaceData Array of find and replace data |
|
450 | 2 | * @param string $returnFormat Return format |
|
451 | 1 | * @param string $templateName Template name |
|
452 | * @param string $templateFilename Template filename on local file system |
||
453 | 9 | * @param array $mergeSettings Array of merge settings |
|
454 | 8 | * |
|
455 | 5 | * @throws InvalidArgumentException |
|
456 | 4 | * |
|
457 | 4 | * @return null|string |
|
458 | */ |
||
459 | 5 | public function findAndReplaceDocument($findAndReplaceData, $returnFormat, $templateName = null, |
|
514 | 11 | ||
515 | |||
516 | 11 | /** |
|
517 | * DELETE methods |
||
518 | * ================================================================================================================= |
||
519 | 10 | */ |
|
520 | 10 | ||
521 | /** |
||
522 | * Delete a template in template storage |
||
523 | 10 | * |
|
524 | 10 | * @param string $templateName Template name |
|
525 | * |
||
526 | 10 | * @throws InvalidArgumentException |
|
527 | * |
||
528 | 9 | * @return bool |
|
529 | 9 | */ |
|
530 | 9 | public function deleteTemplate($templateName) |
|
552 | } |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.