These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | namespace AOE\Crawler\Backend; |
||
3 | |||
4 | /*************************************************************** |
||
5 | * Copyright notice |
||
6 | * |
||
7 | * (c) 2018 AOE GmbH <[email protected]> |
||
8 | * |
||
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 3 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 | use AOE\Crawler\Backend\View\PaginationView; |
||
29 | use AOE\Crawler\Backend\View\ProcessListView; |
||
30 | use AOE\Crawler\Controller\CrawlerController; |
||
31 | use AOE\Crawler\Domain\Model\Reason; |
||
32 | use AOE\Crawler\Domain\Repository\ProcessRepository; |
||
33 | use AOE\Crawler\Domain\Repository\QueueRepository; |
||
34 | use AOE\Crawler\Event\EventDispatcher; |
||
35 | use AOE\Crawler\Service\ProcessService; |
||
36 | use AOE\Crawler\Utility\IconUtility; |
||
37 | use TYPO3\CMS\Backend\Module\AbstractFunctionModule; |
||
38 | use TYPO3\CMS\Backend\Tree\View\PageTreeView; |
||
39 | use TYPO3\CMS\Backend\Utility\BackendUtility; |
||
40 | use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; |
||
41 | use TYPO3\CMS\Core\Imaging\Icon; |
||
42 | use TYPO3\CMS\Core\Messaging\FlashMessage; |
||
43 | use TYPO3\CMS\Core\Messaging\FlashMessageService; |
||
44 | use TYPO3\CMS\Core\Utility\DebugUtility; |
||
45 | use TYPO3\CMS\Core\Utility\GeneralUtility; |
||
46 | use TYPO3\CMS\Core\Utility\MathUtility; |
||
47 | |||
48 | /** |
||
49 | * Class BackendModule |
||
50 | * |
||
51 | * @package AOE\Crawler\Backend |
||
52 | */ |
||
53 | class BackendModule extends AbstractFunctionModule |
||
54 | { |
||
55 | // Internal, dynamic: |
||
56 | public $duplicateTrack = []; |
||
57 | public $submitCrawlUrls = false; |
||
58 | public $downloadCrawlUrls = false; |
||
59 | |||
60 | public $scheduledTime = 0; |
||
61 | public $reqMinute = 0; |
||
62 | |||
63 | /** |
||
64 | * @var array holds the selection of configuration from the configuration selector box |
||
65 | */ |
||
66 | public $incomingConfigurationSelection = []; |
||
67 | |||
68 | /** |
||
69 | * @var CrawlerController |
||
70 | */ |
||
71 | public $crawlerController; |
||
72 | |||
73 | public $CSVaccu = []; |
||
74 | |||
75 | /** |
||
76 | * If true the user requested a CSV export of the queue |
||
77 | * |
||
78 | * @var boolean |
||
79 | */ |
||
80 | public $CSVExport = false; |
||
81 | |||
82 | public $downloadUrls = []; |
||
83 | |||
84 | /** |
||
85 | * Holds the configuration from ext_conf_template loaded by loadExtensionSettings() |
||
86 | * |
||
87 | * @var array |
||
88 | */ |
||
89 | protected $extensionSettings = []; |
||
90 | |||
91 | /** |
||
92 | * Indicate that an flash message with an error is present. |
||
93 | * |
||
94 | * @var boolean |
||
95 | */ |
||
96 | protected $isErrorDetected = false; |
||
97 | |||
98 | /** |
||
99 | * @var ProcessService |
||
100 | */ |
||
101 | protected $processManager; |
||
102 | |||
103 | /** |
||
104 | * the constructor |
||
105 | */ |
||
106 | public function __construct() |
||
107 | { |
||
108 | $this->processManager = new ProcessService(); |
||
109 | } |
||
110 | |||
111 | /** |
||
112 | * Additions to the function menu array |
||
113 | * |
||
114 | * @return array Menu array |
||
115 | */ |
||
116 | public function modMenu() |
||
117 | { |
||
118 | global $LANG; |
||
119 | |||
120 | return [ |
||
121 | 'depth' => [ |
||
122 | 0 => $LANG->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_0'), |
||
123 | 1 => $LANG->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_1'), |
||
124 | 2 => $LANG->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_2'), |
||
125 | 3 => $LANG->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_3'), |
||
126 | 4 => $LANG->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_4'), |
||
127 | 99 => $LANG->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_infi'), |
||
128 | ], |
||
129 | 'crawlaction' => [ |
||
130 | 'start' => $LANG->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.start'), |
||
131 | 'log' => $LANG->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.log'), |
||
132 | 'multiprocess' => $LANG->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.multiprocess') |
||
133 | ], |
||
134 | 'log_resultLog' => '', |
||
135 | 'log_feVars' => '', |
||
136 | 'processListMode' => '', |
||
137 | 'log_display' => [ |
||
138 | 'all' => $LANG->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.all'), |
||
139 | 'pending' => $LANG->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.pending'), |
||
140 | 'finished' => $LANG->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.finished') |
||
141 | ], |
||
142 | 'itemsPerPage' => [ |
||
143 | '5' => $LANG->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.itemsPerPage.5'), |
||
144 | '10' => $LANG->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.itemsPerPage.10'), |
||
145 | '50' => $LANG->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.itemsPerPage.50'), |
||
146 | '0' => $LANG->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.itemsPerPage.0') |
||
147 | ] |
||
148 | ]; |
||
149 | } |
||
150 | |||
151 | /** |
||
152 | * Load extension settings |
||
153 | * |
||
154 | * @return void |
||
155 | */ |
||
156 | protected function loadExtensionSettings() |
||
157 | { |
||
158 | $this->extensionSettings = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['crawler']); |
||
159 | } |
||
160 | |||
161 | /** |
||
162 | * Main function |
||
163 | * |
||
164 | * @return string HTML output |
||
165 | */ |
||
166 | public function main() |
||
167 | { |
||
168 | global $LANG, $BACK_PATH; |
||
169 | |||
170 | $this->incLocalLang(); |
||
171 | |||
172 | $this->loadExtensionSettings(); |
||
173 | if (empty($this->pObj->MOD_SETTINGS['processListMode'])) { |
||
174 | $this->pObj->MOD_SETTINGS['processListMode'] = 'simple'; |
||
175 | } |
||
176 | |||
177 | // Set CSS styles specific for this document: |
||
178 | $this->pObj->content = str_replace('/*###POSTCSSMARKER###*/', ' |
||
179 | TABLE.c-list TR TD { white-space: nowrap; vertical-align: top; } |
||
180 | ', $this->pObj->content); |
||
181 | |||
182 | $this->pObj->content .= '<style type="text/css"><!-- |
||
183 | table.url-table, |
||
184 | table.param-expanded, |
||
185 | table.crawlerlog { |
||
186 | border-bottom: 1px solid grey; |
||
187 | border-spacing: 0; |
||
188 | border-collapse: collapse; |
||
189 | } |
||
190 | table.crawlerlog td, |
||
191 | table.url-table td { |
||
192 | border: 1px solid lightgrey; |
||
193 | border-bottom: 1px solid grey; |
||
194 | white-space: nowrap; vertical-align: top; |
||
195 | } |
||
196 | --></style> |
||
197 | <link rel="stylesheet" type="text/css" href="' . $BACK_PATH . '../typo3conf/ext/crawler/template/res.css" /> |
||
198 | '; |
||
199 | |||
200 | // Type function menu: |
||
201 | $h_func = BackendUtility::getFuncMenu( |
||
202 | $this->pObj->id, |
||
203 | 'SET[crawlaction]', |
||
204 | $this->pObj->MOD_SETTINGS['crawlaction'], |
||
205 | $this->pObj->MOD_MENU['crawlaction'], |
||
206 | 'index.php' |
||
207 | ); |
||
208 | |||
209 | // Additional menus for the log type: |
||
210 | if ($this->pObj->MOD_SETTINGS['crawlaction'] === 'log') { |
||
211 | $h_func .= BackendUtility::getFuncMenu( |
||
212 | $this->pObj->id, |
||
213 | 'SET[depth]', |
||
214 | $this->pObj->MOD_SETTINGS['depth'], |
||
215 | $this->pObj->MOD_MENU['depth'], |
||
216 | 'index.php' |
||
217 | ); |
||
218 | |||
219 | $quiPart = GeneralUtility::_GP('qid_details') ? '&qid_details=' . intval(GeneralUtility::_GP('qid_details')) : ''; |
||
220 | |||
221 | $setId = intval(GeneralUtility::_GP('setID')); |
||
222 | |||
223 | $h_func .= '<hr/>' . |
||
224 | $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.display') . ': ' . BackendUtility::getFuncMenu($this->pObj->id, 'SET[log_display]', $this->pObj->MOD_SETTINGS['log_display'], $this->pObj->MOD_MENU['log_display'], 'index.php', '&setID=' . $setId) . ' - ' . |
||
225 | $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.showresultlog') . ': ' . BackendUtility::getFuncCheck($this->pObj->id, 'SET[log_resultLog]', $this->pObj->MOD_SETTINGS['log_resultLog'], 'index.php', '&setID=' . $setId . $quiPart) . ' - ' . |
||
226 | $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.showfevars') . ': ' . BackendUtility::getFuncCheck($this->pObj->id, 'SET[log_feVars]', $this->pObj->MOD_SETTINGS['log_feVars'], 'index.php', '&setID=' . $setId . $quiPart) . ' - ' . |
||
227 | $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.itemsPerPage') . ': ' . |
||
228 | BackendUtility::getFuncMenu( |
||
229 | $this->pObj->id, |
||
230 | 'SET[itemsPerPage]', |
||
231 | $this->pObj->MOD_SETTINGS['itemsPerPage'], |
||
232 | $this->pObj->MOD_MENU['itemsPerPage'], |
||
233 | 'index.php' |
||
234 | ); |
||
235 | } |
||
236 | |||
237 | $theOutput = $this->pObj->doc->section($LANG->getLL('title'), $h_func, false, true); |
||
238 | |||
239 | // Branch based on type: |
||
240 | switch ((string)$this->pObj->MOD_SETTINGS['crawlaction']) { |
||
241 | case 'start': |
||
242 | if (empty($this->pObj->id)) { |
||
243 | $this->addErrorMessage($GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.noPageSelected')); |
||
244 | } else { |
||
245 | $theOutput .= $this->pObj->doc->section('', $this->drawURLs(), false, true); |
||
246 | } |
||
247 | break; |
||
248 | case 'log': |
||
249 | if (empty($this->pObj->id)) { |
||
250 | $this->addErrorMessage($GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.noPageSelected')); |
||
251 | } else { |
||
252 | $theOutput .= $this->pObj->doc->section('', $this->drawLog(), false, true); |
||
253 | } |
||
254 | break; |
||
255 | case 'cli': |
||
256 | // TODO: drawCLIstatus is not defined, why did we refactor it away? |
||
257 | $theOutput .= $this->pObj->doc->section('', $this->drawCLIstatus(), false, true); |
||
258 | break; |
||
259 | case 'multiprocess': |
||
260 | $theOutput .= $this->pObj->doc->section('', $this->drawProcessOverviewAction(), false, true); |
||
261 | break; |
||
262 | } |
||
263 | |||
264 | return $theOutput; |
||
265 | } |
||
266 | |||
267 | /******************************* |
||
268 | * |
||
269 | * Generate URLs for crawling: |
||
270 | * |
||
271 | ******************************/ |
||
272 | |||
273 | /** |
||
274 | * Produces a table with overview of the URLs to be crawled for each page |
||
275 | * |
||
276 | * @return string HTML output |
||
277 | */ |
||
278 | public function drawURLs() |
||
279 | { |
||
280 | global $BACK_PATH, $BE_USER; |
||
281 | |||
282 | $crawlerParameter = GeneralUtility::_GP('_crawl'); |
||
283 | $downloadParameter = GeneralUtility::_GP('_download'); |
||
284 | |||
285 | // Init: |
||
286 | $this->duplicateTrack = []; |
||
287 | $this->submitCrawlUrls = isset($crawlerParameter); |
||
288 | $this->downloadCrawlUrls = isset($downloadParameter); |
||
289 | $this->makeCrawlerProcessableChecks(); |
||
290 | |||
291 | switch ((string) GeneralUtility::_GP('tstamp')) { |
||
292 | case 'midnight': |
||
293 | $this->scheduledTime = mktime(0, 0, 0); |
||
294 | break; |
||
295 | case '04:00': |
||
296 | $this->scheduledTime = mktime(0, 0, 0) + 4 * 3600; |
||
297 | break; |
||
298 | case 'now': |
||
299 | default: |
||
300 | $this->scheduledTime = time(); |
||
301 | break; |
||
302 | } |
||
303 | // $this->reqMinute = \TYPO3\CMS\Core\Utility\GeneralUtility::intInRange(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('perminute'),1,10000); |
||
304 | // TODO: check relevance |
||
305 | $this->reqMinute = 1000; |
||
306 | |||
307 | $this->incomingConfigurationSelection = GeneralUtility::_GP('configurationSelection'); |
||
0 ignored issues
–
show
|
|||
308 | $this->incomingConfigurationSelection = is_array($this->incomingConfigurationSelection) ? $this->incomingConfigurationSelection : []; |
||
309 | |||
310 | $this->crawlerController = GeneralUtility::makeInstance(CrawlerController::class); |
||
311 | $this->crawlerController->setAccessMode('gui'); |
||
312 | $this->crawlerController->setID = GeneralUtility::md5int(microtime()); |
||
313 | |||
314 | if (empty($this->incomingConfigurationSelection) |
||
315 | || (count($this->incomingConfigurationSelection) == 1 && empty($this->incomingConfigurationSelection[0])) |
||
316 | ) { |
||
317 | $this->addWarningMessage($GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.noConfigSelected')); |
||
318 | $code = ' |
||
319 | <tr> |
||
320 | <td colspan="7"><b>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.noConfigSelected') . '</b></td> |
||
321 | </tr>'; |
||
322 | } else { |
||
323 | if ($this->submitCrawlUrls) { |
||
324 | $reason = new Reason(); |
||
325 | $reason->setReason(Reason::REASON_GUI_SUBMIT); |
||
326 | |||
327 | if ($BE_USER instanceof BackendUserAuthentication) { |
||
328 | $username = $BE_USER->user['username']; |
||
329 | $reason->setDetailText('The user ' . $username . ' added pages to the crawler queue manually '); |
||
330 | } |
||
331 | |||
332 | EventDispatcher::getInstance()->post( |
||
333 | 'invokeQueueChange', |
||
334 | $this->findCrawler()->setID, |
||
335 | ['reason' => $reason] |
||
336 | ); |
||
337 | } |
||
338 | |||
339 | $code = $this->crawlerController->getPageTreeAndUrls( |
||
340 | $this->pObj->id, |
||
341 | $this->pObj->MOD_SETTINGS['depth'], |
||
342 | $this->scheduledTime, |
||
343 | $this->reqMinute, |
||
344 | $this->submitCrawlUrls, |
||
345 | $this->downloadCrawlUrls, |
||
346 | [], // Do not filter any processing instructions |
||
347 | $this->incomingConfigurationSelection |
||
348 | ); |
||
349 | } |
||
350 | |||
351 | $this->downloadUrls = $this->crawlerController->downloadUrls; |
||
352 | $this->duplicateTrack = $this->crawlerController->duplicateTrack; |
||
353 | |||
354 | $output = ''; |
||
355 | if ($code) { |
||
356 | $output .= '<h3>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.configuration') . ':</h3>'; |
||
357 | $output .= '<input type="hidden" name="id" value="' . intval($this->pObj->id) . '" />'; |
||
358 | |||
359 | if (!$this->submitCrawlUrls) { |
||
360 | $output .= $this->drawURLs_cfgSelectors() . '<br />'; |
||
361 | $output .= '<input type="submit" name="_update" value="' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.triggerUpdate') . '" /> '; |
||
362 | $output .= '<input type="submit" name="_crawl" value="' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.triggerCrawl') . '" /> '; |
||
363 | $output .= '<input type="submit" name="_download" value="' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.triggerDownload') . '" /><br /><br />'; |
||
364 | $output .= $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.count') . ': ' . count(array_keys($this->duplicateTrack)) . '<br />'; |
||
365 | $output .= $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.curtime') . ': ' . date('H:i:s', time()) . '<br />'; |
||
366 | $output .= '<br /> |
||
367 | <table class="lrPadding c-list url-table">' . |
||
368 | $this->drawURLs_printTableHeader() . |
||
369 | $code . |
||
370 | '</table>'; |
||
371 | } else { |
||
372 | $output .= count(array_keys($this->duplicateTrack)) . ' ' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.submitted') . '. <br /><br />'; |
||
373 | $output .= '<input type="submit" name="_" value="' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.continue') . '" />'; |
||
374 | $output .= '<input type="submit" onclick="this.form.elements[\'SET[crawlaction]\'].value=\'log\';" value="' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.continueinlog') . '" />'; |
||
375 | } |
||
376 | } |
||
377 | |||
378 | // Download Urls to crawl: |
||
379 | if ($this->downloadCrawlUrls) { |
||
380 | |||
381 | // Creating output header: |
||
382 | $mimeType = 'application/octet-stream'; |
||
383 | Header('Content-Type: ' . $mimeType); |
||
384 | Header('Content-Disposition: attachment; filename=CrawlerUrls.txt'); |
||
385 | |||
386 | // Printing the content of the CSV lines: |
||
387 | echo implode(chr(13) . chr(10), $this->downloadUrls); |
||
388 | |||
389 | exit; |
||
390 | } |
||
391 | |||
392 | return $output; |
||
393 | } |
||
394 | |||
395 | /** |
||
396 | * Draws the configuration selectors for compiling URLs: |
||
397 | * |
||
398 | * @return string HTML table |
||
399 | */ |
||
400 | public function drawURLs_cfgSelectors() |
||
401 | { |
||
402 | $cell = []; |
||
403 | |||
404 | // depth |
||
405 | $cell[] = $this->selectorBox( |
||
406 | [ |
||
407 | 0 => $GLOBALS['LANG']->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_0'), |
||
408 | 1 => $GLOBALS['LANG']->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_1'), |
||
409 | 2 => $GLOBALS['LANG']->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_2'), |
||
410 | 3 => $GLOBALS['LANG']->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_3'), |
||
411 | 4 => $GLOBALS['LANG']->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_4'), |
||
412 | 99 => $GLOBALS['LANG']->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:labels.depth_infi'), |
||
413 | ], |
||
414 | 'SET[depth]', |
||
415 | $this->pObj->MOD_SETTINGS['depth'], |
||
416 | false |
||
417 | ); |
||
418 | $availableConfigurations = $this->crawlerController->getConfigurationsForBranch($this->pObj->id, $this->pObj->MOD_SETTINGS['depth'] ? $this->pObj->MOD_SETTINGS['depth'] : 0); |
||
419 | |||
420 | // Configurations |
||
421 | $cell[] = $this->selectorBox( |
||
422 | empty($availableConfigurations) ? [] : array_combine($availableConfigurations, $availableConfigurations), |
||
423 | 'configurationSelection', |
||
424 | $this->incomingConfigurationSelection, |
||
0 ignored issues
–
show
$this->incomingConfigurationSelection is of type array , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
425 | true |
||
426 | ); |
||
427 | |||
428 | // Scheduled time: |
||
429 | $cell[] = $this->selectorBox( |
||
430 | [ |
||
431 | 'now' => $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.time.now'), |
||
432 | 'midnight' => $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.time.midnight'), |
||
433 | '04:00' => $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.time.4am'), |
||
434 | ], |
||
435 | 'tstamp', |
||
436 | GeneralUtility::_POST('tstamp'), |
||
0 ignored issues
–
show
It seems like
\TYPO3\CMS\Core\Utility\...tility::_POST('tstamp') targeting TYPO3\CMS\Core\Utility\GeneralUtility::_POST() can also be of type array or null ; however, AOE\Crawler\Backend\BackendModule::selectorBox() does only seem to accept string , maybe add an additional type check?
This check looks at variables that are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble.
Loading history...
|
|||
437 | false |
||
438 | ); |
||
439 | |||
440 | $output = ' |
||
441 | <table class="lrPadding c-list"> |
||
442 | <tr class="bgColor5 tableheader"> |
||
443 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.depth') . ':</td> |
||
444 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.configurations') . ':</td> |
||
445 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.scheduled') . ':</td> |
||
446 | </tr> |
||
447 | <tr class="bgColor4"> |
||
448 | <td valign="top">' . implode('</td> |
||
449 | <td valign="top">', $cell) . '</td> |
||
450 | </tr> |
||
451 | </table>'; |
||
452 | |||
453 | return $output; |
||
454 | } |
||
455 | |||
456 | /** |
||
457 | * Create Table header row for URL display |
||
458 | * |
||
459 | * @return string Table header |
||
460 | */ |
||
461 | public function drawURLs_printTableHeader() |
||
462 | { |
||
463 | $content = ' |
||
464 | <tr class="bgColor5 tableheader"> |
||
465 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.pagetitle') . ':</td> |
||
466 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.key') . ':</td> |
||
467 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.parametercfg') . ':</td> |
||
468 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.values') . ':</td> |
||
469 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.urls') . ':</td> |
||
470 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.options') . ':</td> |
||
471 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.parameters') . ':</td> |
||
472 | </tr>'; |
||
473 | |||
474 | return $content; |
||
475 | } |
||
476 | |||
477 | /******************************* |
||
478 | * |
||
479 | * Shows log of indexed URLs |
||
480 | * |
||
481 | ******************************/ |
||
482 | |||
483 | /** |
||
484 | * Shows the log of indexed URLs |
||
485 | * |
||
486 | * @return string HTML output |
||
487 | */ |
||
488 | public function drawLog() |
||
489 | { |
||
490 | global $BACK_PATH; |
||
491 | $output = ''; |
||
492 | |||
493 | // Init: |
||
494 | $this->crawlerController = GeneralUtility::makeInstance(CrawlerController::class); |
||
495 | $this->crawlerController->setAccessMode('gui'); |
||
496 | $this->crawlerController->setID = GeneralUtility::md5int(microtime()); |
||
497 | |||
498 | $csvExport = GeneralUtility::_POST('_csv'); |
||
499 | $this->CSVExport = isset($csvExport); |
||
500 | |||
501 | // Read URL: |
||
502 | if (GeneralUtility::_GP('qid_read')) { |
||
503 | $this->crawlerController->readUrl(intval(GeneralUtility::_GP('qid_read')), true); |
||
504 | } |
||
505 | |||
506 | // Look for set ID sent - if it is, we will display contents of that set: |
||
507 | $showSetId = intval(GeneralUtility::_GP('setID')); |
||
508 | |||
509 | // Show details: |
||
510 | if (GeneralUtility::_GP('qid_details')) { |
||
511 | |||
512 | // Get entry record: |
||
513 | list($q_entry) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'tx_crawler_queue', 'qid=' . intval(GeneralUtility::_GP('qid_details'))); |
||
514 | |||
515 | // Explode values: |
||
516 | $resStatus = $this->getResStatus($q_entry); |
||
517 | $q_entry['parameters'] = unserialize($q_entry['parameters']); |
||
518 | $q_entry['result_data'] = unserialize($q_entry['result_data']); |
||
519 | if (is_array($q_entry['result_data'])) { |
||
520 | $q_entry['result_data']['content'] = unserialize($q_entry['result_data']['content']); |
||
521 | |||
522 | if (!$this->pObj->MOD_SETTINGS['log_resultLog']) { |
||
523 | unset($q_entry['result_data']['content']['log']); |
||
524 | } |
||
525 | } |
||
526 | |||
527 | // Print rudimentary details: |
||
528 | $output .= ' |
||
529 | <br /><br /> |
||
530 | <input type="submit" value="' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.back') . '" name="_back" /> |
||
531 | <input type="hidden" value="' . $this->pObj->id . '" name="id" /> |
||
532 | <input type="hidden" value="' . $showSetId . '" name="setID" /> |
||
533 | <br /> |
||
534 | Current server time: ' . date('H:i:s', time()) . '<br />' . |
||
535 | 'Status: ' . $resStatus . '<br />' . |
||
536 | DebugUtility::viewArray($q_entry); |
||
537 | } else { // Show list: |
||
538 | |||
539 | // If either id or set id, show list: |
||
540 | if ($this->pObj->id || $showSetId) { |
||
541 | if ($this->pObj->id) { |
||
542 | // Drawing tree: |
||
543 | $tree = GeneralUtility::makeInstance(PageTreeView::class); |
||
544 | $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1); |
||
545 | $tree->init('AND ' . $perms_clause); |
||
546 | |||
547 | // Set root row: |
||
548 | $HTML = IconUtility::getIconForRecord('pages', $this->pObj->pageinfo); |
||
549 | $tree->tree[] = [ |
||
550 | 'row' => $this->pObj->pageinfo, |
||
551 | 'HTML' => $HTML |
||
552 | ]; |
||
553 | |||
554 | // Get branch beneath: |
||
555 | if ($this->pObj->MOD_SETTINGS['depth']) { |
||
556 | $tree->getTree($this->pObj->id, $this->pObj->MOD_SETTINGS['depth'], ''); |
||
557 | } |
||
558 | |||
559 | // Traverse page tree: |
||
560 | $code = ''; |
||
561 | $count = 0; |
||
562 | foreach ($tree->tree as $data) { |
||
563 | $code .= $this->drawLog_addRows( |
||
564 | $data['row'], |
||
565 | $data['HTML'] . BackendUtility::getRecordTitle('pages', $data['row'], true), |
||
566 | intval($this->pObj->MOD_SETTINGS['itemsPerPage']) |
||
567 | ); |
||
568 | if (++$count == 1000) { |
||
569 | break; |
||
570 | } |
||
571 | } |
||
572 | } else { |
||
573 | $code = ''; |
||
574 | $code .= $this->drawLog_addRows( |
||
575 | $showSetId, |
||
0 ignored issues
–
show
$showSetId is of type integer , but the function expects a array .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
576 | 'Set ID: ' . $showSetId |
||
577 | ); |
||
578 | } |
||
579 | |||
580 | if ($code) { |
||
581 | $output .= ' |
||
582 | <br /><br /> |
||
583 | <input type="submit" value="' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.reloadlist') . '" name="_reload" /> |
||
584 | <input type="submit" value="' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.downloadcsv') . '" name="_csv" /> |
||
585 | <input type="submit" value="' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.flushvisiblequeue') . '" name="_flush" onclick="return confirm(\'' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.confirmyouresure') . '\');" /> |
||
586 | <input type="submit" value="' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.flushfullqueue') . '" name="_flush_all" onclick="return confirm(\'' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.confirmyouresure') . '\');" /> |
||
587 | <input type="hidden" value="' . $this->pObj->id . '" name="id" /> |
||
588 | <input type="hidden" value="' . $showSetId . '" name="setID" /> |
||
589 | <br /> |
||
590 | ' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.curtime') . ': ' . date('H:i:s', time()) . ' |
||
591 | <br /><br /> |
||
592 | |||
593 | |||
594 | <table class="lrPadding c-list crawlerlog">' . |
||
595 | $this->drawLog_printTableHeader() . |
||
596 | $code . |
||
597 | '</table>'; |
||
598 | } |
||
599 | } else { // Otherwise show available sets: |
||
600 | $setList = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows( |
||
601 | 'set_id, count(*) as count_value, scheduled', |
||
602 | 'tx_crawler_queue', |
||
603 | '', |
||
604 | 'set_id, scheduled', |
||
605 | 'scheduled DESC' |
||
606 | ); |
||
607 | |||
608 | $code = ' |
||
609 | <tr class="bgColor5 tableheader"> |
||
610 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.setid') . ':</td> |
||
611 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.count') . 't:</td> |
||
612 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.time') . ':</td> |
||
613 | </tr> |
||
614 | '; |
||
615 | |||
616 | $cc = 0; |
||
617 | foreach ($setList as $set) { |
||
618 | $code .= ' |
||
619 | <tr class="bgColor' . ($cc % 2 ? '-20' : '-10') . '"> |
||
620 | <td><a href="' . htmlspecialchars('index.php?setID=' . $set['set_id']) . '">' . $set['set_id'] . '</a></td> |
||
621 | <td>' . $set['count_value'] . '</td> |
||
622 | <td>' . BackendUtility::dateTimeAge($set['scheduled']) . '</td> |
||
623 | </tr> |
||
624 | '; |
||
625 | |||
626 | $cc++; |
||
627 | } |
||
628 | |||
629 | $output .= ' |
||
630 | <br /><br /> |
||
631 | <table class="lrPadding c-list">' . |
||
632 | $code . |
||
633 | '</table>'; |
||
634 | } |
||
635 | } |
||
636 | |||
637 | if ($this->CSVExport) { |
||
638 | $this->outputCsvFile(); |
||
639 | } |
||
640 | |||
641 | // Return output |
||
642 | return $output; |
||
643 | } |
||
644 | |||
645 | /** |
||
646 | * Outputs the CSV file and sets the correct headers |
||
647 | */ |
||
648 | protected function outputCsvFile() |
||
649 | { |
||
650 | if (!count($this->CSVaccu)) { |
||
651 | $this->addWarningMessage($GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:message.canNotExportEmptyQueueToCsvText')); |
||
652 | return; |
||
653 | } |
||
654 | |||
655 | $csvLines = []; |
||
656 | |||
657 | // Field names: |
||
658 | reset($this->CSVaccu); |
||
659 | $fieldNames = array_keys(current($this->CSVaccu)); |
||
660 | $csvLines[] = GeneralUtility::csvValues($fieldNames); |
||
661 | |||
662 | // Data: |
||
663 | foreach ($this->CSVaccu as $row) { |
||
664 | $csvLines[] = GeneralUtility::csvValues($row); |
||
665 | } |
||
666 | |||
667 | // Creating output header: |
||
668 | $mimeType = 'application/octet-stream'; |
||
669 | Header('Content-Type: ' . $mimeType); |
||
670 | Header('Content-Disposition: attachment; filename=CrawlerLog.csv'); |
||
671 | |||
672 | // Printing the content of the CSV lines: |
||
673 | echo implode(chr(13) . chr(10), $csvLines); |
||
674 | |||
675 | // Exits: |
||
676 | exit; |
||
677 | } |
||
678 | |||
679 | /** |
||
680 | * Create the rows for display of the page tree |
||
681 | * For each page a number of rows are shown displaying GET variable configuration |
||
682 | * |
||
683 | * @param array $pageRow_setId Page row or set-id |
||
684 | * @param string $titleString Title string |
||
685 | * @param int $itemsPerPage Items per Page setting |
||
686 | * |
||
687 | * @return string HTML <tr> content (one or more) |
||
688 | */ |
||
689 | public function drawLog_addRows($pageRow_setId, $titleString, $itemsPerPage = 10) |
||
690 | { |
||
691 | |||
692 | // If Flush button is pressed, flush tables instead of selecting entries: |
||
693 | |||
694 | if (GeneralUtility::_POST('_flush')) { |
||
695 | $doFlush = true; |
||
696 | $doFullFlush = false; |
||
697 | } elseif (GeneralUtility::_POST('_flush_all')) { |
||
698 | $doFlush = true; |
||
699 | $doFullFlush = true; |
||
700 | } else { |
||
701 | $doFlush = false; |
||
702 | $doFullFlush = false; |
||
703 | } |
||
704 | |||
705 | // Get result: |
||
706 | if (is_array($pageRow_setId)) { |
||
707 | $res = $this->crawlerController->getLogEntriesForPageId($pageRow_setId['uid'], $this->pObj->MOD_SETTINGS['log_display'], $doFlush, $doFullFlush, intval($itemsPerPage)); |
||
708 | } else { |
||
709 | $res = $this->crawlerController->getLogEntriesForSetId($pageRow_setId, $this->pObj->MOD_SETTINGS['log_display'], $doFlush, $doFullFlush, intval($itemsPerPage)); |
||
710 | } |
||
711 | |||
712 | // Init var: |
||
713 | $colSpan = 9 |
||
714 | + ($this->pObj->MOD_SETTINGS['log_resultLog'] ? -1 : 0) |
||
715 | + ($this->pObj->MOD_SETTINGS['log_feVars'] ? 3 : 0); |
||
716 | |||
717 | if (count($res)) { |
||
718 | // Traverse parameter combinations: |
||
719 | $c = 0; |
||
720 | $content = ''; |
||
721 | foreach ($res as $kk => $vv) { |
||
0 ignored issues
–
show
The expression
$res of type array|null is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
Loading history...
|
|||
722 | |||
723 | // Title column: |
||
724 | if (!$c) { |
||
725 | $titleClm = '<td rowspan="' . count($res) . '">' . $titleString . '</td>'; |
||
726 | } else { |
||
727 | $titleClm = ''; |
||
728 | } |
||
729 | |||
730 | // Result: |
||
731 | $resLog = $this->getResultLog($vv); |
||
732 | |||
733 | $resStatus = $this->getResStatus($vv); |
||
734 | $resFeVars = $this->getResFeVars($vv); |
||
735 | |||
736 | // Compile row: |
||
737 | $parameters = unserialize($vv['parameters']); |
||
738 | |||
739 | // Put data into array: |
||
740 | $rowData = []; |
||
741 | if ($this->pObj->MOD_SETTINGS['log_resultLog']) { |
||
742 | $rowData['result_log'] = $resLog; |
||
743 | } else { |
||
744 | $rowData['scheduled'] = ($vv['scheduled'] > 0) ? BackendUtility::datetime($vv['scheduled']) : ' ' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.immediate'); |
||
745 | $rowData['exec_time'] = $vv['exec_time'] ? BackendUtility::datetime($vv['exec_time']) : '-'; |
||
746 | } |
||
747 | $rowData['result_status'] = GeneralUtility::fixed_lgd_cs($resStatus, 50); |
||
748 | $rowData['url'] = '<a href="' . htmlspecialchars($parameters['url']) . '" target="_newWIndow">' . htmlspecialchars($parameters['url']) . '</a>'; |
||
749 | $rowData['feUserGroupList'] = $parameters['feUserGroupList']; |
||
750 | $rowData['procInstructions'] = is_array($parameters['procInstructions']) ? implode('; ', $parameters['procInstructions']) : ''; |
||
751 | $rowData['set_id'] = $vv['set_id']; |
||
752 | |||
753 | if ($this->pObj->MOD_SETTINGS['log_feVars']) { |
||
754 | $rowData['tsfe_id'] = $resFeVars['id']; |
||
755 | $rowData['tsfe_gr_list'] = $resFeVars['gr_list']; |
||
756 | $rowData['tsfe_no_cache'] = $resFeVars['no_cache']; |
||
757 | } |
||
758 | |||
759 | $setId = intval(GeneralUtility::_GP('setID')); |
||
760 | $refreshIcon = IconUtility::getIcon('actions-system-refresh', Icon::SIZE_SMALL); |
||
761 | |||
762 | // Put rows together: |
||
763 | $content .= ' |
||
764 | <tr class="bgColor' . ($c % 2 ? '-20' : '-10') . '"> |
||
765 | ' . $titleClm . ' |
||
766 | <td><a href="' . $this->getModuleUrl(['qid_details' => $vv['qid'], 'setID' => $setId]) . '">' . htmlspecialchars($vv['qid']) . '</a></td> |
||
767 | <td><a href="' . $this->getModuleUrl(['qid_read' => $vv['qid'], 'setID' => $setId]) . '">' . $refreshIcon . '</a></td>'; |
||
768 | foreach ($rowData as $fKey => $value) { |
||
769 | if (GeneralUtility::inList('url', $fKey)) { |
||
770 | $content .= ' |
||
771 | <td>' . $value . '</td>'; |
||
772 | } else { |
||
773 | $content .= ' |
||
774 | <td>' . nl2br(htmlspecialchars($value)) . '</td>'; |
||
775 | } |
||
776 | } |
||
777 | $content .= ' |
||
778 | </tr>'; |
||
779 | $c++; |
||
780 | |||
781 | if ($this->CSVExport) { |
||
782 | // Only for CSV (adding qid and scheduled/exec_time if needed): |
||
783 | $rowData['result_log'] = implode('// ', explode(chr(10), $resLog)); |
||
784 | $rowData['qid'] = $vv['qid']; |
||
785 | $rowData['scheduled'] = BackendUtility::datetime($vv['scheduled']); |
||
786 | $rowData['exec_time'] = $vv['exec_time'] ? BackendUtility::datetime($vv['exec_time']) : '-'; |
||
787 | $this->CSVaccu[] = $rowData; |
||
788 | } |
||
789 | } |
||
790 | } else { |
||
791 | |||
792 | // Compile row: |
||
793 | $content = ' |
||
794 | <tr class="bgColor-20"> |
||
795 | <td>' . $titleString . '</td> |
||
796 | <td colspan="' . $colSpan . '"><em>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.noentries') . '</em></td> |
||
797 | </tr>'; |
||
798 | } |
||
799 | |||
800 | return $content; |
||
801 | } |
||
802 | |||
803 | /** |
||
804 | * Find Fe vars |
||
805 | * |
||
806 | * @param array $row |
||
807 | * @return array |
||
808 | */ |
||
809 | public function getResFeVars($row) |
||
810 | { |
||
811 | $feVars = []; |
||
812 | |||
813 | if ($row['result_data']) { |
||
814 | $resultData = unserialize($row['result_data']); |
||
815 | $requestResult = unserialize($resultData['content']); |
||
816 | $feVars = $requestResult['vars']; |
||
817 | } |
||
818 | |||
819 | return $feVars; |
||
820 | } |
||
821 | |||
822 | /** |
||
823 | * Create Table header row (log) |
||
824 | * |
||
825 | * @return string Table header |
||
826 | */ |
||
827 | public function drawLog_printTableHeader() |
||
828 | { |
||
829 | $content = ' |
||
830 | <tr class="bgColor5 tableheader"> |
||
831 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.pagetitle') . ':</td> |
||
832 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.qid') . ':</td> |
||
833 | <td> </td>' . |
||
834 | ($this->pObj->MOD_SETTINGS['log_resultLog'] ? ' |
||
835 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.resultlog') . ':</td>' : ' |
||
836 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.scheduledtime') . ':</td> |
||
837 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.runtime') . ':</td>') . ' |
||
838 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.status') . ':</td> |
||
839 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.url') . ':</td> |
||
840 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.groups') . ':</td> |
||
841 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.procinstr') . ':</td> |
||
842 | <td>' . $GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.setid') . ':</td>' . |
||
843 | ($this->pObj->MOD_SETTINGS['log_feVars'] ? ' |
||
844 | <td>' . htmlspecialchars('TSFE->id') . '</td> |
||
845 | <td>' . htmlspecialchars('TSFE->gr_list') . '</td> |
||
846 | <td>' . htmlspecialchars('TSFE->no_cache') . '</td>' : '') . ' |
||
847 | </tr>'; |
||
848 | |||
849 | return $content; |
||
850 | } |
||
851 | |||
852 | /** |
||
853 | * Extract the log information from the current row and retrive it as formatted string. |
||
854 | * |
||
855 | * @param array $resultRow |
||
856 | * |
||
857 | * @return string |
||
858 | */ |
||
859 | protected function getResultLog($resultRow) |
||
860 | { |
||
861 | $content = ''; |
||
862 | |||
863 | if (is_array($resultRow) && array_key_exists('result_data', $resultRow)) { |
||
864 | $requestContent = unserialize($resultRow['result_data']); |
||
865 | $requestResult = unserialize($requestContent['content']); |
||
866 | |||
867 | if (is_array($requestResult) && array_key_exists('log', $requestResult)) { |
||
868 | $content = implode(chr(10), $requestResult['log']); |
||
869 | } |
||
870 | } |
||
871 | |||
872 | return $content; |
||
873 | } |
||
874 | |||
875 | public function getResStatus($vv) |
||
876 | { |
||
877 | if ($vv['result_data']) { |
||
878 | $requestContent = unserialize($vv['result_data']); |
||
879 | $requestResult = unserialize($requestContent['content']); |
||
880 | if (is_array($requestResult)) { |
||
881 | if (empty($requestResult['errorlog'])) { |
||
882 | $resStatus = 'OK'; |
||
883 | } else { |
||
884 | $resStatus = implode("\n", $requestResult['errorlog']); |
||
885 | } |
||
886 | } else { |
||
887 | $resStatus = 'Error: ' . substr(preg_replace('/\s+/', ' ', strip_tags($requestContent['content'])), 0, 10000) . '...'; |
||
888 | } |
||
889 | } else { |
||
890 | $resStatus = '-'; |
||
891 | } |
||
892 | return $resStatus; |
||
893 | } |
||
894 | |||
895 | /***************************** |
||
896 | * |
||
897 | * CLI status display |
||
898 | * |
||
899 | *****************************/ |
||
900 | |||
901 | /** |
||
902 | * This method is used to show an overview about the active an the finished crawling processes |
||
903 | * |
||
904 | * @param void |
||
905 | * @return string |
||
906 | */ |
||
907 | protected function drawProcessOverviewAction() |
||
908 | { |
||
909 | $this->runRefreshHooks(); |
||
910 | |||
911 | global $BACK_PATH; |
||
912 | $this->makeCrawlerProcessableChecks(); |
||
913 | |||
914 | $crawler = $this->findCrawler(); |
||
915 | try { |
||
916 | $this->handleProcessOverviewActions(); |
||
917 | } catch (\Exception $e) { |
||
918 | $this->addErrorMessage($e->getMessage()); |
||
919 | } |
||
920 | |||
921 | $offset = intval(GeneralUtility::_GP('offset')); |
||
922 | $perpage = 20; |
||
923 | |||
924 | $processRepository = new ProcessRepository(); |
||
925 | $queueRepository = new QueueRepository(); |
||
926 | |||
927 | $mode = $this->pObj->MOD_SETTINGS['processListMode']; |
||
928 | $where = ''; |
||
929 | if ($mode == 'simple') { |
||
930 | $where = 'active = 1'; |
||
931 | } |
||
932 | |||
933 | $allProcesses = $processRepository->findAll('ttl', 'DESC', $perpage, $offset, $where); |
||
934 | $allCount = $processRepository->countAll($where); |
||
935 | |||
936 | $listView = new ProcessListView(); |
||
937 | $listView->setPageId($this->pObj->id); |
||
938 | $listView->setIconPath($BACK_PATH . '../typo3conf/ext/crawler/template/process/res/img/'); |
||
939 | $listView->setProcessCollection($allProcesses); |
||
940 | $listView->setCliPath($this->processManager->getCrawlerCliPath()); |
||
941 | $listView->setIsCrawlerEnabled(!$crawler->getDisabled() && !$this->isErrorDetected); |
||
942 | $listView->setTotalUnprocessedItemCount($queueRepository->countAllPendingItems()); |
||
943 | $listView->setAssignedUnprocessedItemCount($queueRepository->countAllAssignedPendingItems()); |
||
944 | $listView->setActiveProcessCount($processRepository->countActive()); |
||
945 | $listView->setMaxActiveProcessCount(MathUtility::forceIntegerInRange($this->extensionSettings['processLimit'], 1, 99, 1)); |
||
946 | $listView->setMode($mode); |
||
947 | |||
948 | $paginationView = new PaginationView(); |
||
949 | $paginationView->setCurrentOffset($offset); |
||
950 | $paginationView->setPerPage($perpage); |
||
951 | $paginationView->setTotalItemCount($allCount); |
||
952 | |||
953 | $output = $listView->render(); |
||
954 | |||
955 | if ($paginationView->getTotalPagesCount() > 1) { |
||
956 | $output .= ' <br />' . $paginationView->render(); |
||
957 | } |
||
958 | |||
959 | return $output; |
||
960 | } |
||
961 | |||
962 | /** |
||
963 | * Verify that the crawler is exectuable. |
||
964 | * |
||
965 | * @return void |
||
966 | */ |
||
967 | protected function makeCrawlerProcessableChecks() |
||
968 | { |
||
969 | global $LANG; |
||
970 | |||
971 | if ($this->isCrawlerUserAvailable() === false) { |
||
972 | $this->addErrorMessage($LANG->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:message.noBeUserAvailable')); |
||
973 | } elseif ($this->isCrawlerUserNotAdmin() === false) { |
||
974 | $this->addErrorMessage($LANG->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:message.beUserIsAdmin')); |
||
975 | } |
||
976 | |||
977 | if ($this->isPhpForkAvailable() === false) { |
||
978 | $this->addErrorMessage($LANG->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:message.noPhpForkAvailable')); |
||
979 | } |
||
980 | |||
981 | $exitCode = 0; |
||
982 | $out = []; |
||
983 | exec(escapeshellcmd($this->extensionSettings['phpPath'] . ' -v'), $out, $exitCode); |
||
984 | if ($exitCode > 0) { |
||
985 | $this->addErrorMessage(sprintf($LANG->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:message.phpBinaryNotFound'), htmlspecialchars($this->extensionSettings['phpPath']))); |
||
986 | } |
||
987 | } |
||
988 | |||
989 | /** |
||
990 | * Indicate that the required PHP method "popen" is |
||
991 | * available in the system. |
||
992 | * |
||
993 | * @return boolean |
||
994 | */ |
||
995 | protected function isPhpForkAvailable() |
||
996 | { |
||
997 | return function_exists('popen'); |
||
998 | } |
||
999 | |||
1000 | /** |
||
1001 | * Indicate that the required be_user "_cli_crawler" is |
||
1002 | * global available in the system. |
||
1003 | * |
||
1004 | * @return boolean |
||
1005 | */ |
||
1006 | protected function isCrawlerUserAvailable() |
||
1007 | { |
||
1008 | $isAvailable = false; |
||
1009 | $userArray = BackendUtility::getRecordsByField('be_users', 'username', '_cli_crawler'); |
||
1010 | |||
1011 | if (is_array($userArray)) { |
||
1012 | $isAvailable = true; |
||
1013 | } |
||
1014 | |||
1015 | return $isAvailable; |
||
1016 | } |
||
1017 | |||
1018 | /** |
||
1019 | * Indicate that the required be_user "_cli_crawler" is |
||
1020 | * has no admin rights. |
||
1021 | * |
||
1022 | * @return boolean |
||
1023 | */ |
||
1024 | protected function isCrawlerUserNotAdmin() |
||
1025 | { |
||
1026 | $isAvailable = false; |
||
1027 | $userArray = BackendUtility::getRecordsByField('be_users', 'username', '_cli_crawler'); |
||
1028 | |||
1029 | if (is_array($userArray) && $userArray[0]['admin'] == 0) { |
||
1030 | $isAvailable = true; |
||
1031 | } |
||
1032 | |||
1033 | return $isAvailable; |
||
1034 | } |
||
1035 | |||
1036 | /** |
||
1037 | * Method to handle incomming actions of the process overview |
||
1038 | * |
||
1039 | * @throws \Exception |
||
1040 | * |
||
1041 | * @return void |
||
1042 | */ |
||
1043 | protected function handleProcessOverviewActions() |
||
1044 | { |
||
1045 | $crawler = $this->findCrawler(); |
||
1046 | |||
1047 | switch (GeneralUtility::_GP('action')) { |
||
1048 | case 'stopCrawling': |
||
1049 | //set the cli status to disable (all processes will be terminated) |
||
1050 | $crawler->setDisabled(true); |
||
1051 | break; |
||
1052 | case 'resumeCrawling': |
||
1053 | //set the cli status to end (all processes will be terminated) |
||
1054 | $crawler->setDisabled(false); |
||
1055 | break; |
||
1056 | case 'addProcess': |
||
1057 | $handle = $this->processManager->startProcess(); |
||
1058 | if ($handle === false) { |
||
1059 | throw new \Exception($GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.newprocesserror')); |
||
1060 | } |
||
1061 | $this->addNoticeMessage($GLOBALS['LANG']->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xml:labels.newprocess')); |
||
1062 | break; |
||
1063 | } |
||
1064 | } |
||
1065 | |||
1066 | /** |
||
1067 | * Returns the singleton instance of the crawler. |
||
1068 | * |
||
1069 | * @param void |
||
1070 | * @return CrawlerController crawler object |
||
1071 | */ |
||
1072 | protected function findCrawler() |
||
1073 | { |
||
1074 | if (!$this->crawlerController instanceof CrawlerController) { |
||
1075 | $this->crawlerController = GeneralUtility::makeInstance(CrawlerController::class); |
||
1076 | } |
||
1077 | return $this->crawlerController; |
||
1078 | } |
||
1079 | |||
1080 | /***************************** |
||
1081 | * |
||
1082 | * General Helper Functions |
||
1083 | * |
||
1084 | *****************************/ |
||
1085 | |||
1086 | /** |
||
1087 | * This method is used to add a message to the internal queue |
||
1088 | * |
||
1089 | * @param string the message itself |
||
1090 | * @param integer message level (-1 = success (default), 0 = info, 1 = notice, 2 = warning, 3 = error) |
||
1091 | * |
||
1092 | * @return void |
||
1093 | */ |
||
1094 | private function addMessage($message, $severity = FlashMessage::OK) |
||
1095 | { |
||
1096 | $message = GeneralUtility::makeInstance( |
||
1097 | FlashMessage::class, |
||
1098 | $message, |
||
1099 | '', |
||
1100 | $severity |
||
1101 | ); |
||
1102 | |||
1103 | // TODO: |
||
1104 | /** @var FlashMessageService $flashMessageService */ |
||
1105 | $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class); |
||
1106 | $flashMessageService->getMessageQueueByIdentifier()->addMessage($message); |
||
1107 | } |
||
1108 | |||
1109 | /** |
||
1110 | * Add notice message to the user interface. |
||
1111 | * |
||
1112 | * @param string The message |
||
1113 | * |
||
1114 | * @return void |
||
1115 | */ |
||
1116 | protected function addNoticeMessage($message) |
||
1117 | { |
||
1118 | $this->addMessage($message, FlashMessage::NOTICE); |
||
1119 | } |
||
1120 | |||
1121 | /** |
||
1122 | * Add error message to the user interface. |
||
1123 | * |
||
1124 | * @param string The message |
||
1125 | * |
||
1126 | * @return void |
||
1127 | */ |
||
1128 | protected function addErrorMessage($message) |
||
1129 | { |
||
1130 | $this->isErrorDetected = true; |
||
1131 | $this->addMessage($message, FlashMessage::ERROR); |
||
1132 | } |
||
1133 | |||
1134 | /** |
||
1135 | * Add error message to the user interface. |
||
1136 | * |
||
1137 | * NOTE: |
||
1138 | * This method is basesd on TYPO3 4.3 or higher! |
||
1139 | * |
||
1140 | * @param string The message |
||
1141 | * |
||
1142 | * @return void |
||
1143 | */ |
||
1144 | protected function addWarningMessage($message) |
||
1145 | { |
||
1146 | $this->addMessage($message, FlashMessage::WARNING); |
||
1147 | } |
||
1148 | |||
1149 | /** |
||
1150 | * Create selector box |
||
1151 | * |
||
1152 | * @param array $optArray Options key(value) => label pairs |
||
1153 | * @param string $name Selector box name |
||
1154 | * @param string $value Selector box value (array for multiple...) |
||
1155 | * @param boolean $multiple If set, will draw multiple box. |
||
1156 | * |
||
1157 | * @return string HTML select element |
||
1158 | */ |
||
1159 | public function selectorBox($optArray, $name, $value, $multiple) |
||
1160 | { |
||
1161 | $options = []; |
||
1162 | foreach ($optArray as $key => $val) { |
||
1163 | $options[] = ' |
||
1164 | <option value="' . htmlspecialchars($key) . '"' . ((!$multiple && !strcmp($value, $key)) || ($multiple && in_array($key, (array)$value)) ? ' selected="selected"' : '') . '>' . htmlspecialchars($val) . '</option>'; |
||
1165 | } |
||
1166 | |||
1167 | $output = '<select name="' . htmlspecialchars($name . ($multiple ? '[]' : '')) . '"' . ($multiple ? ' multiple="multiple" size="' . count($options) . '"' : '') . '>' . implode('', $options) . '</select>'; |
||
1168 | |||
1169 | return $output; |
||
1170 | } |
||
1171 | |||
1172 | /** |
||
1173 | * Activate hooks |
||
1174 | * |
||
1175 | * @return void |
||
1176 | */ |
||
1177 | public function runRefreshHooks() |
||
1178 | { |
||
1179 | $crawlerLib = GeneralUtility::makeInstance(CrawlerController::class); |
||
1180 | if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['crawler']['refresh_hooks'])) { |
||
1181 | foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['crawler']['refresh_hooks'] as $objRef) { |
||
1182 | $hookObj = &GeneralUtility::getUserObj($objRef); |
||
1183 | if (is_object($hookObj)) { |
||
1184 | $hookObj->crawler_init($crawlerLib); |
||
1185 | } |
||
1186 | } |
||
1187 | } |
||
1188 | } |
||
1189 | |||
1190 | /** |
||
1191 | * Returns the URL to the current module, including $_GET['id']. |
||
1192 | * |
||
1193 | * @param array $urlParameters optional parameters to add to the URL |
||
1194 | * @return string |
||
1195 | */ |
||
1196 | protected function getModuleUrl(array $urlParameters = []) |
||
1197 | { |
||
1198 | if ($this->pObj->id) { |
||
1199 | $urlParameters = array_merge($urlParameters, [ |
||
1200 | 'id' => $this->pObj->id |
||
1201 | ]); |
||
1202 | } |
||
1203 | return BackendUtility::getModuleUrl(GeneralUtility::_GP('M'), $urlParameters); |
||
0 ignored issues
–
show
It seems like
\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('M') targeting TYPO3\CMS\Core\Utility\GeneralUtility::_GP() can also be of type array or null ; however, TYPO3\CMS\Backend\Utilit...Utility::getModuleUrl() does only seem to accept string , maybe add an additional type check?
This check looks at variables that are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble.
Loading history...
|
|||
1204 | } |
||
1205 | } |
||
1206 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.