Failed Conditions
Pull Request — main (#3637)
by Benni
34:26
created

Builder   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 223
Duplicated Lines 0 %

Test Coverage

Coverage 97.87%

Importance

Changes 0
Metric Value
wmc 25
eloc 81
c 0
b 0
f 0
dl 0
loc 223
ccs 92
cts 94
cp 0.9787
rs 10

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A getDocumentId() 0 3 1
A addKeywordsField() 0 9 3
A getExtractorForPageContent() 0 3 1
A fromPage() 0 55 1
A getPageDocumentId() 0 3 1
A getRootLineFieldValue() 0 7 2
A fromRecord() 0 43 5
A addTagContentFields() 0 4 2
A addAccessField() 0 5 2
A addEndtimeField() 0 4 3
A getSiteByPageId() 0 4 1
A getDocumentIdGroups() 0 10 2
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\Domain\Search\ApacheSolrDocument;
19
20
use ApacheSolrForTypo3\Solr\Access\Rootline;
21
use ApacheSolrForTypo3\Solr\Domain\Site\Site;
22
use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository;
23
use ApacheSolrForTypo3\Solr\Domain\Variants\IdBuilder;
24
use ApacheSolrForTypo3\Solr\System\Solr\Document\Document;
25
use ApacheSolrForTypo3\Solr\Typo3PageContentExtractor;
26
use ApacheSolrForTypo3\Solr\Util;
27
use Doctrine\DBAL\Exception as DBALException;
28
use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException;
29
use TYPO3\CMS\Core\Utility\GeneralUtility;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Core\Utility\GeneralUtility was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
30
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
31
32
/**
33
 * Builder class to build an ApacheSolrDocument
34
 *
35
 * Responsible to build \ApacheSolrForTypo3\Solr\System\Solr\Document\Document
36
 *
37
 * @author Timo Hund <[email protected]>
38
 */
39
class Builder
40
{
41 110
    public function __construct(
42
        protected readonly IdBuilder $variantIdBuilder
43
    ) {
44 110
    }
45
46
    /**
47
     * This method can be used to build a Document from a TYPO3 page.
48
     *
49
     * @throws AspectNotFoundException
50
     * @throws DBALException
51
     */
52 73
    public function fromPage(
53
        TypoScriptFrontendController $page,
54
        string $url,
55
        Rootline $pageAccessRootline,
56
        string $mountPointParameter = '',
57
    ): Document {
58
        /* @var Document $document */
59 73
        $document = GeneralUtility::makeInstance(Document::class);
60 73
        $site = $this->getSiteByPageId($page->id);
61 73
        $pageRecord = $page->page;
62
63 73
        $accessGroups = $this->getDocumentIdGroups($pageAccessRootline);
64 73
        $documentId = $this->getPageDocumentId($page, $accessGroups, $mountPointParameter);
65
66 73
        $document->setField('id', $documentId);
67 73
        $document->setField('site', $site->getDomain());
68 73
        $document->setField('siteHash', $site->getSiteHash());
69 73
        $document->setField('appKey', 'EXT:solr');
70 73
        $document->setField('type', 'pages');
71
72
        // system fields
73 73
        $document->setField('uid', $page->id);
74 73
        $document->setField('pid', $pageRecord['pid']);
75
76
        // variantId
77 73
        $variantId = $this->variantIdBuilder->buildFromTypeAndUid('pages', $page->id);
78 73
        $document->setField('variantId', $variantId);
79
80 73
        $document->setField('typeNum', $page->type);
81 73
        $document->setField('created', $pageRecord['crdate']);
82 73
        $document->setField('changed', $pageRecord['SYS_LASTCHANGED']);
83
84 73
        $rootline = $this->getRootLineFieldValue($page->id, $mountPointParameter);
85 73
        $document->setField('rootline', $rootline);
86
87
        // access
88 73
        $this->addAccessField($document, $pageAccessRootline);
89 73
        $this->addEndtimeField($document, $pageRecord);
90
91
        // content
92
        // @extensionScannerIgnoreLine
93 73
        $contentExtractor = $this->getExtractorForPageContent($page->content);
94 73
        $document->setField('title', $contentExtractor->getPageTitle());
95 73
        $document->setField('subTitle', $pageRecord['subtitle']);
96 73
        $document->setField('navTitle', $pageRecord['nav_title']);
97 73
        $document->setField('author', $pageRecord['author']);
98 73
        $document->setField('description', $pageRecord['description']);
99 73
        $document->setField('abstract', $pageRecord['abstract']);
100 73
        $document->setField('content', $contentExtractor->getIndexableContent());
101 73
        $document->setField('url', $url);
102
103 73
        $this->addKeywordsField($document, $pageRecord);
104 73
        $this->addTagContentFields($document, $contentExtractor->getTagContent());
105
106 73
        return $document;
107
    }
108
109
    /**
110
     * Creates a Solr document with the basic / core fields set already.
111
     *
112
     * @throws DBALException
113
     */
114 21
    public function fromRecord(array $itemRecord, string $type, int $rootPageUid, string $accessRootLine): Document
115
    {
116
        /* @var Document $document */
117 21
        $document = GeneralUtility::makeInstance(Document::class);
118
119 21
        $site = $this->getSiteByPageId($rootPageUid);
120
121 21
        $documentId = $this->getDocumentId($type, $site->getRootPageId(), $itemRecord['uid']);
122
123
        // required fields
124 21
        $document->setField('id', $documentId);
125 21
        $document->setField('type', $type);
126 21
        $document->setField('appKey', 'EXT:solr');
127
128
        // site, siteHash
129 21
        $document->setField('site', $site->getDomain());
130 21
        $document->setField('siteHash', $site->getSiteHash());
131
132
        // uid, pid
133 21
        $document->setField('uid', $itemRecord['uid']);
134 21
        $document->setField('pid', $itemRecord['pid']);
135
136
        // variantId
137 21
        $variantId = $this->variantIdBuilder->buildFromTypeAndUid($type, $itemRecord['uid']);
138 21
        $document->setField('variantId', $variantId);
139
140
        // created, changed
141 21
        if (!empty($GLOBALS['TCA'][$type]['ctrl']['crdate'])) {
142 20
            $document->setField('created', $itemRecord[$GLOBALS['TCA'][$type]['ctrl']['crdate']]);
143
        }
144 21
        if (!empty($GLOBALS['TCA'][$type]['ctrl']['tstamp'])) {
145 20
            $document->setField('changed', $itemRecord[$GLOBALS['TCA'][$type]['ctrl']['tstamp']]);
146
        }
147
148
        // access, endtime
149 21
        $document->setField('access', $accessRootLine);
150 21
        if (!empty($GLOBALS['TCA'][$type]['ctrl']['enablecolumns']['endtime'])
151 21
            && $itemRecord[$GLOBALS['TCA'][$type]['ctrl']['enablecolumns']['endtime']] != 0
152
        ) {
153
            $document->setField('endtime', $itemRecord[$GLOBALS['TCA'][$type]['ctrl']['enablecolumns']['endtime']]);
154
        }
155
156 21
        return $document;
157
    }
158
159
    /**
160
     * @throws AspectNotFoundException
161
     */
162 69
    protected function getPageDocumentId(TypoScriptFrontendController $frontendController, string $accessGroups, string $mountPointParameter): string
163
    {
164 69
        return Util::getPageDocumentId($frontendController->id, $frontendController->type, Util::getLanguageUid(), $accessGroups, $mountPointParameter);
0 ignored issues
show
Bug introduced by
It seems like $frontendController->type can also be of type string; however, parameter $typeNum of ApacheSolrForTypo3\Solr\Util::getPageDocumentId() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

164
        return Util::getPageDocumentId($frontendController->id, /** @scrutinizer ignore-type */ $frontendController->type, Util::getLanguageUid(), $accessGroups, $mountPointParameter);
Loading history...
165
    }
166
167
    /**
168
     * @throws DBALException
169
     */
170 20
    protected function getDocumentId(string $type, int $rootPageId, int $recordUid): string
171
    {
172 20
        return Util::getDocumentId($type, $rootPageId, $recordUid);
173
    }
174
175
    /**
176
     * @throws DBALException
177
     */
178 89
    protected function getSiteByPageId(int $pageId): Site
179
    {
180 89
        $siteRepository = GeneralUtility::makeInstance(SiteRepository::class);
181 89
        return $siteRepository->getSiteByPageId($pageId);
182
    }
183
184
    /**
185
     * Returns extractor for given page content.
186
     */
187 69
    protected function getExtractorForPageContent(string $pageContent): Typo3PageContentExtractor
188
    {
189 69
        return GeneralUtility::makeInstance(Typo3PageContentExtractor::class, /** @scrutinizer ignore-type */ $pageContent);
190
    }
191
192
    /**
193
     * Builds the content for the rootline field.
194
     */
195 73
    protected function getRootLineFieldValue(int $pageId, string $mountPointParameter = ''): string
196
    {
197 73
        $rootline = (string)$pageId;
198 73
        if ($mountPointParameter !== '') {
199 2
            $rootline .= ',' . $mountPointParameter;
200
        }
201 73
        return $rootline;
202
    }
203
204
    /**
205
     * Returns a comma separated list of frontend user groups to use for the document ID.
206
     */
207 73
    protected function getDocumentIdGroups(Rootline $pageAccessRootline): string
208
    {
209 73
        $groups = $pageAccessRootline->getGroups();
210 73
        $groups = Rootline::cleanGroupArray($groups);
211
212 73
        if (empty($groups)) {
213
            $groups[] = 0;
214
        }
215
216 73
        return implode(',', $groups);
217
    }
218
219
    /**
220
     * Adds the access field to the document if needed.
221
     */
222 73
    protected function addAccessField(Document $document, Rootline $pageAccessRootline): void
223
    {
224 73
        $access = (string)$pageAccessRootline;
225 73
        if (trim($access) !== '') {
226 69
            $document->setField('access', $access);
227
        }
228
    }
229
230
    /**
231
     * Adds the endtime field value to the Document.
232
     */
233 73
    protected function addEndtimeField(Document $document, array $pageRecord): void
234
    {
235 73
        if (isset($pageRecord['endtime']) && $pageRecord['endtime'] > 0) {
236 1
            $document->setField('endtime', $pageRecord['endtime']);
237
        }
238
    }
239
240
    /**
241
     * Adds keywords, multi valued.
242
     */
243 73
    protected function addKeywordsField(Document $document, array $pageRecord): void
244
    {
245 73
        if (!isset($pageRecord['keywords'])) {
246 72
            return;
247
        }
248
249 1
        $keywords = array_unique(GeneralUtility::trimExplode(',', $pageRecord['keywords'], true));
250 1
        foreach ($keywords as $keyword) {
251 1
            $document->addField('keywords', $keyword);
252
        }
253
    }
254
255
    /**
256
     * Add content from several tags like headers, anchors, ...
257
     */
258 73
    protected function addTagContentFields(Document $document, array $tagContent = []): void
259
    {
260 73
        foreach ($tagContent as $fieldName => $fieldValue) {
261 1
            $document->setField($fieldName, $fieldValue);
262
        }
263
    }
264
}
265