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 |
||
36 | class Compare |
||
37 | { |
||
38 | |||
39 | use \danielgp\common_lib\CommonCode, |
||
40 | \danielgp\info_compare\ConfigurationCompare, |
||
41 | \danielgp\info_compare\OutputFormBuilder; |
||
42 | |||
43 | private $informatorInternalArray; |
||
44 | private $localConfiguration; |
||
45 | private $serverConfiguration; |
||
46 | private $config; |
||
47 | |||
48 | public function __construct() |
||
|
|||
49 | { |
||
50 | $this->getConfiguration(); |
||
51 | $this->applicationFlags = [ |
||
52 | 'available_languages' => [ |
||
53 | 'en_US' => 'EN', |
||
54 | 'ro_RO' => 'RO', |
||
55 | ], |
||
56 | 'default_language' => 'ro_RO', |
||
57 | 'name' => 'Info-Compare' |
||
58 | ]; |
||
59 | echo $this->setHeaderHtml(); |
||
60 | $this->setDefaultOptions(); |
||
61 | $rqst = new \Symfony\Component\HttpFoundation\Request; |
||
62 | $this->informatorInternalArray['superGlobals'] = $rqst->createFromGlobals(); |
||
63 | echo $this->setFormOptions(); |
||
64 | if (isset($_GET['Label'])) { |
||
65 | $this->processInfos(); |
||
66 | echo $this->setFormCurlInfos(); |
||
67 | echo $this->setFormInfos(); |
||
68 | } |
||
69 | echo $this->setFooterHtml(); |
||
70 | } |
||
71 | |||
72 | private function displayTableFromMultiLevelArray($firstArray, $secondArray) |
||
73 | { |
||
74 | if ((!is_array($firstArray)) || (!is_array($secondArray))) { |
||
75 | return ''; |
||
76 | } |
||
77 | $firstRow = $this->mergeArraysIntoFirstSecond($firstArray, $secondArray, ['first', 'second']); |
||
78 | $secondRow = $this->mergeArraysIntoFirstSecond($secondArray, $firstArray, ['second', 'first']); |
||
79 | $row = array_merge($firstRow, $secondRow); |
||
80 | ksort($row); |
||
81 | $urlArguments = '?Label=' . $_GET['Label']; |
||
82 | $sString[] = '<table style="width:100%">' |
||
83 | . '<thead><tr>' |
||
84 | . '<th>Identifier</th>' |
||
85 | . '<th><a href="' . $this->config['Servers'][$_GET['localConfig']]['url'] |
||
86 | . $urlArguments . '" target="_blank">' |
||
87 | . $this->config['Servers'][$_GET['localConfig']]['name'] . '</a></th>' |
||
88 | . '<th><a href="' . $this->config['Servers'][$_GET['serverConfig']]['url'] |
||
89 | . $urlArguments . '" target="_blank">' |
||
90 | . $this->config['Servers'][$_GET['serverConfig']]['name'] . '</a></th>' |
||
91 | . '</tr></thead>' |
||
92 | . '<tbody>'; |
||
93 | if ($_GET['displayOnlyDifferent'] == '1') { |
||
94 | $displayOnlyDifferent = true; |
||
95 | } else { |
||
96 | $displayOnlyDifferent = false; |
||
97 | } |
||
98 | foreach ($row as $key => $value) { |
||
99 | $rowString = '<tr><td style="width:20%;">' . $key . '</td><td style="width:40%;">' |
||
100 | . str_replace(',', ', ', $value['first']) . '</td><td style="width:40%;">' |
||
101 | . str_replace(',', ', ', $value['second']) . '</td></tr>'; |
||
102 | if ($displayOnlyDifferent) { |
||
103 | if ($value['first'] != $value['second']) { |
||
104 | $sString[] = $rowString; |
||
105 | } |
||
106 | } else { |
||
107 | $sString[] = $rowString; |
||
108 | } |
||
109 | } |
||
110 | $sString[] = '</tbody></table>'; |
||
111 | return implode('', $sString); |
||
112 | } |
||
113 | |||
114 | private function getConfiguration() |
||
115 | { |
||
116 | $storedConfiguration = $this->configuredDeployedInformators(); |
||
117 | foreach ($storedConfiguration['informators'] as $key => $value) { |
||
118 | $this->config['Servers'][] = [ |
||
119 | 'name' => $key, |
||
120 | 'url' => $value, |
||
121 | ]; |
||
122 | } |
||
123 | $haystack = array_keys($storedConfiguration['informators']); |
||
124 | $this->config['Defaults']['Label'] = $storedConfiguration['default']['label']; |
||
125 | $this->config['Defaults']['Source'] = array_search($storedConfiguration['default']['source'], $haystack); |
||
126 | $this->config['Defaults']['Target'] = array_search($storedConfiguration['default']['target'], $haystack); |
||
127 | $this->config['Defaults']['ResultsType'] = $storedConfiguration['default']['typeOfResults']; |
||
128 | } |
||
129 | |||
130 | private function mergeArraysIntoFirstSecond($firstArray, $secondArray, $pSequence = ['first', 'second']) |
||
179 | |||
180 | private function processInfos() |
||
181 | { |
||
182 | if (isset($_GET['localConfig']) && isset($_GET['serverConfig'])) { |
||
183 | $urlArguments = '?Label=' . urlencode($_GET['Label']); |
||
184 | $source = $this->config['Servers'][$_GET['localConfig']]['url'] . $urlArguments; |
||
185 | $this->localConfiguration = $this->getContentFromUrlThroughCurlAsArrayIfJson($source); |
||
186 | $destination = $this->config['Servers'][$_GET['serverConfig']]['url'] . $urlArguments; |
||
187 | $this->serverConfiguration = $this->getContentFromUrlThroughCurlAsArrayIfJson($destination); |
||
188 | } else { |
||
189 | $this->localConfiguration = ['response' => '', 'info' => '']; |
||
190 | $this->serverConfiguration = ['response' => '', 'info' => '']; |
||
191 | } |
||
192 | } |
||
193 | |||
194 | private function setDefaultOptions() |
||
195 | { |
||
196 | if (!isset($_GET['displayOnlyDifferent'])) { |
||
197 | $_GET['displayOnlyDifferent'] = $this->config['Defaults']['ResultsType']; |
||
198 | } |
||
199 | if (!isset($_GET['localConfig'])) { |
||
200 | $_GET['localConfig'] = $this->config['Defaults']['Source']; |
||
201 | } |
||
202 | if (!isset($_GET['serverConfig'])) { |
||
203 | $_GET['serverConfig'] = $this->config['Defaults']['Target']; |
||
204 | } |
||
205 | if (!isset($_GET['Label'])) { |
||
206 | $_GET['Label'] = $this->config['Defaults']['Label']; |
||
207 | } |
||
208 | } |
||
209 | |||
210 | private function setFooterHtml() |
||
223 | |||
224 | private function setFormCurlInfos() |
||
232 | |||
233 | private function setFormInfos() |
||
243 | |||
244 | private function setHeaderHtml() |
||
245 | { |
||
246 | return $this->setHeaderCommon([ |
||
247 | 'lang' => 'en-US', |
||
248 | 'title' => $this->applicationFlags['name'], |
||
256 | } |
||
257 |
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: