Passed
Push — release-11.0.x ( ef2028...d0f0d9 )
by Rafael
18:22 queued 15:35
created

TikaControlPanelModuleController   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 239
Duplicated Lines 0 %

Test Coverage

Coverage 63.74%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 73
dl 0
loc 239
ccs 58
cts 91
cp 0.6374
rs 10
c 1
b 0
f 0
wmc 26

14 Methods

Rating   Name   Duplication   Size   Complexity  
A overwriteView() 0 3 1
A initializeAction() 0 6 1
A overwriteModuleTemplate() 0 3 1
A setTikaConfiguration() 0 3 1
A setTikaService() 0 3 1
A getTikaServerPid() 0 3 1
A isTikaServerJarAvailable() 0 6 2
A getTikaServerVersion() 0 3 1
A isTikaServerRunning() 0 3 1
A stopServerAction() 0 15 2
A checkTikaServerConnection() 0 13 2
A indexAction() 0 23 2
A startServerAction() 0 15 2
B isTikaServerControllable() 0 28 8
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ApacheSolrForTypo3\Tika\Controller\Backend\SolrModule;
6
7
/*
8
 * This file is part of the TYPO3 CMS project.
9
 *
10
 * It is free software; you can redistribute it and/or modify it under
11
 * the terms of the GNU General Public License, either version 2
12
 * of the License, or any later version.
13
 *
14
 * For the full copyright and license information, please read the
15
 * LICENSE.txt file that was distributed with this source code.
16
 *
17
 * The TYPO3 project - inspiring people to share!
18
 */
19
20
use ApacheSolrForTypo3\Solr\Controller\Backend\Search\AbstractModuleController;
21
use ApacheSolrForTypo3\Tika\Service\Tika\AbstractService;
22
use ApacheSolrForTypo3\Tika\Service\Tika\AppService;
23
use ApacheSolrForTypo3\Tika\Service\Tika\ServerService;
24
use ApacheSolrForTypo3\Tika\Service\Tika\ServiceFactory;
25
use ApacheSolrForTypo3\Tika\Service\Tika\SolrCellService;
26
use ApacheSolrForTypo3\Tika\Util;
27
use Psr\Http\Client\ClientExceptionInterface;
28
use Psr\Http\Message\ResponseInterface;
29
use Throwable;
30
use TYPO3\CMS\Backend\Template\ModuleTemplate;
31
use TYPO3\CMS\Core\Http\RedirectResponse;
32
use TYPO3\CMS\Core\Messaging\FlashMessage;
33
use TYPO3\CMS\Core\Utility\GeneralUtility;
34
use TYPO3Fluid\Fluid\View\ViewInterface;
35
36
/**
37
 * Tika Control Panel
38
 *
39
 * @author Ingo Renner <[email protected]>
40
 */
