Added feature #16420: Add link validator module (Thanks to Patrick Gaumond)
[Packages/TYPO3.CMS.git] / typo3 / sysext / linkvalidator / lib / class.tx_linkvalidator_processing.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2005 - 2010 Michael Miousse (michael.miousse@infoglobe.ca)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25 /**
26 * This class provides Processing plugin implementation.
27 *
28 * @author Michael Miousse <michael.miousse@infoglobe.ca>
29 * @author Jochen Rieger <j.rieger@connecta.ag>
30 */
31
32 $GLOBALS['LANG']->includeLLFile('EXT:linkvalidator/modfunc1/locallang.xml');
33
34 class tx_linkvalidator_processing {
35
36 protected $searchFields = array(); // array of tables and fields to search for broken links
37 protected $pidList = ''; // list of pidlist (rootline downwards)
38 protected $linkCounts = array(); // array of tables containing number of external link
39 protected $brokenLinkCounts = array(); // array of tables containing number of broken external link
40 protected $recordsWithBrokenLinks = array(); // array of tables and records containing broken links
41 protected $hookObjectsArr = array(); // array for hooks for own checks
42
43 /**
44 * Fill hookObjectsArr with different links type and possible XClasses
45 */
46 function __construct() {
47 // Hook to handle own checks
48 if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'])) {
49 foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['checkLinks'] as $key => $classRef) {
50 $this->hookObjectsArr[$key] = &t3lib_div::getUserObj($classRef);
51 }
52 }
53 }
54
55 /**
56 * Init Function: here all the needed configuration values are stored in class variables
57 *
58 * @param array $searchField: list of fields in which to search for links
59 * @param string $pid: list of comat separated page uid in which to search for links
60 * @return void
61 */
62 public function init($searchField, $pid) {
63 $this->searchFields = $searchField;
64 $this->pidList = $pid;
65 }
66
67 /**
68 * Find all supported broken links and store it in tx_linkvalidator_links
69 * @param array $checkOptions: list of hook object to activate
70 * @param int $hidden: define if look into hidden fields or not
71 * @return void
72 */
73 public function getLinkStatistics($checkOptions = array(), $hidden = 0) {
74 $results = array();
75 $GLOBALS['TYPO3_DB']->exec_DELETEquery('tx_linkvalidator_links', 'recpid in (' . $this->pidList . ')');
76
77 // let's traverse all configured tables
78 foreach ($this->searchFields as $table => $fields) {
79 $where = 'deleted = 0 AND pid IN (' . $this->pidList . ')';
80 if (!$hidden) {
81 $where .= t3lib_BEfunc::BEenableFields($table);
82 }
83 // if table is not configured, we assume the ext is not installed and therefore no need to check it
84 if (!is_array($GLOBALS['TCA'][$table])) continue;
85
86 // re-init selectFields for table
87 $selectFields = 'uid, pid';
88 $selectFields .= ', ' . $GLOBALS['TCA'][$table]['ctrl']['label'] . ', ' . implode(', ', $fields);
89
90 // TODO: only select rows that have content in at least one of the relevant fields (via OR)
91 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($selectFields, $table, $where);
92 // Get record rows of table
93 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
94
95 // array to store urls from relevant field contents
96 $urls = array();
97
98 // flag whether row contains a broken link in some field or not
99 $rowContainsBrokenLink = FALSE;
100
101 // put together content of all relevant fields
102 $haystack = '';
103 $htmlParser = t3lib_div::makeInstance('t3lib_parsehtml');
104 // get all references
105 foreach ($fields as $field) {
106 $haystack .= $row[$field] . ' --- ';
107 $conf = $GLOBALS['TCA'][$table]['columns'][$field]['config'];
108 // Check if a TCA configured field has softreferences defined (see TYPO3 Core API document)
109 if ($conf['softref'] && strlen($row[$field])) {
110 // Explode the list of softreferences/parameters
111 $softRefs = t3lib_BEfunc::explodeSoftRefParserList($conf['softref']);
112 // Traverse soft references
113 foreach ($softRefs as $spKey => $spParams) {
114 // create / get object
115 $softRefObj = &t3lib_BEfunc::softRefParserObj($spKey);
116
117 if (is_object($softRefObj)) { // If there was an object returned...:
118 // Do processing
119 $resultArray = $softRefObj->findRef($table, $field, $row['uid'], $row[$field], $spKey, $spParams);
120 if (!empty($resultArray['elements'])) {
121
122 $tagAttr = array();
123 if ($spKey == 'typolink_tag') {
124 $linkTags = $htmlParser->splitIntoBlock('link', $resultArray['content']);
125 foreach ($linkTags as $tag) {
126 $attr = $htmlParser->split_tag_attributes($tag);
127 $tagAttr[$tag] = $attr[0];
128 }
129 }
130 foreach ($resultArray['elements'] as $element) {
131 $r = $element['subst'];
132 $title = '';
133 // Parse string for special TYPO3 <link> tag:
134
135 if ($spKey == 'typolink_tag') {
136 foreach ($tagAttr as $tag => $attr) {
137 if (in_array('{softref:' . $r['tokenID'] . '}', $attr)) {
138 $title = strip_tags($tag);
139 }
140 }
141 }
142 $type = '';
143 if (!empty($r)) {
144 foreach ($this->hookObjectsArr as $key => $hookObj) {
145 $type = $hookObj->fetchType($r, $type, $key);
146 }
147 $results[$type][$table . ':' . $field . ':' . $row['uid'] . ':' . $r["tokenID"]]["substr"] = $r;
148 $results[$type][$table . ':' . $field . ':' . $row['uid'] . ':' . $r["tokenID"]]["row"] = $row;
149 $results[$type][$table . ':' . $field . ':' . $row['uid'] . ':' . $r["tokenID"]]["table"] = $table;
150 $results[$type][$table . ':' . $field . ':' . $row['uid'] . ':' . $r["tokenID"]]["field"] = $field;
151 $results[$type][$table . ':' . $field . ':' . $row['uid'] . ':' . $r["tokenID"]]["uid"] = $row['uid'];
152 $results[$type][$table . ':' . $field . ':' . $row['uid'] . ':' . $r["tokenID"]]["linktitle"] = $title;
153 }
154
155 }
156 }
157 }
158 }
159 }
160 }
161 } // end while ($row = ...)
162 } // end foreach $table
163
164 foreach ($this->hookObjectsArr as $key => $hookObj) {
165 if ((is_array($results[$key])) && empty($checkOptions) || (is_array($results[$key]) && $checkOptions[$key])) {
166 // check'em!
167 foreach ($results[$key] as $entryKey => $entryValue) {
168 $table = $entryValue['table'];
169 $record = array();
170 $record['headline'] = $entryValue['row'][$GLOBALS['TCA'][$table]['ctrl']['label']];
171 $record['recpid'] = $entryValue['row']['pid'];
172 $record['recuid'] = $entryValue['uid'];
173 $record['tablename'] = $table;
174 $record['linktitle'] = $entryValue['linktitle'];
175 $record['field'] = $entryValue['field'];
176 $record['lastcheck'] = time();
177 $url = $entryValue['substr']['tokenValue'];
178 $this->linkCounts[$table]++;
179 $checkURL = $hookObj->checkLink($url, $entryValue, $this);
180 // broken link found!
181 if ($checkURL != 1) {
182 $this->brokenLinkCounts[$table]++;
183 $record['typelinks'] = $key;
184 $record['url'] = $url;
185 $record['urlresponse'] = '<span style="color:red">' . $checkURL . '</span>';
186 $GLOBALS['TYPO3_DB']->exec_INSERTquery('tx_linkvalidator_links', $record);
187 } elseif (t3lib_div::_GP('showalllinks')) {
188 $this->brokenLinkCounts[$table]++;
189 $record['url'] = $url;
190 $record['typelinks'] = $key;
191 $record['urlresponse'] = '<span style="color:green">OK</span>';
192 $GLOBALS['TYPO3_DB']->exec_INSERTquery('tx_linkvalidator_links', $record);
193 }
194
195 }
196 }
197 }
198
199 } // end function getLinkStatistics
200
201 /**
202 * Fill a markerarray with the number of link found in a list of page.
203 * @param string $curPage: commat separeted page uid list
204 * @return array markerarray with the number of link found
205 */
206 function getLinkCounts($curPage) {
207 $markerArray = array();
208 if (($res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
209 'count(uid) as nbBrokenLinks,typelinks',
210 'tx_linkvalidator_links',
211 'recpid in (' . $this->pidList . ')',
212 'typelinks'
213 ))) {
214 while (($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))) {
215 $markerArray[$row['typelinks']] = $row['nbBrokenLinks'];
216 $markerArray['brokenlinkCount'] += $row['nbBrokenLinks'];
217 }
218 }
219 return $markerArray;
220 }
221
222 }
223
224 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/linkvalidator/lib/class.tx_linkvalidator_processing.php']) {
225 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/linkvalidator/lib/class.tx_linkvalidator_processing.php']);
226 }
227 ?>