Passed
Push — task/3376-TYPO3_12_compatibili... ( dc7e5a...379ca7 )
by Rafael
40:48
created

getConfigIndexEnableStatus()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 18
rs 9.9332
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
declare(strict_types=1);
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
namespace ApacheSolrForTypo3\Solr\Report;
19
20
use ApacheSolrForTypo3\Solr\FrontendEnvironment;
21
use ApacheSolrForTypo3\Solr\System\Configuration\ExtensionConfiguration;
22
use ApacheSolrForTypo3\Solr\System\Records\Pages\PagesRepository;
23
use Doctrine\DBAL\Driver\Exception as DBALDriverException;
24
use RuntimeException;
25
use TYPO3\CMS\Core\Error\Http\ServiceUnavailableException;
26
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
27
use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity;
28
use TYPO3\CMS\Core\Utility\GeneralUtility;
29
use TYPO3\CMS\Reports\Status;
30
31
/**
32
 * Provides a status report, which checks whether the configuration of the
33
 * extension is ok.
34
 *
35
 * @author Ingo Renner <[email protected]>
36
 */
37
class SolrConfigurationStatus extends AbstractSolrStatus
38
{
39
    /**
40
     * @var ExtensionConfiguration
41
     */
42
    protected ExtensionConfiguration $extensionConfiguration;
43
44
    /**
45
     * @var FrontendEnvironment
46
     */
47
    protected FrontendEnvironment $frontendEnvironment;
48
49
    /**
50
     * SolrConfigurationStatus constructor.
51
     * @param ExtensionConfiguration|null $extensionConfiguration
52
     * @param FrontendEnvironment|null $frontendEnvironment
53
     */
54
    public function __construct(
55
        ExtensionConfiguration $extensionConfiguration = null,
56
        FrontendEnvironment $frontendEnvironment = null
57
    ) {
58
        $this->extensionConfiguration = $extensionConfiguration ?? GeneralUtility::makeInstance(ExtensionConfiguration::class);
59
        $this->frontendEnvironment = $frontendEnvironment ?? GeneralUtility::makeInstance(FrontendEnvironment::class);
60
    }
61
62
    /**
63
     * Compiles a collection of configuration status checks.
64
     *
65
     * @return array
66
     *
67
     * @throws DBALDriverException
68
     */
69
    public function getStatus(): array
70
    {
71
        $reports = [];
72
73
        $rootPageFlagStatus = $this->getRootPageFlagStatus();
74
        if (!is_null($rootPageFlagStatus)) {
75
            $reports[] = $rootPageFlagStatus;
76
77
            // intended early return, no sense in going on if there are no root pages
78
            return $reports;
79
        }
80
81
        $configIndexEnableStatus = $this->getConfigIndexEnableStatus();
82
        if (!is_null($configIndexEnableStatus)) {
83
            $reports[] = $configIndexEnableStatus;
84
        }
85
86
        return $reports;
87
    }
88
89
    /**
90
     * {@inheritDoc}
91
     */
92
    public function getLabel(): string
93
    {
94
        return 'solr/configuration';
95
    }
96
97
    /**
98
     * Checks whether the "Use as Root Page" page property has been set for any
99
     * site.
100
     *
101
     * @return Status|null An error status is returned if no root pages were found.
102
     */
103
    protected function getRootPageFlagStatus(): ?Status
104
    {
105
        $rootPages = $this->getRootPages();
106
        if (!empty($rootPages)) {
107
            return null;
108
        }
109
110
        $report = $this->getRenderedReport('RootPageFlagStatus.html');
111
        return GeneralUtility::makeInstance(
112
            Status::class,
113
            /** @scrutinizer ignore-type */
114
            'Sites',
115
            /** @scrutinizer ignore-type */
116
            'No sites found',
117
            /** @scrutinizer ignore-type */
118
            $report,
119
            /** @scrutinizer ignore-type */
120
            ContextualFeedbackSeverity::ERROR
121
        );
122
    }
123
124
    /**
125
     * Checks whether config.index_enable is set to 1, otherwise indexing will
126
     * not work.
127
     *
128
     * @return Status|null An error status is returned for each site root page config.index_enable = 0.
129
     * @throws DBALDriverException
130
     */
131
    protected function getConfigIndexEnableStatus(): ?Status
132
    {
133
        $rootPagesWithIndexingOff = $this->getRootPagesWithIndexingOff();
134
        if (empty($rootPagesWithIndexingOff)) {
135
            return null;
136
        }
137
138
        $report = $this->getRenderedReport('SolrConfigurationStatusIndexing.html', ['pages' => $rootPagesWithIndexingOff]);
139
        return GeneralUtility::makeInstance(
140
            Status::class,
141
            /** @scrutinizer ignore-type */
142
            'Page Indexing',
143
            /** @scrutinizer ignore-type */
144
            'Indexing is disabled',
145
            /** @scrutinizer ignore-type */
146
            $report,
147
            /** @scrutinizer ignore-type */
148
            ContextualFeedbackSeverity::WARNING
149
        );
150
    }
151
152
    /**
153
     * Returns an array of rootPages where the indexing is off and EXT:solr is enabled.
154
     *
155
     * @return array
156
     * @throws DBALDriverException
157
     */
158
    protected function getRootPagesWithIndexingOff(): array
159
    {
160
        $rootPages = $this->getRootPages();
161
        $rootPagesWithIndexingOff = [];
162
163
        foreach ($rootPages as $rootPage) {
164
            try {
165
                $solrIsEnabledAndIndexingDisabled = $this->getIsSolrEnabled($rootPage['uid']) && !$this->getIsIndexingEnabled($rootPage['uid']);
166
                if ($solrIsEnabledAndIndexingDisabled) {
167
                    $rootPagesWithIndexingOff[] = $rootPage;
168
                }
169
            } catch (RuntimeException $rte) {
170
                $rootPagesWithIndexingOff[] = $rootPage;
171
            } catch (ServiceUnavailableException $sue) {
172
                if ($sue->getCode() == 1294587218) {
173
                    //  No TypoScript template found, continue with next site
174
                    $rootPagesWithIndexingOff[] = $rootPage;
175
                    continue;
176
                }
177
            } catch (SiteNotFoundException $sue) {
178
                if ($sue->getCode() == 1521716622) {
179
                    //  No site found, continue with next site
180
                    $rootPagesWithIndexingOff[] = $rootPage;
181
                    continue;
182
                }
183
            }
184
        }
185
186
        return $rootPagesWithIndexingOff;
187
    }
188
189
    /**
190
     * Gets the site's root pages. The "Is root of website" flag must be set,
191
     * which usually is the case for pages with pid = 0.
192
     *
193
     * @return array An array of (partial) root page records, containing the uid and title fields
194
     */
195
    protected function getRootPages(): array
196
    {
197
        $pagesRepository = GeneralUtility::makeInstance(PagesRepository::class);
198
        return $pagesRepository->findAllRootPages();
199
    }
200
201
    /**
202
     * Checks if the solr plugin is enabled with plugin.tx_solr.enabled.
203
     *
204
     * @param int $pageUid
205
     * @return bool
206
     * @throws DBALDriverException
207
     */
208
    protected function getIsSolrEnabled(int $pageUid): bool
209
    {
210
        return $this->frontendEnvironment->getSolrConfigurationFromPageId($pageUid)->getEnabled();
211
    }
212
213
    /**
214
     * Checks if the indexing is enabled with config.index_enable
215
     *
216
     * @param int $pageUid
217
     * @return bool
218
     * @throws DBALDriverException
219
     */
220
    protected function getIsIndexingEnabled(int $pageUid): bool
221
    {
222
        return (bool)$this->frontendEnvironment
223
            ->getConfigurationFromPageId($pageUid)
224
            ->getValueByPathOrDefaultValue('config.index_enable', false);
225
    }
226
}
227