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