Passed
Pull Request — master (#1317)
by
unknown
21:24
created

AbstractModuleController::switchCoreAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 0
cts 9
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 7
nc 1
nop 2
crap 2
1
<?php
2
namespace ApacheSolrForTypo3\Solr\Controller\Backend\Search;
3
4
/***************************************************************
5
 *  Copyright notice
6
 *
7
 *  (c) 2010-2017 dkd Internet Service GmbH <[email protected]>
8
 *  All rights reserved
9
 *
10
 *  This script is part of the TYPO3 project. The TYPO3 project is
11
 *  free software; you can redistribute it and/or modify
12
 *  it under the terms of the GNU General Public License as published by
13
 *  the Free Software Foundation; either version 2 of the License, or
14
 *  (at your option) any later version.
15
 *
16
 *  The GNU General Public License can be found at
17
 *  http://www.gnu.org/copyleft/gpl.html.
18
 *
19
 *  This script is distributed in the hope that it will be useful,
20
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 *  GNU General Public License for more details.
23
 *
24
 *  This copyright notice MUST APPEAR in all copies of the script!
25
 ***************************************************************/
26
27
use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository;
28
use ApacheSolrForTypo3\Solr\Site;
29
use ApacheSolrForTypo3\Solr\SolrService as SolrCoreConnection;
30
use ApacheSolrForTypo3\Solr\System\Mvc\Backend\Component\Exception\InvalidViewObjectNameException;
31
use ApacheSolrForTypo3\Solr\Utility\StringUtility;
32
use TYPO3\CMS\Backend\Template\Components\Menu\Menu;
33
use TYPO3\CMS\Backend\Utility\BackendUtility;
34
use TYPO3\CMS\Backend\View\BackendTemplateView;
35
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
36
use TYPO3\CMS\Core\Messaging\AbstractMessage;
37
use TYPO3\CMS\Core\Utility\GeneralUtility;
38
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
39
use TYPO3\CMS\Extbase\Mvc\View\NotFoundView;
40
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
41
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
42
43
/**
44
 * Abstract Module
45
 *
46
 * @property BackendTemplateView $view
47
 */
48
abstract class AbstractModuleController extends ActionController
49
{
50
    /**
51
     * Backend Template Container
52
     *
53
     * @var string
54
     */
55
    protected $defaultViewObjectName = BackendTemplateView::class;
56
57
    /**
58
     * @var \ApacheSolrForTypo3\Solr\Utility\StringUtility
59
     */
60
    protected $stringUtility;
61
62
    /**
63
     * In the pagetree selected page UID
64
     *
65
     * @var int
66
     */
67
    protected $selectedPageUID;
68
69
    /**
70
     * @var SiteRepository
71
     */
72
    protected $siteRepository;
73
    /**
74
     * @var Site
75
     */
76
    protected $selectedSite;
77
78
    /**
79
     * @var SolrCoreConnection
80
     */
81
    protected $selectedSolrCoreConnection;
82
83
    /**
84
     * @var Menu
85
     */
86
    protected $coreSelectorMenu = null;
87
88
    /**
89
     * @var \ApacheSolrForTypo3\Solr\ConnectionManager
90
     * @inject
91
     */
92
    protected $solrConnectionManager = null;
93
94
    /**
95
     * @var \ApacheSolrForTypo3\Solr\System\Mvc\Backend\Service\ModuleDataStorageService
96
     * @inject
97
     */
98
    protected $moduleDataStorageService = null;
99
100
    /**
101
     * Method to pass a StringUtil object.
102
     * Use to overwrite injected object in unit test context.
103
     *
104
     * @param \ApacheSolrForTypo3\Solr\Utility\StringUtility $stringUtility
105
     */
106
    public function injectStringHelper(StringUtility $stringUtility)
107
    {
108
        $this->stringUtility = $stringUtility;
109
    }
110
111
    /**
112
     * Initializes the controller and sets needed vars.
113
     */
114
    protected function initializeAction()
115
    {
116
        parent::initializeAction();
117
        $this->selectedPageUID = (int)GeneralUtility::_GP('id');
118
        if ($this->request->hasArgument('id')) {
119
            $this->selectedPageUID = (int)$this->request->getArgument('id');
120
        }
121
122
        if ($this->selectedPageUID < 1) {
123
            return;
124
        }
125
126
        $this->siteRepository = $this->objectManager->get(SiteRepository::class);
127
128
        try {
129
            $this->selectedSite = $this->siteRepository->getSiteByPageId($this->selectedPageUID);
130
        } catch (\InvalidArgumentException $exception) {
131
            return;
132
        }
133
    }
134
135
    /**
136
     * Set up the doc header properly here
137
     *
138
     * @param ViewInterface $view
139
     * @return void
140
     */
141
    protected function initializeView(ViewInterface $view)
142
    {
143
        parent::initializeView($view);
144
        if ($view instanceof NotFoundView || $this->selectedPageUID < 1) {
145
            return;
146
        }
147
        $this->view->getModuleTemplate()->addJavaScriptCode('mainJsFunctions', '
148
                top.fsMod.recentIds["searchbackend"] = ' . (int)$this->selectedPageUID . ';'
149
        );
150
        if (null === $this->selectedSite) {
151
            return;
152
        }
153
154
        /* @var BackendUserAuthentication $beUser */
155
        $beUser = $GLOBALS['BE_USER'];
156
        $permissionClause = $beUser->getPagePermsClause(1);
157
        $pageRecord = BackendUtility::readPageAccess($this->selectedSite->getRootPageId(), $permissionClause);
158
159
        if (false === $pageRecord) {
160
            throw new \InvalidArgumentException(vsprintf('There is something wrong with permissions for page "%s" for backend user "%s".', [$this->selectedSite->getRootPageId(), $beUser->user['username']]), 1496146317);
161
        }
162
        $this->view->getModuleTemplate()->getDocHeaderComponent()->setMetaInformation($pageRecord);
163
164
        $this->view->assign('pUID', $this->selectedPageUID);
165
    }
166
167
    /**
168
     * Generates selector menu in backends doc header using selected page from page tree.
169
     *
170
     * @param string|null $uriToRedirectTo
171
     */
172
    public function generateCoreSelectorMenuUsingPageTree(string $uriToRedirectTo = null)
173
    {
174
        if ($this->selectedPageUID < 1 || null === $this->selectedSite) {
175
            return;
176
        }
177
178
        if ($this->view instanceof NotFoundView) {
179
            $this->initializeSelectedSolrCoreConnection();
180
            return;
181
        }
182
183
        $this->generateCoreSelectorMenu($this->selectedSite, $uriToRedirectTo);
184
    }
185
186
    /**
187
     * Generates Core selector Menu for given Site.
188
     *
189
     * @param Site $site
190
     * @param string|null $uriToRedirectTo
191
     * @throws InvalidViewObjectNameException
192
     */
193
    protected function generateCoreSelectorMenu(Site $site, string $uriToRedirectTo = null)
194
    {
195
        if (!$this->view instanceof BackendTemplateView) {
196
            throw new InvalidViewObjectNameException(vsprintf(
197
                'The controller "%s" must use BackendTemplateView to be able to generate menu for backends docheader. \
198
                Please set `protected $defaultViewObjectName = BackendTemplateView::class;` field in your controller.',
199
                [static::class]), 1493804179);
200
        }
201
        $this->view->getModuleTemplate()->setFlashMessageQueue($this->controllerContext->getFlashMessageQueue());
202
203
        $this->coreSelectorMenu = $this->view->getModuleTemplate()->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
204
        $this->coreSelectorMenu->setIdentifier('component_core_selector_menu');
205
206
        if (!isset($uriToRedirectTo)) {
207
            $uriToRedirectTo = $this->uriBuilder->reset()->uriFor();
208
        }
209
210
        $this->initializeSelectedSolrCoreConnection();
211
        $cores = $this->solrConnectionManager->getConnectionsBySite($site);
212
        foreach ($cores as $core) {
213
            $menuItem = $this->coreSelectorMenu->makeMenuItem();
214
            $menuItem->setTitle($core->getPath());
215
            $uri = $this->uriBuilder->reset()->uriFor('switchCore',
216
                [
217
                    'corePath' => $core->getPath(),
218
                    'uriToRedirectTo' => $uriToRedirectTo
219
                ]
220
            );
221
            $menuItem->setHref($uri);
222
223
            if ($core->getPath() == $this->selectedSolrCoreConnection->getPath()) {
224
                $menuItem->setActive(true);
225
            }
226
            $this->coreSelectorMenu->addMenuItem($menuItem);
227
        }
228
229
        $this->view->getModuleTemplate()->getDocHeaderComponent()->getMenuRegistry()->addMenu($this->coreSelectorMenu);
230
    }
231
232
    /**
233
     * Switches used core.
234
     *
235
     * Note: Does not check availability of core in site. All this stuff is done in the generation step.
236
     *
237
     * @param string $corePath
238
     * @param string $uriToRedirectTo
239
     */
240
    public function switchCoreAction(string $corePath, string $uriToRedirectTo)
241
    {
242
        $moduleData = $this->moduleDataStorageService->loadModuleData();
243
        $moduleData->setCore($corePath);
244
245
        $this->moduleDataStorageService->persistModuleData($moduleData);
246
        $message = LocalizationUtility::translate('coreselector_switched_successfully', 'solr', [$corePath]);
247
        $this->addFlashMessage($message);
248
        $this->redirectToUri($uriToRedirectTo);
249
    }
250
251
    /**
252
     * Initializes the solr core connection considerately to the components state.
253
     * Uses and persists default core connection if persisted core in Site does not exist.
254
     *
255
     */
256
    private function initializeSelectedSolrCoreConnection()
257
    {
258
        $moduleData = $this->moduleDataStorageService->loadModuleData();
259
260
        $solrCoreConnections = $this->solrConnectionManager->getConnectionsBySite($this->selectedSite);
261
        $currentSolrCorePath = $moduleData->getCore();
262
        if (empty($currentSolrCorePath)) {
263
            $this->initializeFirstAvailableSolrCoreConnection($solrCoreConnections, $moduleData);
264
        }
265
        foreach ($solrCoreConnections as $solrCoreConnection) {
266
            if ($solrCoreConnection->getPath() == $currentSolrCorePath) {
267
                $this->selectedSolrCoreConnection = $solrCoreConnection;
268
            }
269
        }
270
        if (!$this->selectedSolrCoreConnection instanceof SolrCoreConnection && count($solrCoreConnections) > 0) {
271
            $this->initializeFirstAvailableSolrCoreConnection($solrCoreConnections, $moduleData);
272
            $message = LocalizationUtility::translate('coreselector_switched_to_default_core', 'solr', [$currentSolrCorePath, $this->selectedSite->getLabel(), $this->selectedSolrCoreConnection->getPath()]);
273
            $this->addFlashMessage($message, '', AbstractMessage::NOTICE);
274
        }
275
    }
276
277
    /**
278
     * @param SolrCoreConnection[] $solrCoreConnections
279
     */
280
    private function initializeFirstAvailableSolrCoreConnection(array $solrCoreConnections, $moduleData)
281
    {
282
        $this->selectedSolrCoreConnection = $solrCoreConnections[0];
283
        $moduleData->setCore($this->selectedSolrCoreConnection->getPath());
284
        $this->moduleDataStorageService->persistModuleData($moduleData);
285
    }
286
}
287