41
class TikaControlPanelModuleController extends AbstractModuleController
42
{
43
    /**
44
     * Tika configuration
45
     *
46
     * @var array
47
     */
48
    protected array $tikaConfiguration = [];
49
50
    /**
51
     * @var AbstractService|AppService|ServerService|SolrCellService
52
     */
53
    protected $tikaService;
54
55
    /**
56
     * Can be used in the test context to mock a {@link view}.
57
     *
58
     * Purpose: PhpUnit
59
     *
60
     * @param ViewInterface $view
61
     */
62 1
    public function overwriteView(ViewInterface $view): void
63
    {
64 1
        $this->view = $view;
0 ignored issues
show
Documentation Bug introduced by
It seems like $view of type TYPO3Fluid\Fluid\View\ViewInterface is incompatible with the declared type TYPO3\CMS\Extbase\Mvc\View\ViewInterface of property $view.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
65
    }
66
67
    /**
68
     * Can be used in the test context to mock a {@link moduleTemplate}.
69
     *
70
     * Purpose: PhpUnit
71
     *
72
     * @param ModuleTemplate $moduleTemplate
73
     */
74 1
    public function overwriteModuleTemplate(ModuleTemplate $moduleTemplate): void
75
    {
76 1
        $this->moduleTemplate = $moduleTemplate;
77
    }
78
79
    /**
80
     * @param AbstractService $tikaService
81
     */
82 1
    public function setTikaService(AbstractService $tikaService): void
83
    {
84 1
        $this->tikaService = $tikaService;
85
    }
86
87
    /**
88
     * Initializes resources commonly needed for several actions.
89
     * @noinspection PhpUnused
90
     */
91
    protected function initializeAction(): void
92
    {
93
        parent::initializeAction();
94
        $tikaConfiguration = Util::getTikaExtensionConfiguration();
95
        $this->setTikaConfiguration($tikaConfiguration);
96
        $this->tikaService = ServiceFactory::getTika($this->tikaConfiguration['extractor'] ?? '');
97
    }
98
99
    /**
100
     * @param array $tikaConfiguration
101
     */
102 1
    public function setTikaConfiguration(array $tikaConfiguration): void
103
    {
104 1
        $this->tikaConfiguration = $tikaConfiguration;
105
    }
106
107
    /**
108
     * Index action
109
     *
110
     * @return ResponseInterface
111
     * @throws ClientExceptionInterface
112
     */
113 1
    public function indexAction(): ResponseInterface
114
    {
115 1
        $this->view->assign('configuration', $this->tikaConfiguration);
116 1
        $this->view->assign(
117 1
            'extractor',
118 1
            ucfirst($this->tikaConfiguration['extractor'] ?? '')
119 1
        );
120
121 1
        if ($this->tikaConfiguration['extractor'] === 'server') {
122 1
            $this->checkTikaServerConnection();
123
124 1
            $this->view->assign(
125 1
                'server',
126 1
                [
127 1
                    'jarAvailable' => $this->isTikaServerJarAvailable(),
128 1
                    'isRunning' => $this->isTikaServerRunning(),
129 1
                    'isControllable' => $this->isTikaServerControllable(),
130 1
                    'pid' => $this->getTikaServerPid(),
131 1
                    'version' => $this->getTikaServerVersion(),
132 1
                ]
133 1
            );
134
        }
135 1
        return $this->getModuleTemplateResponse();
136
    }
137
138
    /**
139
     * Starts the Tika server
140
     * @noinspection PhpUnused
141
     */
142
    public function startServerAction(): ResponseInterface
143
    {
144
        $this->tikaService->/** @scrutinizer ignore-call */startServer();
145
146
        // give it some time to start
147
        sleep(2);
148
149
        if ($this->tikaService->/** @scrutinizer ignore-call */isServerRunning()) {
150
            $this->addFlashMessage(
151
                'Tika server started.',
152
                FlashMessage::OK
153
            );
154
        }
155
156
        return new RedirectResponse($this->uriBuilder->uriFor('index'), 303);
157
    }
158
159
    /**
160
     * Stops the Tika server
161
     * @noinspection PhpUnused
162
     */
163
    public function stopServerAction(): ResponseInterface
164
    {
165
        $this->tikaService->/** @scrutinizer ignore-call */ stopServer();
166
167
        // give it some time to stop
168
        sleep(2);
169
170
        if (!$this->tikaService->/** @scrutinizer ignore-call */ isServerRunning()) {
171
            $this->addFlashMessage(
172
                'Tika server stopped.',
173
                FlashMessage::OK
174
            );
175
        }
176
177
        return new RedirectResponse($this->uriBuilder->uriFor('index'), 303);
178
    }
179
180
    /**
181
     * Gets the Tika server version
182
     *
183
     * @return string Tika server version string
184
     * @throws ClientExceptionInterface
185
     * @throws Throwable
186
     */
187 1
    protected function getTikaServerVersion(): string
188
    {
189 1
        return $this->tikaService->getTikaVersion();
190
    }
191
192
    /**
193
     * Tries to connect to Tika server
194
     *
195
     * @return bool TRUE if the Tika server responds, FALSE otherwise.
196
     */
197 1
    protected function isTikaServerRunning(): bool
198
    {
199 1
        return $this->tikaService->/** @scrutinizer ignore-call */ isServerRunning();
200
    }
201
202
    /**
203
     * Returns the pid if the Tika server has been started through the backend
204
     * module.
205
     *
206
     * @return int|null Tika Server pid or null if not found
207
     */
208 1
    protected function getTikaServerPid(): ?int
209
    {
210 1
        return $this->tikaService->/** @scrutinizer ignore-call */getServerPid();
211
    }
212
213
    /**
214
     * Checks whether the server jar has been configured properly.
215
     *
216
     * @return bool TRUE if a path for the jar has been configured and the path exists
217
     */
218 1
    protected function isTikaServerJarAvailable(): bool
219
    {
220 1
        if (!empty($this->tikaConfiguration['tikaServerPath'])) {
221 1
            return file_exists($this->tikaConfiguration['tikaServerPath']);
222
        }
223
        return false;
224
    }
225
226
    /**
227
     * Checks whether Tika server can be controlled (started/stopped).
228
     *
229
     * Checks whether exec() is allowed and whether configuration is available.
230
     *
231
     * @return bool TRUE if Tika server can be started/stopped
232
     */
233 1
    protected function isTikaServerControllable(): bool
234
    {
235 1
        $disabledFunctions = ini_get('disable_functions')
236 1
            . ',' . ini_get('suhosin.executor.func.blacklist');
237 1
        $disabledFunctions = GeneralUtility::trimExplode(
238 1
            ',',
239 1
            $disabledFunctions
240 1
        );
241 1
        if (in_array('exec', $disabledFunctions)) {
242
            return false;
243
        }
244
245 1
        if (ini_get('safe_mode')) {
246
            return false;
247
        }
248
249 1
        $jarAvailable = $this->isTikaServerJarAvailable();
250 1
        $running = $this->isTikaServerRunning();
251 1
        $pid = $this->getTikaServerPid();
252
253 1
        $controllable = false;
254 1
        if ($running && $jarAvailable && !is_null($pid)) {
255 1
            $controllable = true;
256
        } elseif (!$running && $jarAvailable) {
257
            $controllable = true;
258
        }
259
260 1
        return $controllable;
261
    }
262
263
    /**
264
     * Checks whether the configured Tika server can be reached and provides a
265
     * flash message according to the result of the check.
266
     */
267 1
    protected function checkTikaServerConnection(): void
268
    {
269 1
        if ($this->tikaService->/** @scrutinizer ignore-call */ping()) {
270
            $this->addFlashMessage(
271
                'Tika host contacted at: ' . $this->tikaService->/** @scrutinizer ignore-call */getTikaServerUrl(),
272
                'Your Apache Tika server has been contacted.',
273
                FlashMessage::OK
274
            );
275
        } else {
276 1
            $this->addFlashMessage(
277 1
                'Could not connect to Tika at: ' . $this->tikaService->/** @scrutinizer ignore-call */getTikaServerUrl(),
278 1
                'Unable to contact Apache Tika server.',
279 1
                FlashMessage::ERROR
280 1
            );
281
        }
282
    }
283
}
284