Total Complexity | 45 |
Total Lines | 385 |
Duplicated Lines | 0 % |
Changes | 9 | ||
Bugs | 0 | Features | 0 |
Complex classes like CheckAllTemplatesResponseController 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.
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 CheckAllTemplatesResponseController, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
29 | class CheckAllTemplatesResponseController extends Controller implements Flushable |
||
30 | { |
||
31 | /** |
||
32 | * Defines methods that can be called directly. |
||
33 | * |
||
34 | * @var array |
||
35 | */ |
||
36 | private static $allowed_actions = [ |
||
37 | 'testone' => 'ADMIN', |
||
38 | ]; |
||
39 | |||
40 | private static $use_default_admin = true; |
||
41 | |||
42 | private static $username = ''; |
||
43 | |||
44 | private static $password = ''; |
||
45 | |||
46 | private static $url_segment = 'admin/templateoverviewsmoketestresponse'; |
||
47 | |||
48 | private static $use_w3_validation = false; |
||
49 | |||
50 | private static $create_diff = false; |
||
51 | |||
52 | private $guzzleCookieJar; |
||
53 | |||
54 | private $guzzleClient; |
||
55 | |||
56 | private $guzzleHasError = false; |
||
57 | |||
58 | private $isSuccess = false; |
||
59 | |||
60 | /** |
||
61 | * temporary Admin used to log in. |
||
62 | * |
||
63 | * @var Member |
||
64 | */ |
||
65 | private $member; |
||
66 | |||
67 | private $rawResponse = ''; |
||
68 | |||
69 | /** |
||
70 | * @var bool |
||
71 | */ |
||
72 | private $debug = false; |
||
73 | |||
74 | public static function flush() |
||
75 | { |
||
76 | $cache = Injector::inst()->get(CacheInterface::class . '.templateoverview'); |
||
77 | $cache->clear(); |
||
78 | } |
||
79 | |||
80 | public static function get_user_email() |
||
92 | } |
||
93 | |||
94 | public static function get_password() |
||
95 | { |
||
96 | $password = Config::inst()->get(self::class, 'password'); |
||
97 | if (! $password) { |
||
98 | if (Config::inst()->get(self::class, 'use_default_admin')) { |
||
99 | $password = DefaultAdminService::getDefaultAdminPassword(); |
||
100 | } else { |
||
101 | $cache = Injector::inst()->get(CacheInterface::class . '.templateoverview'); |
||
102 | if (! $cache->has('password')) { |
||
103 | $password = strtolower('aa' . substr(uniqid(), 0, 8)) . '_.,' . strtoupper('BB' . substr(uniqid(), 0, 8)); |
||
104 | $cache->set('password', $password); |
||
105 | } |
||
106 | |||
107 | $password = $cache->get('password'); |
||
108 | } |
||
109 | } |
||
110 | |||
111 | return $password; |
||
112 | } |
||
113 | |||
114 | public static function get_test_user() |
||
117 | } |
||
118 | |||
119 | /** |
||
120 | * Main function |
||
121 | * has two streams: |
||
122 | * 1. check on url specified in GET variable. |
||
123 | * 2. create a list of urls to check. |
||
124 | */ |
||
125 | public function testone(HTTPRequest $request) |
||
126 | { |
||
127 | $isCMSLink = (bool) $request->getVar('iscmslink'); |
||
128 | $testURL = $request->getVar('test') ?: null; |
||
129 | |||
130 | // 1. actually test a URL and return the data |
||
131 | if ($testURL) { |
||
132 | $this->guzzleSetup(); |
||
133 | $this->getTestUser(); |
||
134 | $content = $this->testURL($testURL); |
||
135 | $this->deleteUser(); |
||
136 | $diff = 'Please install https://github.com/Kevin-Kip/meru/ to see diff.'; |
||
137 | //these echo is required! |
||
138 | echo $content; |
||
139 | if (! Director::is_ajax()) { |
||
140 | $comparisonBaseURL = Config::inst()->get(self::class, 'comparision_base_url'); |
||
141 | $width = '98%'; |
||
142 | $style = 'border: none;'; |
||
143 | if ($comparisonBaseURL) { |
||
144 | $width = '48%'; |
||
145 | $style = 'float: left;'; |
||
146 | if ($this->isSuccess && ! $isCMSLink && $this->Config()->create_diff) { |
||
147 | $otherURL = $comparisonBaseURL . $testURL; |
||
148 | $testContent = str_replace(Director::absoluteBaseURL(), $comparisonBaseURL, $this->rawResponse); |
||
149 | $rawResponseOtherSite = @file_get_contents($otherURL); |
||
150 | if (class_exists(Differ::class)) { |
||
151 | $diff = (new Differ())->diff( |
||
152 | $testContent, |
||
153 | $rawResponseOtherSite |
||
|
|||
154 | ); |
||
155 | $rawResponseOtherSite = Convert::raw2htmlatt(str_replace("'", '\\\'', $rawResponseOtherSite)); |
||
156 | $diff = ' |
||
157 | <iframe id="iframe2" width="' . $width . '%" height="7000" srcdoc=\'' . $rawResponseOtherSite . '\' style="float: right;"></iframe> |
||
158 | |||
159 | <hr style="clear: both; margin-top: 20px; padding-top: 20px;" /> |
||
160 | <h1>Diff</h1> |
||
161 | <link href="/resources/vendor/sunnysideup/templateoverview/client/css/checkalltemplates.css" rel="stylesheet" type="text/css" /> |
||
162 | ' . $diff; |
||
163 | } |
||
164 | } |
||
165 | } |
||
166 | |||
167 | $rawResponse = Convert::raw2htmlatt(str_replace("'", '\\\'', $this->rawResponse)); |
||
168 | echo ' |
||
169 | <h1>Response</h1> |
||
170 | '; |
||
171 | echo $diff; |
||
172 | echo ' |
||
173 | <iframe id="iframe" width="' . $width . '" height="700" srcdoc=\'' . $rawResponse . '\' style="' . $style . '"></iframe> |
||
174 | '; |
||
175 | } |
||
176 | |||
177 | return; |
||
178 | } |
||
179 | |||
180 | user_error('no test url provided.'); |
||
181 | } |
||
182 | |||
183 | public function getTestUser() |
||
184 | { |
||
185 | if (Config::inst()->get(self::class, 'use_default_admin')) { |
||
186 | $this->member = Injector::inst()->get(DefaultAdminService::class)->findOrCreateDefaultAdmin(); |
||
187 | |||
188 | return $this->member; |
||
189 | } |
||
190 | |||
191 | //Make temporary admin member |
||
192 | $filter = ['Email' => self::get_user_email()]; |
||
193 | // @var Member|null $this->member |
||
194 | $this->member = Member::get() |
||
195 | ->filter($filter) |
||
196 | ->first() |
||
197 | ; |
||
198 | if (empty($this->member)) { |
||
199 | $this->member = Member::create($filter); |
||
200 | } |
||
201 | |||
202 | $this->member->Password = self::get_password(); |
||
203 | $this->member->LockedOutUntil = null; |
||
204 | $this->member->FirstName = 'Test'; |
||
205 | $this->member->Surname = 'User'; |
||
206 | $this->member->write(); |
||
207 | $auth = new MemberAuthenticator(); |
||
208 | $result = $auth->checkPassword($this->member, self::get_password()); |
||
209 | if (! $result->isValid()) { |
||
210 | user_error('Error in creating test user.', E_USER_ERROR); |
||
211 | |||
212 | return; |
||
213 | } |
||
214 | |||
215 | $service = Injector::inst()->get(DefaultAdminService::class); |
||
216 | $adminGroup = $service->findOrCreateAdminGroup(); |
||
217 | $this->member->Groups()->add($adminGroup); |
||
218 | if (Permission::checkMember($this->member, 'ADMIN')) { |
||
219 | user_error('No admin group exists', E_USER_ERROR); |
||
220 | |||
221 | return; |
||
222 | } |
||
223 | |||
224 | return $this->member; |
||
225 | } |
||
226 | |||
227 | /** |
||
228 | * @return mixed |
||
229 | */ |
||
230 | protected function guzzleSendRequest(string $url) |
||
265 | } |
||
266 | |||
267 | protected function isJson($string) |
||
268 | { |
||
269 | $obj = json_decode($string); |
||
270 | |||
271 | return JSON_ERROR_NONE === json_last_error() && 'object' === gettype($obj); |
||
272 | } |
||
273 | |||
274 | /** |
||
275 | * ECHOES the result of testing the URL.... |
||
276 | * |
||
277 | * @param string $url |
||
278 | */ |
||
279 | private function testURL($url) |
||
280 | { |
||
281 | if (strlen(trim($url)) < 1) { |
||
282 | user_error('empty url'); //Checks for empty strings. |
||
283 | } |
||
284 | |||
285 | if (AllLinks::is_admin_link($url)) { |
||
286 | $validate = false; |
||
287 | } else { |
||
288 | $validate = Config::inst()->get(self::class, 'use_w3_validation'); |
||
289 | } |
||
290 | |||
291 | $testURL = Director::absoluteURL('/admin/templateoverviewloginandredirect/login/?BackURL='); |
||
292 | $testURL .= urlencode($url); |
||
293 | $this->guzzleSetup(); |
||
294 | |||
295 | $start = microtime(true); |
||
296 | $response = $this->guzzleSendRequest($testURL); |
||
297 | $end = microtime(true); |
||
298 | |||
299 | $data = [ |
||
300 | 'status' => 'success', |
||
301 | 'httpResponse' => '200', |
||
302 | 'content' => '', |
||
303 | 'responseTime' => round($end - $start, 4), |
||
304 | 'type' => '', |
||
305 | 'length' => '', |
||
306 | 'w3Content' => '', |
||
307 | ]; |
||
308 | |||
309 | $httpResponse = $response->getStatusCode(); |
||
310 | $error = $response->getReasonPhrase(); |
||
311 | if ($this->guzzleHasError) { |
||
312 | //we already have the body ... |
||
313 | } else { |
||
314 | $this->rawResponse = $response->getBody(); |
||
315 | } |
||
316 | |||
317 | $data['httpResponse'] = $httpResponse; |
||
318 | |||
319 | if (401 === $httpResponse) { |
||
320 | $data['status'] = 'error'; |
||
321 | $data['content'] = 'Could not access: ' . $url; |
||
322 | |||
323 | return json_encode($data); |
||
324 | } |
||
325 | |||
326 | //uncaught errors ... |
||
327 | if ($this->rawResponse && 'Fatal error' === substr((string) $this->rawResponse, 0, 12)) { |
||
328 | $data['status'] = 'error'; |
||
329 | $data['content'] = $this->rawResponse; |
||
330 | } elseif (200 === $httpResponse && $this->rawResponse && strlen( (string) $this->rawResponse) < 200) { |
||
331 | if (! $this->isJson($this->rawResponse)) { |
||
332 | $data['status'] = 'error - no response'; |
||
333 | $data['content'] = 'SHORT RESPONSE: ' . $this->rawResponse; |
||
334 | } |
||
335 | } |
||
336 | |||
337 | $data['w3Content'] = 'n/a'; |
||
338 | |||
339 | if (200 !== $httpResponse) { |
||
340 | $data['status'] = 'error'; |
||
341 | $data['content'] .= 'unexpected response: ' . $error . $this->rawResponse; |
||
342 | } else { |
||
343 | $this->isSuccess = true; |
||
344 | $data['type'] = $response->getHeaders()['Content-Type'][0] ?? 'no-content-type'; |
||
345 | $data['length'] = $response->getHeaders()['Content-Length'][0] ?? '0'; |
||
346 | if ($validate) { |
||
347 | $w3Obj = new W3cValidateApi(); |
||
348 | $data['w3Content'] = $w3Obj->W3Validate('', $this->rawResponse); |
||
349 | } |
||
350 | } |
||
351 | |||
352 | if (Director::is_ajax()) { |
||
353 | return json_encode($data); |
||
354 | } |
||
355 | |||
356 | $content = ''; |
||
357 | $content .= '<p><strong>URL:</strong> ' . $url . '</p>'; |
||
358 | $content .= '<p><strong>Status:</strong> ' . $data['status'] . '</p>'; |
||
359 | $content .= '<p><strong>HTTP response:</strong> ' . $data['httpResponse'] . '</p>'; |
||
360 | $content .= '<p><strong>Content:</strong> ' . htmlspecialchars($data['content']) . '</p>'; |
||
361 | $content .= '<p><strong>Response time:</strong> ' . $data['responseTime'] . '</p>'; |
||
362 | $content .= '<p><strong>Type:</strong> ' . $data['type'] . '</p>'; |
||
363 | |||
364 | return $content . ('<p><strong>W3 Content:</strong> ' . $data['w3Content'] . '</p>'); |
||
365 | } |
||
366 | |||
367 | /** |
||
368 | * creates the basic curl. |
||
369 | */ |
||
370 | private function guzzleSetup() |
||
371 | { |
||
372 | // $user_agent='Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0'; |
||
373 | // $post = $type == "GET" ? false : true; |
||
374 | // |
||
375 | // $strCookie = 'PHPSESSID=' . session_id() . '; path=/'; |
||
376 | // $options = array( |
||
377 | // CURLOPT_CUSTOMREQUEST => $type, //set request type post or get |
||
378 | // CURLOPT_POST => $post, //set to GET |
||
379 | // CURLOPT_USERAGENT => $user_agent, //set user agent |
||
380 | // CURLOPT_COOKIE => $strCookie, //set cookie file |
||
381 | // CURLOPT_COOKIEFILE => "cookie.txt", //set cookie file |
||
382 | // CURLOPT_COOKIEJAR => "cookie.txt", //set cookie jar |
||
383 | // CURLOPT_RETURNTRANSFER => true, // return web page |
||
384 | // CURLOPT_HEADER => false, // don't return headers |
||
385 | // CURLOPT_FOLLOWLOCATION => true, // follow redirects |
||
386 | // CURLOPT_ENCODING => "", // handle all encodings |
||
387 | // CURLOPT_AUTOREFERER => true, // set referer on redirect |
||
388 | // CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect |
||
389 | // CURLOPT_TIMEOUT => 120, // timeout on response |
||
390 | // CURLOPT_MAXREDIRS => 10, // stop after 10 redirects |
||
391 | // ); |
||
392 | // |
||
393 | // $this->ch = curl_init(); |
||
394 | // |
||
395 | // curl_setopt_array($this->ch, $options); |
||
396 | |||
397 | $this->guzzleCookieJar = new CookieJar(); |
||
398 | $this->guzzleClient = new Client( |
||
399 | [ |
||
400 | 'base_uri' => Director::baseURL(), |
||
401 | 'cookies' => true, |
||
402 | ] |
||
403 | ); |
||
404 | } |
||
405 | |||
406 | private function deleteUser() |
||
414 | } |
||
415 | } |
||
416 | |||
417 | // private function debugme($lineNumber, $variable = "") |
||
418 | // { |
||
419 | // if ($this->debug) { |
||
426 |