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