1 | <?php |
||||
2 | |||||
3 | declare(strict_types=1); |
||||
4 | |||||
5 | namespace AOE\Crawler\Backend\RequestForm; |
||||
6 | |||||
7 | use AOE\Crawler\Backend\Helper\ResultHandler; |
||||
8 | use AOE\Crawler\Backend\Helper\UrlBuilder; |
||||
9 | use AOE\Crawler\Converter\JsonCompatibilityConverter; |
||||
10 | use AOE\Crawler\Domain\Repository\QueueRepository; |
||||
11 | use AOE\Crawler\Utility\MessageUtility; |
||||
12 | use AOE\Crawler\Value\QueueFilter; |
||||
13 | use AOE\Crawler\Writer\FileWriter\CsvWriter\CrawlerCsvWriter; |
||||
14 | use AOE\Crawler\Writer\FileWriter\CsvWriter\CsvWriterInterface; |
||||
15 | use Doctrine\DBAL\Query\QueryBuilder; |
||||
16 | use TYPO3\CMS\Backend\Tree\View\PageTreeView; |
||||
17 | use TYPO3\CMS\Backend\Utility\BackendUtility; |
||||
18 | use TYPO3\CMS\Core\Database\ConnectionPool; |
||||
19 | use TYPO3\CMS\Core\Imaging\Icon; |
||||
20 | use TYPO3\CMS\Core\Imaging\IconFactory; |
||||
21 | use TYPO3\CMS\Core\Utility\DebugUtility; |
||||
22 | use TYPO3\CMS\Core\Utility\GeneralUtility; |
||||
23 | use TYPO3\CMS\Extbase\Object\ObjectManager; |
||||
24 | use TYPO3\CMS\Fluid\View\StandaloneView; |
||||
25 | use TYPO3\CMS\Info\Controller\InfoModuleController; |
||||
26 | |||||
27 | final class LogRequestForm extends AbstractRequestForm implements RequestFormInterface |
||||
28 | { |
||||
29 | /** |
||||
30 | * @var StandaloneView |
||||
31 | */ |
||||
32 | private $view; |
||||
33 | |||||
34 | /** |
||||
35 | * @var JsonCompatibilityConverter |
||||
36 | */ |
||||
37 | private $jsonCompatibilityConverter; |
||||
38 | |||||
39 | /** |
||||
40 | * @var int |
||||
41 | */ |
||||
42 | private $pageId; |
||||
43 | |||||
44 | /** |
||||
45 | * @var bool |
||||
46 | */ |
||||
47 | private $CSVExport = false; |
||||
48 | |||||
49 | /** |
||||
50 | * @var InfoModuleController |
||||
51 | */ |
||||
52 | private $infoModuleController; |
||||
53 | |||||
54 | /** |
||||
55 | * @var QueryBuilder |
||||
56 | */ |
||||
57 | private $queryBuilder; |
||||
58 | |||||
59 | /** |
||||
60 | * @var CsvWriterInterface |
||||
61 | */ |
||||
62 | private $csvWriter; |
||||
63 | |||||
64 | /** |
||||
65 | * @var QueueRepository |
||||
66 | */ |
||||
67 | private $queueRepository; |
||||
68 | |||||
69 | /** |
||||
70 | * @var array |
||||
71 | */ |
||||
72 | private $CSVaccu = []; |
||||
73 | |||||
74 | 1 | public function __construct(StandaloneView $view, InfoModuleController $infoModuleController, array $extensionSettings) |
|||
75 | { |
||||
76 | 1 | $objectManager = GeneralUtility::makeInstance(ObjectManager::class); |
|||
77 | 1 | $this->view = $view; |
|||
78 | 1 | $this->infoModuleController = $infoModuleController; |
|||
79 | 1 | $this->jsonCompatibilityConverter = new JsonCompatibilityConverter(); |
|||
80 | 1 | $this->queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(QueueRepository::TABLE_NAME); |
|||
81 | 1 | $this->csvWriter = new CrawlerCsvWriter(); |
|||
82 | 1 | $this->extensionSettings = $extensionSettings; |
|||
83 | 1 | $this->queueRepository = $objectManager->get(QueueRepository::class); |
|||
84 | 1 | } |
|||
85 | |||||
86 | public function render($id, string $elementName, array $menuItems): string |
||||
87 | { |
||||
88 | $quiPart = GeneralUtility::_GP('qid_details') ? '&qid_details=' . (int) GeneralUtility::_GP('qid_details') : ''; |
||||
89 | $setId = (int) GeneralUtility::_GP('setID'); |
||||
90 | $this->pageId = $id; |
||||
91 | |||||
92 | return $this->getDepthDropDownHtml($id, $elementName, $menuItems) |
||||
93 | . $this->showLogAction($setId, $quiPart); |
||||
94 | } |
||||
95 | |||||
96 | private function getDepthDropDownHtml($id, string $currentValue, array $menuItems): string |
||||
97 | { |
||||
98 | return BackendUtility::getFuncMenu( |
||||
99 | $id, |
||||
100 | 'SET[depth]', |
||||
101 | $currentValue, |
||||
102 | $menuItems |
||||
103 | ); |
||||
104 | } |
||||
105 | |||||
106 | /******************************* |
||||
107 | * |
||||
108 | * Shows log of indexed URLs |
||||
109 | * |
||||
110 | ******************************/ |
||||
111 | |||||
112 | /** |
||||
113 | * @throws \TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException |
||||
114 | * @throws \TYPO3\CMS\Extbase\Object\Exception |
||||
115 | */ |
||||
116 | private function showLogAction(int $setId, string $quiPath): string |
||||
117 | { |
||||
118 | $this->view->setTemplate('ShowLog'); |
||||
119 | if (empty($this->pageId)) { |
||||
120 | $this->isErrorDetected = true; |
||||
121 | MessageUtility::addErrorMessage($this->getLanguageService()->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xlf:labels.noPageSelected')); |
||||
122 | } else { |
||||
123 | $this->findCrawler()->setID = GeneralUtility::md5int(microtime()); |
||||
124 | |||||
125 | $csvExport = GeneralUtility::_POST('_csv'); |
||||
126 | $this->CSVExport = isset($csvExport); |
||||
127 | |||||
128 | // Read URL: |
||||
129 | if (GeneralUtility::_GP('qid_read')) { |
||||
130 | $this->findCrawler()->readUrl((int) GeneralUtility::_GP('qid_read'), true); |
||||
131 | } |
||||
132 | |||||
133 | // Look for set ID sent - if it is, we will display contents of that set: |
||||
134 | $showSetId = (int) GeneralUtility::_GP('setID'); |
||||
135 | |||||
136 | $queueId = GeneralUtility::_GP('qid_details'); |
||||
137 | $this->view->assign('queueId', $queueId); |
||||
138 | $this->view->assign('setId', $showSetId); |
||||
139 | // Show details: |
||||
140 | if ($queueId) { |
||||
141 | // Get entry record: |
||||
142 | $q_entry = $this->queryBuilder |
||||
0 ignored issues
–
show
|
|||||
143 | ->from(QueueRepository::TABLE_NAME) |
||||
144 | ->select('*') |
||||
145 | ->where( |
||||
146 | $this->queryBuilder->expr()->eq('qid', $this->queryBuilder->createNamedParameter($queueId)) |
||||
147 | ) |
||||
148 | ->execute() |
||||
149 | ->fetch(); |
||||
150 | |||||
151 | // Explode values |
||||
152 | $q_entry['parameters'] = $this->jsonCompatibilityConverter->convert($q_entry['parameters']); |
||||
153 | $q_entry['result_data'] = $this->jsonCompatibilityConverter->convert($q_entry['result_data']); |
||||
154 | $resStatus = ResultHandler::getResStatus($q_entry['result_data']); |
||||
155 | if (is_array($q_entry['result_data'])) { |
||||
156 | $q_entry['result_data']['content'] = $this->jsonCompatibilityConverter->convert($q_entry['result_data']['content']); |
||||
157 | if (! $this->infoModuleController->MOD_SETTINGS['log_resultLog']) { |
||||
158 | if (is_array($q_entry['result_data']['content'])) { |
||||
159 | unset($q_entry['result_data']['content']['log']); |
||||
160 | } |
||||
161 | } |
||||
162 | } |
||||
163 | |||||
164 | $this->view->assign('queueStatus', $resStatus); |
||||
165 | $this->view->assign('queueDetails', DebugUtility::viewArray($q_entry)); |
||||
166 | } else { |
||||
167 | // Show list |
||||
168 | // Drawing tree: |
||||
169 | $tree = GeneralUtility::makeInstance(PageTreeView::class); |
||||
170 | $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1); |
||||
171 | $tree->init('AND ' . $perms_clause); |
||||
172 | |||||
173 | // Set root row: |
||||
174 | $pageinfo = BackendUtility::readPageAccess( |
||||
175 | $this->pageId, |
||||
176 | $perms_clause |
||||
177 | ); |
||||
178 | $HTML = $this->getIconFactory()->getIconForRecord('pages', $pageinfo, Icon::SIZE_SMALL)->render(); |
||||
0 ignored issues
–
show
It seems like
$pageinfo can also be of type false ; however, parameter $row of TYPO3\CMS\Core\Imaging\I...ory::getIconForRecord() does only seem to accept array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
179 | $tree->tree[] = [ |
||||
180 | 'row' => $pageinfo, |
||||
181 | 'HTML' => $HTML, |
||||
182 | ]; |
||||
183 | |||||
184 | // Get branch beneath: |
||||
185 | if ($this->infoModuleController->MOD_SETTINGS['depth']) { |
||||
186 | $tree->getTree($this->pageId, $this->infoModuleController->MOD_SETTINGS['depth']); |
||||
187 | } |
||||
188 | |||||
189 | // If Flush button is pressed, flush tables instead of selecting entries: |
||||
190 | if (GeneralUtility::_POST('_flush')) { |
||||
191 | $doFlush = true; |
||||
192 | } elseif (GeneralUtility::_POST('_flush_all')) { |
||||
193 | $doFlush = true; |
||||
194 | $this->infoModuleController->MOD_SETTINGS['log_display'] = 'all'; |
||||
195 | } else { |
||||
196 | $doFlush = false; |
||||
197 | } |
||||
198 | $itemsPerPage = (int) $this->infoModuleController->MOD_SETTINGS['itemsPerPage']; |
||||
199 | $queueFilter = new QueueFilter($this->infoModuleController->MOD_SETTINGS['log_display']); |
||||
200 | |||||
201 | if ($doFlush) { |
||||
202 | $this->queueRepository->flushQueue($queueFilter); |
||||
203 | } |
||||
204 | |||||
205 | // Traverse page tree: |
||||
206 | $count = 0; |
||||
207 | $logEntriesPerPage = []; |
||||
208 | foreach ($tree->tree as $data) { |
||||
209 | $logEntriesOfPage = $this->queueRepository->getQueueEntriesForPageId( |
||||
210 | (int) $data['row']['uid'], |
||||
211 | $itemsPerPage, |
||||
212 | $queueFilter |
||||
213 | ); |
||||
214 | |||||
215 | $logEntriesPerPage[] = $this->drawLog_addRows( |
||||
216 | $logEntriesOfPage, |
||||
217 | $data['HTML'] . BackendUtility::getRecordTitle('pages', $data['row'], true) |
||||
218 | ); |
||||
219 | if (++$count === 1000) { |
||||
220 | break; |
||||
221 | } |
||||
222 | } |
||||
223 | |||||
224 | $this->view->assign('logEntriesPerPage', $logEntriesPerPage); |
||||
225 | } |
||||
226 | |||||
227 | if ($this->CSVExport) { |
||||
228 | $this->outputCsvFile(); |
||||
229 | } |
||||
230 | } |
||||
231 | $this->view->assign('showResultLog', (bool) $this->infoModuleController->MOD_SETTINGS['log_resultLog']); |
||||
232 | $this->view->assign('showFeVars', (bool) $this->infoModuleController->MOD_SETTINGS['log_feVars']); |
||||
233 | $this->view->assign('displayActions', 1); |
||||
234 | $this->view->assign('displayLogFilterHtml', $this->getDisplayLogFilterHtml($setId)); |
||||
235 | $this->view->assign('itemPerPageHtml', $this->getItemsPerPageDropDownHtml()); |
||||
236 | $this->view->assign('showResultLogHtml', $this->getShowResultLogCheckBoxHtml($setId, $quiPath)); |
||||
237 | $this->view->assign('showFeVarsHtml', $this->getShowFeVarsCheckBoxHtml($setId, $quiPath)); |
||||
238 | return $this->view->render(); |
||||
239 | } |
||||
240 | |||||
241 | /** |
||||
242 | * Outputs the CSV file and sets the correct headers |
||||
243 | */ |
||||
244 | private function outputCsvFile(): void |
||||
245 | { |
||||
246 | if (! count($this->CSVaccu)) { |
||||
247 | MessageUtility::addWarningMessage($this->getLanguageService()->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xlf:message.canNotExportEmptyQueueToCsvText')); |
||||
248 | return; |
||||
249 | } |
||||
250 | |||||
251 | $csvString = $this->csvWriter->arrayToCsv($this->CSVaccu); |
||||
252 | |||||
253 | header('Content-Type: application/octet-stream'); |
||||
254 | header('Content-Disposition: attachment; filename=CrawlerLog.csv'); |
||||
255 | echo $csvString; |
||||
256 | |||||
257 | exit; |
||||
258 | } |
||||
259 | |||||
260 | private function getIconFactory(): IconFactory |
||||
261 | { |
||||
262 | return GeneralUtility::makeInstance(IconFactory::class); |
||||
263 | } |
||||
264 | |||||
265 | private function getDisplayLogFilterHtml(int $setId): string |
||||
266 | { |
||||
267 | return $this->getLanguageService()->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xlf:labels.display') . ': ' . BackendUtility::getFuncMenu( |
||||
268 | $this->pageId, |
||||
269 | 'SET[log_display]', |
||||
270 | $this->infoModuleController->MOD_SETTINGS['log_display'], |
||||
271 | $this->infoModuleController->MOD_MENU['log_display'], |
||||
272 | 'index.php', |
||||
273 | '&setID=' . $setId |
||||
274 | ); |
||||
275 | } |
||||
276 | |||||
277 | private function getItemsPerPageDropDownHtml(): string |
||||
278 | { |
||||
279 | return $this->getLanguageService()->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xlf:labels.itemsPerPage') . ': ' . |
||||
280 | BackendUtility::getFuncMenu( |
||||
281 | $this->pageId, |
||||
282 | 'SET[itemsPerPage]', |
||||
283 | $this->infoModuleController->MOD_SETTINGS['itemsPerPage'], |
||||
284 | $this->infoModuleController->MOD_MENU['itemsPerPage'] |
||||
285 | ); |
||||
286 | } |
||||
287 | |||||
288 | private function getShowResultLogCheckBoxHtml(int $setId, string $quiPart): string |
||||
289 | { |
||||
290 | return BackendUtility::getFuncCheck( |
||||
291 | $this->pageId, |
||||
292 | 'SET[log_resultLog]', |
||||
293 | $this->infoModuleController->MOD_SETTINGS['log_resultLog'], |
||||
294 | 'index.php', |
||||
295 | '&setID=' . $setId . $quiPart |
||||
296 | ) . ' ' . $this->getLanguageService()->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xlf:labels.showresultlog'); |
||||
297 | } |
||||
298 | |||||
299 | private function getShowFeVarsCheckBoxHtml(int $setId, string $quiPart): string |
||||
300 | { |
||||
301 | return BackendUtility::getFuncCheck( |
||||
302 | $this->pageId, |
||||
303 | 'SET[log_feVars]', |
||||
304 | $this->infoModuleController->MOD_SETTINGS['log_feVars'], |
||||
305 | 'index.php', |
||||
306 | '&setID=' . $setId . $quiPart |
||||
307 | ) . ' ' . $this->getLanguageService()->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xlf:labels.showfevars'); |
||||
308 | } |
||||
309 | |||||
310 | /** |
||||
311 | * Create the rows for display of the page tree |
||||
312 | * For each page a number of rows are shown displaying GET variable configuration |
||||
313 | * |
||||
314 | * @param array $logEntriesOfPage Log items of one page |
||||
315 | * @param string $titleString Title string |
||||
316 | * |
||||
317 | * @throws \TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException |
||||
318 | * |
||||
319 | * @psalm-return non-empty-list<array{titleRowSpan: positive-int, colSpan: int, title: string, noEntries?: string, trClass?: string, qid?: array{link: \TYPO3\CMS\Core\Http\Uri, link-text: string}, refresh?: array{link: \TYPO3\CMS\Core\Http\Uri, link-text: Icon, warning: Icon|string}, columns?: array{url: mixed|string, scheduled: string, exec_time: string, result_log: string, result_status: string, feUserGroupList: string, procInstructions: string, set_id: string, tsfe_id: string, tsfe_gr_list: string}}> |
||||
320 | */ |
||||
321 | private function drawLog_addRows(array $logEntriesOfPage, string $titleString): array |
||||
322 | { |
||||
323 | $resultArray = []; |
||||
324 | $contentArray = []; |
||||
325 | |||||
326 | $contentArray['titleRowSpan'] = 1; |
||||
327 | $contentArray['colSpan'] = 9 |
||||
328 | + ($this->infoModuleController->MOD_SETTINGS['log_resultLog'] ? -1 : 0) |
||||
329 | + ($this->infoModuleController->MOD_SETTINGS['log_feVars'] ? 3 : 0); |
||||
330 | |||||
331 | if (! empty($logEntriesOfPage)) { |
||||
332 | $setId = (int) GeneralUtility::_GP('setID'); |
||||
333 | $refreshIcon = $this->getIconFactory()->getIcon('actions-system-refresh', Icon::SIZE_SMALL); |
||||
334 | // Traverse parameter combinations: |
||||
335 | $firstIteration = true; |
||||
336 | foreach ($logEntriesOfPage as $vv) { |
||||
337 | // Title column: |
||||
338 | if ($firstIteration) { |
||||
339 | $contentArray['titleRowSpan'] = count($logEntriesOfPage); |
||||
340 | $contentArray['title'] = $titleString; |
||||
341 | } else { |
||||
342 | $contentArray['title'] = ''; |
||||
343 | $contentArray['titleRowSpan'] = 1; |
||||
344 | } |
||||
345 | |||||
346 | $firstIteration = false; |
||||
347 | $execTime = $vv['exec_time'] ? BackendUtility::datetime($vv['exec_time']) : '-'; |
||||
348 | |||||
349 | // Result: |
||||
350 | $resLog = ResultHandler::getResultLog($vv); |
||||
351 | |||||
352 | $resultData = $vv['result_data'] ? $this->jsonCompatibilityConverter->convert($vv['result_data']) : []; |
||||
353 | $resStatus = ResultHandler::getResStatus($resultData); |
||||
354 | |||||
355 | // Compile row: |
||||
356 | $parameters = $this->jsonCompatibilityConverter->convert($vv['parameters']); |
||||
357 | |||||
358 | // Put data into array: |
||||
359 | $rowData = []; |
||||
360 | if ($this->infoModuleController->MOD_SETTINGS['log_resultLog']) { |
||||
361 | $rowData['result_log'] = $resLog; |
||||
362 | } else { |
||||
363 | $rowData['scheduled'] = ($vv['scheduled'] > 0) ? BackendUtility::datetime($vv['scheduled']) : 0; |
||||
364 | $rowData['exec_time'] = $execTime; |
||||
365 | } |
||||
366 | $rowData['result_status'] = GeneralUtility::fixed_lgd_cs($resStatus, 50); |
||||
367 | $url = htmlspecialchars($parameters['url'] ?? $parameters['alturl'], ENT_QUOTES | ENT_HTML5); |
||||
368 | $rowData['url'] = '<a href="' . $url . '" target="_newWIndow">' . $url . '</a>'; |
||||
369 | $rowData['feUserGroupList'] = $parameters['feUserGroupList'] ?: ''; |
||||
370 | $rowData['procInstructions'] = is_array($parameters['procInstructions']) ? implode('; ', $parameters['procInstructions']) : ''; |
||||
371 | $rowData['set_id'] = (string) $vv['set_id']; |
||||
372 | |||||
373 | if ($this->infoModuleController->MOD_SETTINGS['log_feVars']) { |
||||
374 | $resFeVars = ResultHandler::getResFeVars($resultData ?: []); |
||||
375 | $rowData['tsfe_id'] = $resFeVars['id'] ?: ''; |
||||
376 | $rowData['tsfe_gr_list'] = $resFeVars['gr_list'] ?: ''; |
||||
377 | } |
||||
378 | |||||
379 | $trClass = ''; |
||||
380 | $warningIcon = ''; |
||||
381 | if (str_contains($resStatus, 'Error:')) { |
||||
382 | $trClass = 'bg-danger'; |
||||
383 | $warningIcon = $this->getIconFactory()->getIcon('actions-ban', Icon::SIZE_SMALL); |
||||
384 | } |
||||
385 | |||||
386 | // Put rows together: |
||||
387 | $contentArray['trClass'] = $trClass; |
||||
388 | $contentArray['qid'] = [ |
||||
389 | 'link' => UrlBuilder::getInfoModuleUrl(['qid_details' => $vv['qid'], 'setID' => $setId]), |
||||
390 | 'link-text' => htmlspecialchars((string) $vv['qid'], ENT_QUOTES | ENT_HTML5), |
||||
391 | ]; |
||||
392 | $contentArray['refresh'] = [ |
||||
393 | 'link' => UrlBuilder::getInfoModuleUrl(['qid_read' => $vv['qid'], 'setID' => $setId]), |
||||
394 | 'link-text' => $refreshIcon, |
||||
395 | 'warning' => $warningIcon, |
||||
396 | ]; |
||||
397 | |||||
398 | foreach ($rowData as $fKey => $value) { |
||||
399 | if ($fKey === 'url') { |
||||
400 | $contentArray['columns'][$fKey] = $value; |
||||
401 | } else { |
||||
402 | $contentArray['columns'][$fKey] = nl2br(htmlspecialchars((string) $value, ENT_QUOTES | ENT_HTML5)); |
||||
403 | } |
||||
404 | } |
||||
405 | |||||
406 | $resultArray[] = $contentArray; |
||||
407 | |||||
408 | if ($this->CSVExport) { |
||||
409 | // Only for CSV (adding qid and scheduled/exec_time if needed): |
||||
410 | $csvExport['scheduled'] = BackendUtility::datetime($vv['scheduled']); |
||||
411 | $csvExport['exec_time'] = $vv['exec_time'] ? BackendUtility::datetime($vv['exec_time']) : '-'; |
||||
412 | $csvExport['result_status'] = $contentArray['columns']['result_status']; |
||||
413 | $csvExport['url'] = $contentArray['columns']['url']; |
||||
414 | $csvExport['feUserGroupList'] = $contentArray['columns']['feUserGroupList']; |
||||
415 | $csvExport['procInstructions'] = $contentArray['columns']['procInstructions']; |
||||
416 | $csvExport['set_id'] = $contentArray['columns']['set_id']; |
||||
417 | $csvExport['result_log'] = str_replace(chr(10), '// ', $resLog); |
||||
418 | $csvExport['qid'] = $vv['qid']; |
||||
419 | $this->CSVaccu[] = $csvExport; |
||||
420 | } |
||||
421 | } |
||||
422 | } else { |
||||
423 | $contentArray['title'] = $titleString; |
||||
424 | $contentArray['noEntries'] = $this->getLanguageService()->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xlf:labels.noentries'); |
||||
425 | |||||
426 | $resultArray[] = $contentArray; |
||||
427 | } |
||||
428 | |||||
429 | return $resultArray; |
||||
430 | } |
||||
431 | } |
||||
432 |
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.