Issues (138)

Classes/Backend/RequestForm/StartRequestForm.php (4 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace AOE\Crawler\Backend\RequestForm;
6
7
/*
8
 * (c) 2020 AOE GmbH <[email protected]>
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\CrawlerController;
23
use AOE\Crawler\Domain\Model\Reason;
24
use AOE\Crawler\Utility\MessageUtility;
25
use AOE\Crawler\Utility\SignalSlotUtility;
26
use TYPO3\CMS\Core\Utility\GeneralUtility;
27
use TYPO3\CMS\Fluid\View\StandaloneView;
28
use TYPO3\CMS\Info\Controller\InfoModuleController;
29
30
final class StartRequestForm extends AbstractRequestForm implements RequestFormInterface
31
{
32
    /**
33
     * @var StandaloneView
34
     */
35
    private $view;
36
37
    /**
38
     * @var InfoModuleController
39
     */
40
    private $infoModuleController;
41
42
    /**
43
     * @var int
44
     */
45
    private $reqMinute = 1000;
46
47
    /**
48
     * @var array holds the selection of configuration from the configuration selector box
49
     */
50
    private $incomingConfigurationSelection = [];
51
52 2
    public function __construct(StandaloneView $view, InfoModuleController $infoModuleController, array $extensionSettings)
53
    {
54 2
        $this->view = $view;
55 2
        $this->infoModuleController = $infoModuleController;
56 2
        $this->extensionSettings = $extensionSettings;
57 2
    }
58
59 1
    public function render($id, string $elementName, array $menuItems): string
60
    {
61 1
        return $this->showCrawlerInformationAction($id);
62
    }
63
64
    /*******************************
65
     *
66
     * Generate URLs for crawling:
67
     *
68
     ******************************/
69
70
    /**
71
     * Show a list of URLs to be crawled for each page
72
     */
73 1
    private function showCrawlerInformationAction(int $pageId): string
74
    {
75 1
        if (empty($pageId)) {
76
            $this->isErrorDetected = true;
77
            MessageUtility::addErrorMessage($this->getLanguageService()->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xlf:labels.noPageSelected'));
78
            return '';
79
        }
80
81 1
        $this->view->setTemplate('ShowCrawlerInformation');
82
83 1
        $crawlParameter = GeneralUtility::_GP('_crawl');
84 1
        $downloadParameter = GeneralUtility::_GP('_download');
85
86 1
        $submitCrawlUrls = isset($crawlParameter);
87 1
        $downloadCrawlUrls = isset($downloadParameter);
88 1
        $this->makeCrawlerProcessableChecks($this->extensionSettings);
89
90 1
        $scheduledTime = $this->getScheduledTime((string) GeneralUtility::_GP('tstamp'));
91
92 1
        $this->incomingConfigurationSelection = GeneralUtility::_GP('configurationSelection');
93 1
        $this->incomingConfigurationSelection = is_array($this->incomingConfigurationSelection) ? $this->incomingConfigurationSelection : [];
94
95 1
        $this->crawlerController = GeneralUtility::makeInstance(CrawlerController::class);
96 1
        $this->crawlerController->setID = GeneralUtility::md5int(microtime());
97
98 1
        $code = '';
99 1
        $noConfigurationSelected = empty($this->incomingConfigurationSelection)
100 1
            || (count($this->incomingConfigurationSelection) === 1 && empty($this->incomingConfigurationSelection[0]));
101 1
        if ($noConfigurationSelected) {
102 1
            MessageUtility::addWarningMessage($this->getLanguageService()->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xlf:labels.noConfigSelected'));
103
        } else {
104
            if ($submitCrawlUrls) {
105
                $reason = new Reason();
106
                $reason->setReason(Reason::REASON_GUI_SUBMIT);
107
                $reason->setDetailText('The user ' . $GLOBALS['BE_USER']->user['username'] . ' added pages to the crawler queue manually');
108
109
                $signalPayload = ['reason' => $reason];
110
                SignalSlotUtility::emitSignal(
0 ignored issues
show
Deprecated Code introduced by
The function AOE\Crawler\Utility\Sign...otUtility::emitSignal() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

110
                /** @scrutinizer ignore-deprecated */ SignalSlotUtility::emitSignal(
Loading history...
111
                    self::class,
112
                    SignalSlotUtility::SIGNAL_INVOKE_QUEUE_CHANGE,
113
                    $signalPayload
114
                );
115
            }
116
117
            $code = $this->crawlerController->getPageTreeAndUrls(
118
                $pageId,
119
                $this->infoModuleController->MOD_SETTINGS['depth'],
120
                $scheduledTime,
121
                $this->reqMinute,
122
                $submitCrawlUrls,
123
                $downloadCrawlUrls,
124
                // Do not filter any processing instructions
125
                [],
126
                $this->incomingConfigurationSelection
127
            );
128
        }
129
130 1
        $downloadUrls = $this->crawlerController->downloadUrls;
131
132 1
        $duplicateTrack = $this->crawlerController->duplicateTrack;
133
134 1
        $this->view->assign('noConfigurationSelected', $noConfigurationSelected);
135 1
        $this->view->assign('submitCrawlUrls', $submitCrawlUrls);
136 1
        $this->view->assign('amountOfUrls', count($duplicateTrack));
137 1
        $this->view->assign('selectors', $this->generateConfigurationSelectors($pageId));
138 1
        $this->view->assign('code', $code);
139 1
        $this->view->assign('displayActions', 0);
140
141
        // Download Urls to crawl:
142 1
        if ($downloadCrawlUrls) {
143
            // Creating output header:
144
            header('Content-Type: application/octet-stream');
145
            header('Content-Disposition: attachment; filename=CrawlerUrls.txt');
146
147
            // Printing the content of the CSV lines:
148
            echo implode(chr(13) . chr(10), $downloadUrls);
149
            exit;
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return string. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
150
        }
151
152 1
        return $this->view->render();
153
    }
154
155
    /**
156
     * Generates the configuration selectors for compiling URLs:
157
     */
158 1
    private function generateConfigurationSelectors(int $pageId): array
159
    {
160 1
        $selectors = [];
161 1
        $selectors['depth'] = $this->selectorBox(
162
            [
163 1
                0 => $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_0'),
164 1
                1 => $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_1'),
165 1
                2 => $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_2'),
166 1
                3 => $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_3'),
167 1
                4 => $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_4'),
168 1
                99 => $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_infi'),
169
            ],
170 1
            'SET[depth]',
171 1
            $this->infoModuleController->MOD_SETTINGS['depth'],
172 1
            false
173
        );
174
175
        // Configurations
176 1
        $availableConfigurations = $this->crawlerController->getConfigurationsForBranch($pageId, (int) $this->infoModuleController->MOD_SETTINGS['depth'] ?: 0);
177 1
        $selectors['configurations'] = $this->selectorBox(
178 1
            empty($availableConfigurations) ? [] : array_combine($availableConfigurations, $availableConfigurations),
179 1
            'configurationSelection',
180 1
            $this->incomingConfigurationSelection,
181 1
            true
182
        );
183
184
        // Scheduled time:
185 1
        $selectors['scheduled'] = $this->selectorBox(
186
            [
187 1
                'now' => $this->getLanguageService()->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xlf:labels.time.now'),
188 1
                'midnight' => $this->getLanguageService()->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xlf:labels.time.midnight'),
189 1
                '04:00' => $this->getLanguageService()->sL('LLL:EXT:crawler/Resources/Private/Language/locallang.xlf:labels.time.4am'),
190
            ],
191 1
            'tstamp',
192 1
            GeneralUtility::_POST('tstamp'),
193 1
            false
194
        );
195
196 1
        return $selectors;
197
    }
198
199
    /**
200
     * Create selector box
201
     *
202
     * @param array $optArray Options key(value) => label pairs
203
     * @param string $name Selector box name
204
     * @param string|array $value Selector box value (array for multiple...)
205
     * @param boolean $multiple If set, will draw multiple box.
206
     *
207
     * @return string HTML select element
208
     */
209 1
    private function selectorBox($optArray, $name, $value, bool $multiple): string
210
    {
211 1
        if (! is_string($value) || ! is_array($value)) {
0 ignored issues
show
The condition is_array($value) is always false.
Loading history...
212 1
            $value = '';
213
        }
214
215 1
        $options = [];
216 1
        foreach ($optArray as $key => $val) {
217 1
            $selected = (! $multiple && ! strcmp($value, (string) $key)) || ($multiple && in_array($key, (array) $value, true));
218 1
            $options[] = '
219 1
                <option value="' . $key . '" ' . ($selected ? ' selected="selected"' : '') . '>' . htmlspecialchars($val, ENT_QUOTES | ENT_HTML5) . '</option>';
220
        }
221
222 1
        return '<select class="form-control" name="' . htmlspecialchars($name . ($multiple ? '[]' : ''), ENT_QUOTES | ENT_HTML5) . '"' . ($multiple ? ' multiple' : '') . '>' . implode('', $options) . '</select>';
223
    }
224
225
    /**
226
     * @return int
227
     */
228 1
    private function getScheduledTime(string $time)
229
    {
230 1
        switch ($time) {
231 1
            case 'midnight':
232
                $scheduledTime = mktime(0, 0, 0);
233
                break;
234 1
            case '04:00':
235
                $scheduledTime = mktime(0, 0, 0) + 4 * 3600;
236
                break;
237 1
            case 'now':
238
            default:
239 1
                $scheduledTime = time();
240 1
                break;
241
        }
242
243 1
        if (! $scheduledTime) {
244
            return time();
245
        }
246
247 1
        return $scheduledTime;
248
    }
249
}
250