Passed
Push — master ( 3e6704...db24af )
by Rafael
43:26 queued 10s
created

getAdditionalFields()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 30
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 16
c 1
b 0
f 0
dl 0
loc 30
rs 9.7333
cc 2
nc 2
nop 3
1
<?php
2
3
namespace ApacheSolrForTypo3\Solr\Task;
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
use ApacheSolrForTypo3\Solr\Backend\CoreSelectorField;
19
use ApacheSolrForTypo3\Solr\Backend\SiteSelectorField;
20
use ApacheSolrForTypo3\Solr\Domain\Site\Site;
21
use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository;
22
use ApacheSolrForTypo3\Solr\NoSolrConnectionFoundException;
23
use Exception;
24
use LogicException;
25
use TYPO3\CMS\Backend\Form\Exception as BackendFormException;
26
use TYPO3\CMS\Core\Localization\LanguageService;
27
use TYPO3\CMS\Core\Messaging\FlashMessage;
28
use TYPO3\CMS\Core\Page\PageRenderer;
29
use TYPO3\CMS\Core\Utility\GeneralUtility;
30
use TYPO3\CMS\Scheduler\AbstractAdditionalFieldProvider;
31
use TYPO3\CMS\Scheduler\Controller\SchedulerModuleController;
32
use TYPO3\CMS\Scheduler\Task\AbstractTask;
33
use TYPO3\CMS\Scheduler\Task\Enumeration\Action;
34
35
/**
36
 * Adds an additional field to specify the Solr server to initialize the index queue for
37
 *
38
 * @author Jens Jacobsen <[email protected]>
39
 */
