Passed
Push — release-11.0.x ( 910681...ed160c )
by Rafael
11:00
created

overwriteModuleTemplate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
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 TYPO3\CMS\Backend\Template\ModuleTemplate;
30
use TYPO3\CMS\Core\Http\RedirectResponse;
31
use TYPO3\CMS\Core\Messaging\FlashMessage;
32
use TYPO3\CMS\Core\Utility\GeneralUtility;
33
use TYPO3Fluid\Fluid\View\ViewInterface;
34
35
/**
36
 * Tika Control Panel
37
 *
38
 * @author Ingo Renner <[email protected]>
39
 */
40
class TikaControlPanelModuleController extends AbstractModuleController
41
{
42
43
    /**
44
     * Tika configuration
45
     *
46
     * @var array
47
     */
48
    protected array $tikaConfiguration = [];
49
50
    /**
51
     * @var 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 1
    }
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 1
    }
78
79
    /**
80
     * @param AbstractService $tikaService
81
     */
82 1
    public function setTikaService(AbstractService $tikaService): void
83
    {
84 1
        $this->tikaService = $tikaService;
0 ignored issues
show
Documentation Bug introduced by
$tikaService is of type ApacheSolrForTypo3\Tika\...ce\Tika\AbstractService, but the property $tikaService was declared to be of type ApacheSolrForTypo3\Tika\...ce\Tika\SolrCellService. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
85 1
    }
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 1
    }
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
        );
120
121 1
        if ($this->tikaConfiguration['extractor'] === 'server') {
122 1
            $this->checkTikaServerConnection();
123
124 1
            $this->view->assign(
125 1
                'server',
126
                [
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
                ]
133
            );
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->isServerRunning()) {
0 ignored issues
show
Bug introduced by
The method isServerRunning() does not exist on ApacheSolrForTypo3\Tika\...ce\Tika\SolrCellService. ( Ignorable by Annotation )

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

170
        if (!$this->tikaService->/** @scrutinizer ignore-call */ isServerRunning()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method isServerRunning() does not exist on ApacheSolrForTypo3\Tika\Service\Tika\AppService. ( Ignorable by Annotation )

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

170
        if (!$this->tikaService->/** @scrutinizer ignore-call */ isServerRunning()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
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
     */
186 1
    protected function getTikaServerVersion(): string
187
    {
188 1
        return $this->tikaService->getTikaVersion();
189
    }
190
191
    /**
192
     * Tries to connect to Tika server
193
     *
194
     * @return bool TRUE if the Tika server responds, FALSE otherwise.
195
     */
196 1
    protected function isTikaServerRunning(): bool
197
    {
198 1
        return $this->tikaService->isServerRunning();
199
    }
200
201
    /**
202
     * Returns the pid if the Tika server has been started through the backend
203
     * module.
204
     *
205
     * @return int|null Tika Server pid or null if not found
206
     */
207 1
    protected function getTikaServerPid(): ?int
208
    {
209 1
        return $this->tikaService->/** @scrutinizer ignore-call */getServerPid();
210
    }
211
212
    /**
213
     * Checks whether the server jar has been configured properly.
214
     *
215
     * @return bool TRUE if a path for the jar has been configured and the path exists
216
     */
217 1
    protected function isTikaServerJarAvailable(): bool
218
    {
219 1
        if (!empty($this->tikaConfiguration['tikaServerPath'])) {
220 1
            return file_exists($this->tikaConfiguration['tikaServerPath']);
221
        }
222
        return false;
223
    }
224
225
    /**
226
     * Checks whether Tika server can be controlled (started/stopped).
227
     *
228
     * Checks whether exec() is allowed and whether configuration is available.
229
     *
230
     * @return bool TRUE if Tika server can be started/stopped
231
     */
232 1
    protected function isTikaServerControllable(): bool
233
    {
234 1
        $disabledFunctions = ini_get('disable_functions')
235 1
            . ',' . ini_get('suhosin.executor.func.blacklist');
236 1
        $disabledFunctions = GeneralUtility::trimExplode(
237 1
            ',',
238 1
            $disabledFunctions
239
        );
240 1
        if (in_array('exec', $disabledFunctions)) {
241
            return false;
242
        }
243
244 1
        if (ini_get('safe_mode')) {
245
            return false;
246
        }
247
248 1
        $jarAvailable = $this->isTikaServerJarAvailable();
249 1
        $running = $this->isTikaServerRunning();
250 1
        $pid = $this->getTikaServerPid();
251
252 1
        $controllable = false;
253 1
        if ($running && $jarAvailable && !is_null($pid)) {
254 1
            $controllable = true;
255
        } elseif (!$running && $jarAvailable) {
256
            $controllable = true;
257
        }
258
259 1
        return $controllable;
260
    }
261
262
    /**
263
     * Checks whether the configured Tika server can be reached and provides a
264
     * flash message according to the result of the check.
265
     */
266 1
    protected function checkTikaServerConnection(): void
267
    {
268 1
        if ($this->tikaService->/** @scrutinizer ignore-call */ping()) {
269
            $this->addFlashMessage(
270
                'Tika host contacted at: ' . $this->tikaService->/** @scrutinizer ignore-call */getTikaServerUrl(),
271
                'Your Apache Tika server has been contacted.',
272
                FlashMessage::OK
273
            );
274
        } else {
275 1
            $this->addFlashMessage(
276 1
                'Could not connect to Tika at: ' . $this->tikaService->/** @scrutinizer ignore-call */getTikaServerUrl(),
277 1
                'Unable to contact Apache Tika server.',
278 1
                FlashMessage::ERROR
279
            );
280
        }
281 1
    }
282
}
283