[CLEANUP] Link validator: LinkHandler
[Packages/TYPO3.CMS.git] / typo3 / sysext / linkvalidator / Classes / Linktype / LinkHandler.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 use TYPO3\CMS\Backend\Utility\BackendUtility;
18 use TYPO3\CMS\Core\Utility\StringUtility;
19
20 /**
21 * This class provides Check Link Handler plugin implementation
22 *
23 * @author Dimitri K├Ânig <dk@cabag.ch>
24 * @author Michael Miousse <michael.miousse@infoglobe.ca>
25 */
26 class LinkHandler extends AbstractLinktype {
27
28 /**
29 * @var string
30 */
31 const DELETED = 'deleted';
32
33 /**
34 * @var string
35 */
36 const DISABLED = 'disabled';
37
38 /**
39 * Checks a given URL for validity
40 *
41 * @param string $url Url to check
42 * @param array $softRefEntry The soft reference entry which builds the context of that url
43 * @param \TYPO3\CMS\Linkvalidator\LinkAnalyzer $reference Parent instance
44 * @return bool TRUE on success or FALSE on error
45 */
46 public function checkLink($url, $softRefEntry, $reference) {
47 $response = TRUE;
48 $errorType = '';
49 $errorParams = array();
50 $parts = explode(':', $url);
51 if (count($parts) !== 3) {
52 return $response;
53 }
54
55 list(, $tableName, $rowid) = $parts;
56 $rowid = (int)$rowid;
57
58 $row = NULL;
59 $tsConfig = $reference->getTSConfig();
60 $reportHiddenRecords = (bool)$tsConfig['linkhandler.']['reportHiddenRecords'];
61
62 // First check, if we find a non disabled record if the check
63 // for hidden records is enabled.
64 if ($reportHiddenRecords) {
65 $row = $this->getRecordRow($tableName, $rowid, 'disabled');
66 if ($row === NULL) {
67 $response = FALSE;
68 $errorType = self::DISABLED;
69 }
70 }
71
72 // If no enabled record was found or we did not check that see
73 // if we can find a non deleted record.
74 if ($row === NULL) {
75 $row = $this->getRecordRow($tableName, $rowid, 'deleted');
76 if ($row === NULL) {
77 $response = FALSE;
78 $errorType = self::DELETED;
79 }
80 }
81
82 // If we did not find a non deleted record, check if we find a
83 // deleted one.
84 if ($row === NULL) {
85 $row = $this->getRecordRow($tableName, $rowid, 'all');
86 if ($row === NULL) {
87 $response = FALSE;
88 $errorType = '';
89 }
90 }
91
92 if (!$response) {
93 $errorParams['errorType'] = $errorType;
94 $errorParams['tablename'] = $tableName;
95 $errorParams['uid'] = $rowid;
96 $this->setErrorParams($errorParams);
97 }
98
99 return $response;
100 }
101
102 /**
103 * Type fetching method, based on the type that softRefParserObj returns
104 *
105 * @param array $value Reference properties
106 * @param string $type Current type
107 * @param string $key Validator hook name
108 * @return string fetched type
109 */
110 public function fetchType($value, $type, $key) {
111 if ($value['type'] === 'string' && StringUtility::beginsWith(strtolower($value['tokenValue']), 'record:')) {
112 $type = 'linkhandler';
113 }
114 return $type;
115 }
116
117 /**
118 * Generate the localized error message from the error params saved from the parsing
119 *
120 * @param array $errorParams All parameters needed for the rendering of the error message
121 * @return string Validation error message
122 */
123 public function getErrorMessage($errorParams) {
124 $errorType = $errorParams['errorType'];
125 $tableName = $errorParams['tablename'];
126 if (!empty($GLOBALS['TCA'][$tableName]['ctrl']['title'])) {
127 $title = $this->getLanguageService()->sL($GLOBALS['TCA'][$tableName]['ctrl']['title']);
128 } else {
129 $title = $tableName;
130 }
131 switch ($errorType) {
132 case self::DISABLED:
133 $response = $this->getTranslatedErrorMessage('list.report.rownotvisible', $errorParams['uid'], $title);
134 break;
135 case self::DELETED:
136 $response = $this->getTranslatedErrorMessage('list.report.rowdeleted', $errorParams['uid'], $title);
137 break;
138 default:
139 $response = $this->getTranslatedErrorMessage('list.report.rownotexisting', $errorParams['uid']);
140 }
141 return $response;
142 }
143
144 /**
145 * Fetches the translation with the given key and replaces the ###uid### and ###title### markers
146 *
147 * @param string $translationKey
148 * @param int $uid
149 * @param string $title
150 * @return string
151 */
152 protected function getTranslatedErrorMessage($translationKey, $uid, $title = NULL) {
153 $message = $this->getLanguageService()->getLL($translationKey);
154 $message = str_replace('###uid###', (int)$uid, $message);
155 if (isset($title)) {
156 $message = str_replace('###title###', htmlspecialchars($title), $message);
157 }
158 return $message;
159 }
160
161 /**
162 * Fetches the record with the given UID from the given table.
163 *
164 * The filter option accepts two values:
165 *
166 * "disabled" will filter out disabled and deleted records.
167 * "deleted" filters out deleted records but will return disabled records.
168 * If nothing is specified all records will be returned (including deleted).
169 *
170 * @param string $tableName The name of the table from which the record should be fetched.
171 * @param int $uid The UID of the record that should be fetched.
172 * @param string $filter A filter setting, can be empty or "disabled" or "deleted".
173 * @return array|NULL The result row as associative array or NULL if nothing is found.
174 */
175 protected function getRecordRow($tableName, $uid, $filter = '') {
176
177 $whereStatement = 'uid = ' . (int)$uid;
178
179 switch ($filter) {
180 case self::DISABLED:
181 $whereStatement .= BackendUtility::BEenableFields($tableName) . BackendUtility::deleteClause($tableName);
182 break;
183 case self::DELETED:
184 $whereStatement .= BackendUtility::deleteClause($tableName);
185 break;
186 }
187
188 $row = $this->getDatabaseConnection()->exec_SELECTgetSingleRow(
189 '*',
190 $tableName,
191 $whereStatement
192 );
193
194 // Since exec_SELECTgetSingleRow can return NULL or FALSE we
195 // make sure we always return NULL if no row was found.
196 if ($row === FALSE) {
197 $row = NULL;
198 }
199
200 return $row;
201 }
202
203 }