40
class OptimizeIndexTaskAdditionalFieldProvider extends AbstractAdditionalFieldProvider
41
{
42
    /**
43
     * Default language file of the extension link validator
44
     *
45
     * @var string
46
     */
47
    protected $languageFile = 'LLL:EXT:solr/Resources/Private/Language/locallang.xlf';
48
49
    /**
50
     * Task information
51
     *
52
     * @var array
53
     */
54
    protected $taskInformation;
55
56
    /**
57
     * Scheduler task
58
     *
59
     * @var AbstractTask|null
60
     */
61
    protected $task = null;
62
63
    /**
64
     * Scheduler Module
65
     *
66
     * @var SchedulerModuleController
67
     */
68
    protected $schedulerModule;
69
70
    /**
71
     * Selected site
72
     *
73
     * @var Site
74
     */
75
    protected $site = null;
76
77
    /**
78
     * SiteRepository
79
     *
80
     * @var SiteRepository
81
     */
82
    protected $siteRepository;
83
84
    /**
85
     * @var PageRenderer
86
     */
87
    protected $pageRenderer = null;
88
89
    /**
90
     * ReIndexTaskAdditionalFieldProvider constructor.
91
     */
92
    public function __construct()
93
    {
94
        $this->siteRepository = GeneralUtility::makeInstance(SiteRepository::class);
95
    }
96
97
    /**
98
     * Initializes this instance and the necessary objects.
99
     *
100
     * @param SchedulerModuleController $schedulerModule
101
     * @param AbstractTask|null $task
102
     * @param array $taskInfo
103
     */
104
    protected function initialize(
105
        SchedulerModuleController $schedulerModule,
106
        AbstractTask $task = null,
107
        array $taskInfo = []
108
    )
109
    {
110
        /** @var $task ReIndexTask */
111
        $this->task = $task;
112
        $this->schedulerModule = $schedulerModule;
113
        $this->taskInformation = $taskInfo;
114
115
        $currentAction = $schedulerModule->getCurrentAction();
116
117
        if ($currentAction->equals(Action::EDIT)) {
118
            $this->site = $this->siteRepository->getSiteByRootPageId($task->getRootPageId());
119
        }
120
    }
121
122
    /**
123
     * Used to define fields to provide the Solr server address when adding
124
     * or editing a task.
125
     *
126
     * @param array $taskInfo reference to the array containing the info used in the add/edit form
127
     * @param AbstractTask $task when editing, reference to the current task object. Null when adding.
128
     * @param SchedulerModuleController $schedulerModule reference to the calling object (Scheduler's BE module)
129
     * @return array Array containing all the information pertaining to the additional fields
130
     *                        The array is multidimensional, keyed to the task class name and each field's id
131
     *                        For each field it provides an associative sub-array with the following:
132
     * @throws BackendFormException
133
     * @throws NoSolrConnectionFoundException
134
     * @noinspection PhpParameterByRefIsNotUsedAsReferenceInspection
135
     * @noinspection PhpMissingReturnTypeInspection
136
     */
137
    public function getAdditionalFields(
138
        array &$taskInfo,
139
        $task,
140
        SchedulerModuleController $schedulerModule
141
    )
142
    {
143
        $additionalFields = [];
144
145
        if (!$this->isTaskInstanceofOptimizeIndexTask($task)) {
146
            return $additionalFields;
147
        }
148
149
        $this->initialize($schedulerModule, $task, $taskInfo);
150
        $siteSelectorField = GeneralUtility::makeInstance(SiteSelectorField::class);
151
152
        $additionalFields['site'] = [
153
            'code' => $siteSelectorField->getAvailableSitesSelector('tx_scheduler[site]', $this->site),
154
            'label' => $this->languageFile . ':field_site',
155
            'cshKey' => '',
156
            'cshLabel' => ''
157
        ];
158
159
        $additionalFields['cores'] = [
160
            'code' => $this->getCoreSelectorMarkup(),
161
            'label' => $this->languageFile . ':field_cores',
162
            'cshKey' => '',
163
            'cshLabel' => ''
164
        ];
165
166
        return $additionalFields;
167
    }
168
169
    /**
170
     * Returns the selector HTML element with available cores.
171
     *
172
     * @throws BackendFormException
173
     * @throws NoSolrConnectionFoundException
174
     */
175
    protected function getCoreSelectorMarkup(): string
176
    {
177
        $selectorMarkup = $this->getLanguageService()->sL($this->languageFile . ':tasks.validate.selectSiteFirst');
178
179
        if (is_null($this->site)) {
180
            return $selectorMarkup;
181
        }
182
183
        /* @var CoreSelectorField $selectorField */
184
        $selectorField = GeneralUtility::makeInstance(CoreSelectorField::class, /** @scrutinizer ignore-type */ $this->site);
185
        $selectorField->setFormElementName('tx_scheduler[cores]');
186
        /* @noinspection PhpPossiblePolymorphicInvocationInspection */
187
        $selectorField->setSelectedValues($this->task->/** @scrutinizer ignore-call */getCoresToOptimizeIndex());
188
        return $selectorField->render();
189
    }
190
191
    /**
192
     * Checks any additional data that is relevant to this task. If the task
193
     * class is not relevant, the method is expected to return TRUE
194
     *
195
     * @param array $submittedData reference to the array containing the data submitted by the user
196
     * @param SchedulerModuleController $schedulerModule reference to the calling object (Scheduler's BE module)
197
     * @return bool True if validation was ok (or selected class is not relevant), FALSE otherwise
198
     * @throws Exception
199
     * @noinspection PhpParameterByRefIsNotUsedAsReferenceInspection
200
     * @noinspection PhpMissingReturnTypeInspection
201
     */
202
    public function validateAdditionalFields(
203
        array &$submittedData,
204
        SchedulerModuleController $schedulerModule
205
    )
206
    {
207
        $result = true;
208
        // validate site
209
        $sites = $this->siteRepository->getAvailableSites();
210
        if (!array_key_exists($submittedData['site'], $sites)) {
211
            $result = false;
212
        }
213
214
        // validate core selection
215
        if (array_key_exists('cores', $submittedData)
216
            && !is_array($submittedData['cores'])
217
        ) {
218
            $this->addMessage(
219
                $this->getLanguageService()->sL($this->languageFile . ':tasks.validate.invalidCores'),
220
                FlashMessage::ERROR
221
            );
222
            $result = false;
223
        }
224
        return $result;
225
    }
226
227
    /**
228
     * Saves any additional input into the current task object if the task
229
     * class matches.
230
     *
231
     * @param array $submittedData array containing the data submitted by the user
232
     * @param AbstractTask $task reference to the current task object
233
     */
234
    public function saveAdditionalFields(
235
        array $submittedData,
236
        AbstractTask $task
237
    )
238
    {
239
        /** @var $task OptimizeIndexTask */
240
        if (!$this->isTaskInstanceofOptimizeIndexTask($task)) {
241
            return;
242
        }
243
244
        $task->/** @scrutinizer ignore-call */
245
            setRootPageId($submittedData['site']);
246
247
        $cores = [];
248
        if (!empty($submittedData['cores'])) {
249
            $cores = $submittedData['cores'];
250
        }
251
        $task->/** @scrutinizer ignore-call */
252
        setCoresToOptimizeIndex($cores);
253
    }
254
255
    /**
256
     * @return PageRenderer
257
     */
258
    protected function getPageRenderer(): ?PageRenderer
259
    {
260
        if (!isset($this->pageRenderer)) {
261
            $this->pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
262
        }
263
        return $this->pageRenderer;
264
    }
265
266
    /**
267
     * Check that a task is an instance of ReIndexTask
268
     *
269
     * @param AbstractTask|null $task
270
     * @return boolean
271
     */
272
    protected function isTaskInstanceofOptimizeIndexTask(?AbstractTask $task): bool
273
    {
274
        if ((!is_null($task)) && (!($task instanceof OptimizeIndexTask))) {
275
            throw new LogicException(
276
                '$task must be an instance of OptimizeIndexTask, '
277
                .'other instances are not supported.', 1624620844
278
            );
279
        }
280
        return true;
281
    }
282
283
    /**
284
     * @return LanguageService
285
     */
286
    protected function getLanguageService(): LanguageService
287
    {
288
        return $GLOBALS['LANG'];
289
    }
290
}
291