• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tomasnorre / crawler / 4092880773

pending completion
4092880773

push

github

GitHub
[TASK] Cleanup BackendModule Controllers (#1005)

246 of 246 new or added lines in 9 files covered. (100.0%)

1778 of 2545 relevant lines covered (69.86%)

3.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/Classes/Controller/Backend/BackendModuleCrawlerLogController.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace AOE\Crawler\Controller\Backend;
6

7
/*
8
 * (c) 2022-     Tomas Norre Mikkelsen <tomasnorre@gmail.com>
9
 *
10
 * This file is part of the TYPO3 Crawler Extension.
11
 *
12
 * It is free software; you can redistribute it and/or modify it under
13
 * the terms of the GNU General Public License, either version 2
14
 * of the License, or any later version.
15
 *
16
 * For the full copyright and license information, please read the
17
 * LICENSE.txt file that was distributed with this source code.
18
 *
19
 * The TYPO3 project - inspiring people to share!
20
 */
21

22
use AOE\Crawler\Controller\Backend\Helper\ResultHandler;
23
use AOE\Crawler\Controller\CrawlerController;
24
use AOE\Crawler\Converter\JsonCompatibilityConverter;
25
use AOE\Crawler\Domain\Repository\QueueRepository;
26
use AOE\Crawler\Service\BackendModuleHtmlElementService;
27
use AOE\Crawler\Service\BackendModuleLogService;
28
use AOE\Crawler\Utility\MessageUtility;
29
use AOE\Crawler\Value\QueueFilter;
30
use AOE\Crawler\Writer\FileWriter\CsvWriter\CsvWriterInterface;
31
use Psr\Http\Message\ResponseInterface;
32
use Psr\Http\Message\ServerRequestInterface;
33
use Symfony\Contracts\Service\Attribute\Required;
34
use TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException;
35
use TYPO3\CMS\Backend\Template\ModuleTemplate;
36
use TYPO3\CMS\Backend\Tree\View\PageTreeView;
37
use TYPO3\CMS\Backend\Utility\BackendUtility;
38
use TYPO3\CMS\Core\Database\ConnectionPool;
39
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
40
use TYPO3\CMS\Core\Imaging\Icon;
41
use TYPO3\CMS\Core\Imaging\IconFactory;
42
use TYPO3\CMS\Core\Utility\DebugUtility;
43
use TYPO3\CMS\Core\Utility\GeneralUtility;
44

45
/**
46
 * @internal since v12.0.0
47
 */
48
final class BackendModuleCrawlerLogController extends AbstractBackendModuleController implements BackendModuleControllerInterface
49
{
50
    public const BACKEND_MODULE = 'web_site_crawler_log';
51

52
    private QueryBuilder $queryBuilder;
53
    private bool $CSVExport = false;
54
    private readonly array $backendModuleMenu;
55
    private int $setId;
56
    private string $quiPath;
57
    private string $logDisplay;
58
    private int $itemsPerPage;
59
    private string $showResultLog;
60
    private string $showFeVars;
61
    private int $showSetId;
62
    private string $logDepth;
63
    /**
64
     * @var mixed|string|null
65
     */
66
    private mixed $queueId;
67

68
    public function __construct(
69
        private readonly QueueRepository $queueRepository,
70
        private readonly CsvWriterInterface $csvWriter,
71
        private readonly JsonCompatibilityConverter $jsonCompatibilityConverter,
72
        private readonly IconFactory $iconFactory,
73
        private readonly CrawlerController $crawlerController,
74
        private readonly BackendModuleLogService $backendModuleLogService,
75
        private readonly BackendModuleHtmlElementService $backendModuleHtmlElementService,
76
    ) {
77
        $this->backendModuleMenu = $this->getModuleMenu();
×
78
    }
79

80
    #[Required]
81
    public function setQueryBuilder(): void
82
    {
83
        $this->queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
×
84
            QueueRepository::TABLE_NAME
×
85
        );
×
86
    }
87

88
    public function handleRequest(ServerRequestInterface $request): ResponseInterface
89
    {
90
        $this->setPropertiesBasedOnPostVars($request);
×
91
        $this->moduleTemplate = $this->setupView($request, $this->pageUid);
×
92
        $this->moduleTemplate = $this->moduleTemplate->makeDocHeaderModuleMenu(['id' => $this->pageUid]);
×
93

94
        if (!$this->pageUid) {
×
95
            $this->isErrorDetected = true;
×
96
            $this->moduleTemplate->assign('noPageSelected', true);
×
97
            return $this->moduleTemplate->renderResponse('Backend/ShowLog');
×
98
        }
99
        $this->moduleTemplate = $this->assignValues();
×
100
        return $this->moduleTemplate->renderResponse('Backend/ShowLog');
×
101
    }
102

103
    private function getQueueEntry(mixed $queueId): array
104
    {
105
        $q_entry = $this->queryBuilder
×
106
            ->from(QueueRepository::TABLE_NAME)
×
107
            ->select('*')->where(
×
108
                $this->queryBuilder->expr()->eq('qid', $this->queryBuilder->createNamedParameter($queueId))
×
109
            )->executeQuery()
×
110
            ->fetchAssociative();
×
111

112
        // Explode values
113
        $q_entry['parameters'] = $this->jsonCompatibilityConverter->convert($q_entry['parameters']);
×
114
        $q_entry['result_data'] = $this->jsonCompatibilityConverter->convert($q_entry['result_data']);
×
115
        $resStatus = ResultHandler::getResStatus($q_entry['result_data']);
×
116
        if (is_array($q_entry['result_data'])) {
×
117
            $q_entry['result_data']['content'] = $this->jsonCompatibilityConverter->convert(
×
118
                $q_entry['result_data']['content']
×
119
            );
×
120
            if (!$this->showResultLog) {
×
121
                if (is_array($q_entry['result_data']['content'])) {
×
122
                    unset($q_entry['result_data']['content']['log']);
×
123
                }
124
            }
125
        }
126
        return [$q_entry, $resStatus];
×
127
    }
128

129
    /**
130
     * @throws RouteNotFoundException
131
     */
132
    private function assignValues(): ModuleTemplate
133
    {
134
        // Look for set ID sent - if it is, we will display contents of that set:
135
        $this->showSetId = (int) GeneralUtility::_GP('setID');
×
136
        $this->CSVExport = (bool) GeneralUtility::_GP('_csv');
×
137
        $logEntriesPerPage = [];
×
138
        $csvData = [];
×
139

140
        if (GeneralUtility::_GP('qid_read')) {
×
141
            $this->crawlerController->readUrl((int) GeneralUtility::_GP('qid_read'), true);
×
142
        }
143

144
        if ($this->queueId) {
×
145
            // Get entry record:
146
            [$q_entry, $resStatus] = $this->getQueueEntry($this->queueId);
×
147
            $this->moduleTemplate->assignMultiple([
×
148
                'queueStatus' => $resStatus,
×
149
                'queueDetails' => DebugUtility::viewArray($q_entry),
×
150
            ]);
×
151
        } else {
152
            // Show list
153
            // Drawing tree:
154
            $tree = GeneralUtility::makeInstance(PageTreeView::class);
×
155
            $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
×
156
            $tree->init('AND ' . $perms_clause);
×
157

158
            // Set root row:
159
            $pageinfo = BackendUtility::readPageAccess($this->pageUid, $perms_clause);
×
160

161
            if (is_array($pageinfo)) {
×
162
                $HTML = $this->iconFactory->getIconForRecord('pages', $pageinfo, Icon::SIZE_SMALL)->render();
×
163
                $tree->tree[] = [
×
164
                    'row' => $pageinfo,
×
165
                    'HTML' => $HTML,
×
166
                ];
×
167
            }
168

169
            // Get branch beneath:
170
            if ($this->logDepth) {
×
171
                $tree->getTree($this->pageUid, (int) $this->logDepth);
×
172
            }
173

174
            // If Flush button is pressed, flush tables instead of selecting entries:
175
            if (GeneralUtility::_POST('_flush')) {
×
176
                $doFlush = true;
×
177
            } elseif (GeneralUtility::_POST('_flush_all')) {
×
178
                $doFlush = true;
×
179
                $this->logDisplay = 'all';
×
180
            } else {
181
                $doFlush = false;
×
182
            }
183

184
            $queueFilter = new QueueFilter($this->logDisplay);
×
185

186
            if ($doFlush) {
×
187
                $this->queueRepository->flushQueue($queueFilter);
×
188
            }
189

190
            // Traverse page tree:
191
            $count = 0;
×
192

193
            foreach ($tree->tree as $data) {
×
194
                $logEntriesOfPage = $this->queueRepository->getQueueEntriesForPageId(
×
195
                    (int) $data['row']['uid'],
×
196
                    $this->itemsPerPage,
×
197
                    $queueFilter
×
198
                );
×
199

200
                [$logEntriesPerPage[], $csvData] = $this->backendModuleLogService->addRows(
×
201
                    $logEntriesOfPage,
×
202
                    (int) GeneralUtility::_GP('setID'),
×
203
                    $data['HTML'] . BackendUtility::getRecordTitle('pages', $data['row'], true),
×
204
                    $this->showResultLog,
×
205
                    $this->showFeVars,
×
206
                    $this->CSVExport
×
207
                );
×
208
                if (++$count === 1000) {
×
209
                    break;
×
210
                }
211
            }
212

213
            $this->moduleTemplate->assign('logEntriesPerPage', $logEntriesPerPage);
×
214
        }
215

216
        if ($this->CSVExport) {
×
217
            $this->outputCsvFile($csvData);
×
218
        }
219

220
        $queryParams = [
×
221
            'setID' => $this->setId,
×
222
            'displayLog' => $this->logDisplay,
×
223
            'itemsPerPage' => $this->itemsPerPage,
×
224
            'ShowFeVars' => $this->showFeVars,
×
225
            'ShowResultLog' => $this->showResultLog,
×
226
            'logDepth' => $this->logDepth,
×
227
        ];
×
228

229
        return $this->moduleTemplate->assignMultiple([
×
230
            'actionUrl' => '',
×
231
            'queueId' => $this->queueId,
×
232
            'setId' => $this->showSetId,
×
233
            'noPageSelected' => false,
×
234
            'logEntriesPerPage' => $logEntriesPerPage,
×
235
            'showResultLog' => $this->showResultLog,
×
236
            'showFeVars' => $this->showFeVars,
×
237
            'displayActions' => 1,
×
238
            'displayLogFilterHtml' => $this->backendModuleHtmlElementService->getFormElementSelect(
×
239
                'displayLog',
×
240
                $this->pageUid,
×
241
                $this->logDisplay,
×
242
                $this->backendModuleMenu,
×
243
                $queryParams
×
244
            ),
×
245
            'itemPerPageHtml' => $this->backendModuleHtmlElementService->getFormElementSelect(
×
246
                'itemsPerPage',
×
247
                $this->pageUid,
×
248
                $this->itemsPerPage,
×
249
                $this->backendModuleMenu,
×
250
                $queryParams
×
251
            ),
×
252
            'showResultLogHtml' => $this->backendModuleHtmlElementService->getFormElementCheckbox(
×
253
                'ShowResultLog', $this->pageUid, $this->showResultLog, $queryParams, $this->quiPath
×
254
            ),
×
255
            'showFeVarsHtml' => $this->backendModuleHtmlElementService->getFormElementCheckbox(
×
256
                'ShowFeVars',
×
257
                $this->pageUid,
×
258
                $this->showFeVars,
×
259
                $queryParams,
×
260
                $this->quiPath
×
261
            ),
×
262
            'depthDropDownHtml' => $this->backendModuleHtmlElementService->getFormElementSelect(
×
263
                'logDepth',
×
264
                $this->pageUid,
×
265
                $this->logDepth,
×
266
                $this->backendModuleMenu,
×
267
                $queryParams
×
268
            ),
×
269
        ]);
×
270
    }
271

272
    private function setPropertiesBasedOnPostVars(ServerRequestInterface $request): void
273
    {
274
        $this->pageUid = (int) ($request->getQueryParams()['id'] ?? -1);
×
275
        $this->setId = (int) GeneralUtility::_GP('setID');
×
276
        $this->quiPath = GeneralUtility::_GP('qid_details') ? '&qid_details=' . (int) GeneralUtility::_GP('qid_details') : '';
×
277
        $this->queueId = GeneralUtility::_GP('qid_details');
×
278
        $this->logDisplay = GeneralUtility::_GP('displayLog') ?? 'all';
×
279
        $this->itemsPerPage = (int) (GeneralUtility::_GP('itemsPerPage') ?? 10);
×
280
        $this->showResultLog = (string) (GeneralUtility::_GP('ShowResultLog') ?? 0);
×
281
        $this->showFeVars = (string) (GeneralUtility::_GP('ShowFeVars') ?? 0);
×
282
        $this->logDepth = (string) (GeneralUtility::_GP('logDepth') ?? 0);
×
283
    }
284

285
    /**
286
     * Outputs the CSV file and sets the correct headers
287
     */
288
    private function outputCsvFile(array $csvData): void
289
    {
290
        if (!count($csvData)) {
×
291
            MessageUtility::addWarningMessage(
×
292
                $this->getLanguageService()->sL(
×
293
                    'LLL:EXT:crawler/Resources/Private/Language/locallang.xlf:message.canNotExportEmptyQueueToCsvText'
×
294
                )
×
295
            );
×
296
            return;
×
297
        }
298

299
        $csvString = $this->csvWriter->arrayToCsv($csvData);
×
300

301
        header('Content-Type: application/octet-stream');
×
302
        header('Content-Disposition: attachment; filename=CrawlerLog.csv');
×
303
        echo $csvString;
×
304

305
        exit;
×
306
    }
307
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc