[BUGFIX] linkvalidator: Fatal error: Call to a member function getUrl()
[Packages/TYPO3.CMS.git] / typo3 / sysext / linkvalidator / Classes / Linktype / ExternalLinktype.php
1 <?php
2 namespace TYPO3\CMS\Linkvalidator\Linktype;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 /**
18 * This class provides Check External Links plugin implementation
19 *
20 * @author Dimitri K├Ânig <dk@cabag.ch>
21 * @author Michael Miousse <michael.miousse@infoglobe.ca>
22 * @author Philipp Gampe <typo3.dev@philippgampe.info>
23 */
24 class ExternalLinktype extends \TYPO3\CMS\Linkvalidator\Linktype\AbstractLinktype {
25
26 /**
27 * Cached list of the URLs, which were already checked for the current processing
28 *
29 * @var array $urlReports
30 */
31 protected $urlReports = array();
32
33 /**
34 * Cached list of all error parameters of the URLs, which were already checked for the current processing
35 *
36 * @var array $urlErrorParams
37 */
38 protected $urlErrorParams = array();
39
40 /**
41 * List of headers to be used for matching an URL for the current processing
42 *
43 * @var array $additionalHeaders
44 */
45 protected $additionalHeaders = array();
46
47 /**
48 * Checks a given URL for validity
49 *
50 * @param string $url The URL to check
51 * @param array $softRefEntry The soft reference entry which builds the context of that URL
52 * @param \TYPO3\CMS\Linkvalidator\LinkAnalyzer $reference Parent instance
53 * @return bool TRUE on success or FALSE on error
54 */
55 public function checkLink($url, $softRefEntry, $reference) {
56 $errorParams = array();
57 $isValidUrl = TRUE;
58 if (isset($this->urlReports[$url])) {
59 if (!$this->urlReports[$url]) {
60 if (is_array($this->urlErrorParams[$url])) {
61 $this->setErrorParams($this->urlErrorParams[$url]);
62 }
63 }
64 return $this->urlReports[$url];
65 }
66 $config = array(
67 'follow_redirects' => TRUE,
68 'strict_redirects' => TRUE
69 );
70 /** @var $request \TYPO3\CMS\Core\Http\HttpRequest */
71 $request = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Http\HttpRequest::class, $url, 'HEAD', $config);
72 // Observe cookies
73 $request->setCookieJar(TRUE);
74 try {
75 /** @var $response \HTTP_Request2_Response */
76 $response = $request->send();
77 $status = isset($response) ? $response->getStatus() : 0;
78 // HEAD was not allowed or threw an error, now trying GET
79 if ($status >= 400) {
80 $request->setMethod('GET');
81 $request->setHeader('Range', 'bytes = 0 - 4048');
82 /** @var $response \HTTP_Request2_Response */
83 $response = $request->send();
84 }
85 } catch (\Exception $e) {
86 $isValidUrl = FALSE;
87 // A redirect loop occurred
88 if ($e->getCode() === 40) {
89 $traceUrl = $request->getUrl()->getURL();
90 /** @var \HTTP_Request2_Response $event['data'] */
91 $event = $request->getLastEvent();
92 if ($event['data'] instanceof \HTTP_Request2_Response) {
93 $traceCode = $event['data']->getStatus();
94 } else {
95 $traceCode = 'loop';
96 }
97 $errorParams['errorType'] = 'loop';
98 $errorParams['location'] = $traceUrl;
99 $errorParams['errorCode'] = $traceCode;
100 } else {
101 $errorParams['errorType'] = 'exception';
102 }
103 $errorParams['message'] = $e->getMessage();
104 }
105 $status = isset($response) ? $response->getStatus() : 0;
106 if ($status >= 300) {
107 $isValidUrl = FALSE;
108 $errorParams['errorType'] = $status;
109 $errorParams['message'] = $response->getReasonPhrase();
110 }
111 if (!$isValidUrl) {
112 $this->setErrorParams($errorParams);
113 }
114 $this->urlReports[$url] = $isValidUrl;
115 $this->urlErrorParams[$url] = $errorParams;
116 return $isValidUrl;
117 }
118
119 /**
120 * Generate the localized error message from the error params saved from the parsing
121 *
122 * @param array $errorParams All parameters needed for the rendering of the error message
123 * @return string Validation error message
124 */
125 public function getErrorMessage($errorParams) {
126 $errorType = $errorParams['errorType'];
127 switch ($errorType) {
128 case 300:
129 $response = sprintf($GLOBALS['LANG']->getLL('list.report.externalerror'), $errorType);
130 break;
131 case 403:
132 $response = $GLOBALS['LANG']->getLL('list.report.pageforbidden403');
133 break;
134 case 404:
135 $response = $GLOBALS['LANG']->getLL('list.report.pagenotfound404');
136 break;
137 case 500:
138 $response = $GLOBALS['LANG']->getLL('list.report.internalerror500');
139 break;
140 case 'loop':
141 $response = sprintf($GLOBALS['LANG']->getLL('list.report.redirectloop'), $errorParams['errorCode'], $errorParams['location']);
142 break;
143 case 'exception':
144 $response = sprintf($GLOBALS['LANG']->getLL('list.report.httpexception'), $errorParams['message']);
145 break;
146 default:
147 $response = sprintf($GLOBALS['LANG']->getLL('list.report.otherhttpcode'), $errorType, $errorParams['message']);
148 }
149 return $response;
150 }
151
152 /**
153 * Get the external type from the softRefParserObj result
154 *
155 * @param array $value Reference properties
156 * @param string $type Current type
157 * @param string $key Validator hook name
158 * @return string Fetched type
159 */
160 public function fetchType($value, $type, $key) {
161 preg_match_all('/((?:http|https))(?::\\/\\/)(?:[^\\s<>]+)/i', $value['tokenValue'], $urls, PREG_PATTERN_ORDER);
162 if (!empty($urls[0][0])) {
163 $type = 'external';
164 }
165 return $type;
166 }
167
168 }