37079ba17161b09fb9438a5ceefee5c75a7259e3
[Packages/TYPO3.CMS.git] / typo3 / sysext / linkvalidator / classes / linktype / class.tx_linkvalidator_linktype_external.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2010 - 2009 Jochen Rieger (j.rieger@connecta.ag)
6 * (c) 2010 - 2011 Michael Miousse (michael.miousse@infoglobe.ca)
7 * All rights reserved
8 *
9 * This script is part of the TYPO3 project. The TYPO3 project is
10 * free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * The GNU General Public License can be found at
16 * http://www.gnu.org/copyleft/gpl.html.
17 *
18 * This script is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * This copyright notice MUST APPEAR in all copies of the script!
24 ***************************************************************/
25 /**
26 * This class provides Check External Links plugin implementation
27 *
28 * @author Dimitri K├Ânig <dk@cabag.ch>
29 * @author Michael Miousse <michael.miousse@infoglobe.ca>
30 * @author Philipp Gampe <typo3.dev@philippgampe.info>
31 * @package TYPO3
32 * @subpackage linkvalidator
33 */
34 class tx_linkvalidator_linktype_External extends tx_linkvalidator_linktype_Abstract {
35
36 /**
37 * Cached list of the URLs, which were already checked for the current processing
38 *
39 * @var array $urlReports
40 */
41 protected $urlReports = array();
42
43 /**
44 * Cached list of all error parameters of the URLs, which were already checked for the current processing
45 *
46 * @var array $urlErrorParams
47 */
48 protected $urlErrorParams = array();
49
50 /**
51 * List of headers to be used for matching an URL for the current processing
52 *
53 * @var array $additionalHeaders
54 */
55 protected $additionalHeaders = array();
56
57
58 /**
59 * Checks a given URL for validity
60 *
61 * @param string $url The URL to check
62 * @param array $softRefEntry The soft reference entry which builds the context of that URL
63 * @param tx_linkvalidator_Processor $reference Parent instance of tx_linkvalidator_Processor
64 * @return boolean TRUE on success or FALSE on error
65 */
66 public function checkLink($url, $softRefEntry, $reference) {
67 $errorParams = array();
68 $isValidUrl = TRUE;
69
70 if (isset($this->urlReports[$url])) {
71 if (!$this->urlReports[$url]) {
72 if(is_array($this->urlErrorParams[$url])) {
73 $this->setErrorParams($this->urlErrorParams[$url]);
74 }
75 }
76 return $this->urlReports[$url];
77 }
78
79 $config = array(
80 'follow_redirects' => TRUE,
81 'strict_redirects' => TRUE,
82 );
83
84 /** @var t3lib_http_Request|HTTP_Request2 $request */
85 $request = t3lib_div::makeInstance('t3lib_http_Request', $url, 'HEAD', $config);
86 // Observe cookies
87 $request->setCookieJar(TRUE);
88
89 try {
90 /** @var HTTP_Request2_Response $response */
91 $response = $request->send();
92 // HEAD was not allowed, now trying GET
93 if (isset($response) && $response->getStatus() === 405) {
94 $request->setMethod('GET');
95 $request->setHeader('Range', 'bytes = 0 - 4048');
96 /** @var HTTP_Request2_Response $response */
97 $response = $request->send();
98 }
99 }
100 catch (Exception $e) {
101 $isValidUrl = FALSE;
102 // A redirect loop occurred
103 if ($e->getCode() === 40) {
104 // Parse the exception for more information
105 $trace = $e->getTrace();
106 $traceUrl = $trace[0]['args'][0]->getUrl()->getUrl();
107 $traceCode = $trace[0]['args'][1]->getStatus();
108
109 $errorParams['errorType'] = 'loop';
110 $errorParams['location'] = $traceUrl;
111 $errorParams['errorCode'] = $traceCode;
112 } else {
113 $errorParams['errorType'] = 'exception';
114 }
115 $errorParams['message'] = $e->getMessage();
116 }
117
118 if (isset($response) && $response->getStatus() >= 300) {
119 $isValidUrl = FALSE;
120 $errorParams['errorType'] = $response->getStatus();
121 $errorParams['message'] = $response->getReasonPhrase();
122 }
123
124 if (!$isValidUrl) {
125 $this->setErrorParams($errorParams);
126 }
127
128 $this->urlReports[$url] = $isValidUrl;
129 $this->urlErrorParams[$url] = $errorParams;
130
131 return $isValidUrl;
132 }
133
134 /**
135 * Generate the localized error message from the error params saved from the parsing
136 *
137 * @param array $errorParams All parameters needed for the rendering of the error message
138 * @return string Validation error message
139 */
140 public function getErrorMessage($errorParams) {
141 $errorType = $errorParams['errorType'];
142 switch ($errorType) {
143 case 300:
144 $response = sprintf($GLOBALS['LANG']->getLL('list.report.externalerror'), $errorType);
145 break;
146
147 case 403:
148 $response = $GLOBALS['LANG']->getLL('list.report.pageforbidden403');
149 break;
150
151 case 404:
152 $response = $GLOBALS['LANG']->getLL('list.report.pagenotfound404');
153 break;
154
155 case 500:
156 $response = $GLOBALS['LANG']->getLL('list.report.internalerror500');
157 break;
158
159 case 'loop':
160 $response = sprintf($GLOBALS['LANG']->getLL('list.report.redirectloop'), $errorParams['errorCode'], $errorParams['location']);
161 break;
162
163 case 'exception':
164 $response = sprintf($GLOBALS['LANG']->getLL('list.report.httpexception'), $errorParams['message']);
165 break;
166
167 default:
168 $response = sprintf($GLOBALS['LANG']->getLL('list.report.otherhttpcode'), $errorType, $errorParams['message']);
169 }
170
171 return $response;
172 }
173
174 /**
175 * Get the external type from the softRefParserObj result
176 *
177 * @param array $value Reference properties
178 * @param string $type Current type
179 * @param string $key Validator hook name
180 * @return string Fetched type
181 */
182 public function fetchType($value, $type, $key) {
183 preg_match_all('/((?:http|https))(?::\/\/)(?:[^\s<>]+)/i', $value['tokenValue'], $urls, PREG_PATTERN_ORDER);
184
185 if (!empty($urls[0][0])) {
186 $type = "external";
187 }
188
189 return $type;
190 }
191
192 }
193
194 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/linkvalidator/classes/linktypes/class.tx_linkvalidator_linktypes_external.php'])) {
195 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/linkvalidator/classes/linktypes/class.tx_linkvalidator_linktypes_external.php']);
196 }
197
198 ?>