Completed
Push — master ( 5919d7...94bd1b )
by Rafael
05:28
created

Builder::fromRecord()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 44
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 44
ccs 11
cts 11
cp 1
rs 8.439
c 0
b 0
f 0
cc 5
eloc 22
nc 8
nop 4
crap 5
1
<?php
2
namespace ApacheSolrForTypo3\Solr\Domain\Search\ApacheSolrDocument;
3
4
/***************************************************************
5
 *  Copyright notice
6
 *
7
 *  (c) 2017 Timo Hund <[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 Apache_Solr_Document;
28
use ApacheSolrForTypo3\Solr\Access\Rootline;
29
use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository;
30
use ApacheSolrForTypo3\Solr\Domain\Variants\IdBuilder;
31
use ApacheSolrForTypo3\Solr\Site;
32
use ApacheSolrForTypo3\Solr\Typo3PageContentExtractor;
33
use ApacheSolrForTypo3\Solr\Util;
34
use TYPO3\CMS\Core\Utility\GeneralUtility;
35
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
36
37
/**
38
 * Builder class to build an ApacheSolrDocument
39
 *
40
 * Responsible to build Apache_Solr_Documents
41
 *
42
 * @author Timo Hund <[email protected]>
43
 */
44
class Builder
45
{
46
    /**
47
     * @var IdBuilder
48
     */
49
    protected $variantIdBuilder;
50
51
    /**
52
     * Builder constructor.
53
     * @param IdBuilder|null $variantIdBuilder
54
     */
55 59
    public function __construct(IdBuilder $variantIdBuilder = null)
56
    {
57 59
        $this->variantIdBuilder = is_null($variantIdBuilder) ? GeneralUtility::makeInstance(IdBuilder::class) : $variantIdBuilder;
58 59
    }
59
60
    /**
61
     * This method can be used to build an Apache_Solr_Document from a TYPO3 page.
62
     *
63
     * @param TypoScriptFrontendController $page
64
     * @param string $url
65
     * @param Rootline $pageAccessRootline
66
     * @param string $mountPointParameter
67
     * @return Apache_Solr_Document|object
68
     */
69 59
    public function fromPage(TypoScriptFrontendController $page, $url, Rootline $pageAccessRootline, $mountPointParameter): \Apache_Solr_Document
70
    {
71
        /* @var $document \Apache_Solr_Document */
72 59
        $document = GeneralUtility::makeInstance(Apache_Solr_Document::class);
73 59
        $site = $this->getSiteByPageId($page->id);
74 59
        $pageRecord = $page->page;
75
76 59
        $accessGroups = $this->getDocumentIdGroups($pageAccessRootline);
77 59
        $documentId = $this->getPageDocumentId($page, $accessGroups, $mountPointParameter);
78
79 59
        $document->setField('id', $documentId);
80 59
        $document->setField('site', $site->getDomain());
81 59
        $document->setField('siteHash', $site->getSiteHash());
82 59
        $document->setField('appKey', 'EXT:solr');
83 59
        $document->setField('type', 'pages');
84
85
        // system fields
86 59
        $document->setField('uid', $page->id);
87 59
        $document->setField('pid', $pageRecord['pid']);
88
89
        // variantId
90 59
        $variantId = $this->variantIdBuilder->buildFromTypeAndUid('pages', $page->id);
91 59
        $document->setField('variantId', $variantId);
92
93 59
        $document->setField('typeNum', $page->type);
94 59
        $document->setField('created', $pageRecord['crdate']);
95 59
        $document->setField('changed', $pageRecord['SYS_LASTCHANGED']);
96
97 59
        $rootline = $this->getRootLineFieldValue($page->id, $mountPointParameter);
98 59
        $document->setField('rootline', $rootline);
99
100
        // access
101 59
        $this->addAccessField($document, $pageAccessRootline);
102 59
        $this->addEndtimeField($document, $pageRecord);
103
104
        // content
105 59
        $contentExtractor = $this->getExtractorForPageContent($page->content);
106 59
        $document->setField('title', $contentExtractor->getPageTitle());
107 59
        $document->setField('subTitle', $pageRecord['subtitle']);
108 59
        $document->setField('navTitle', $pageRecord['nav_title']);
109 59
        $document->setField('author', $pageRecord['author']);
110 59
        $document->setField('description', $pageRecord['description']);
111 59
        $document->setField('abstract', $pageRecord['abstract']);
112 59
        $document->setField('content', $contentExtractor->getIndexableContent());
113 59
        $document->setField('url', $url);
114
115 59
        $this->addKeywordsField($document, $pageRecord);
116 59
        $this->addTagContentFields($document, $contentExtractor->getTagContent());
117
118 59
        return $document;
119
    }
120
121
122
    /**
123
     * Creates a Solr document with the basic / core fields set already.
124
     *
125
     * @param array $itemRecord
126
     * @param string $type
127 55
     * @param int $rootPageUid
128
     * @param string $accessRootLine
129 55
     * @return Apache_Solr_Document
130
     */
131
    public function fromRecord(array $itemRecord, string $type, int $rootPageUid, string $accessRootLine): \Apache_Solr_Document
132
    {
133
        /* @var $document Apache_Solr_Document */
134
        $document = GeneralUtility::makeInstance(Apache_Solr_Document::class);
135
136 55
        $site = $this->getSiteByPageId($rootPageUid);
137
138 55
        $documentId = $this->getDocumentId($type, $site->getRootPageId(), $itemRecord['uid']);
139 55
140
        // required fields
141
        $document->setField('id', $documentId);
142
        $document->setField('type', $type);
143
        $document->setField('appKey', 'EXT:solr');
144
145
        // site, siteHash
146 55
        $document->setField('site', $site->getDomain());
147
        $document->setField('siteHash', $site->getSiteHash());
148 55
149
        // uid, pid
150
        $document->setField('uid', $itemRecord['uid']);
151
        $document->setField('pid', $itemRecord['pid']);
152
153
        // variantId
154
        $variantId = $this->variantIdBuilder->buildFromTypeAndUid($type, $itemRecord['uid']);
155
        $document->setField('variantId', $variantId);
156
157
        // created, changed
158 59
        if (!empty($GLOBALS['TCA'][$type]['ctrl']['crdate'])) {
159
            $document->setField('created', $itemRecord[$GLOBALS['TCA'][$type]['ctrl']['crdate']]);
160 59
        }
161 59
        if (!empty($GLOBALS['TCA'][$type]['ctrl']['tstamp'])) {
162 47
            $document->setField('changed', $itemRecord[$GLOBALS['TCA'][$type]['ctrl']['tstamp']]);
163
        }
164 59
165
        // access, endtime
166
        $document->setField('access', $accessRootLine);
167
        if (!empty($GLOBALS['TCA'][$type]['ctrl']['enablecolumns']['endtime'])
168
            && $itemRecord[$GLOBALS['TCA'][$type]['ctrl']['enablecolumns']['endtime']] != 0
169
        ) {
170
            $document->setField('endtime', $itemRecord[$GLOBALS['TCA'][$type]['ctrl']['enablecolumns']['endtime']]);
171
        }
172
173
        return $document;
174 59
    }
175
176 59
    /**
177 59
     * @param TypoScriptFrontendController  $page
178
     * @param string $accessGroups
179 59
     * @param string $mountPointParameter
180 13
     * @return string
181
     */
182
    protected function getPageDocumentId(TypoScriptFrontendController $page, string $accessGroups, string $mountPointParameter): string
183 59
    {
184
        return Util::getPageDocumentId($page->id, $page->type, $page->sys_language_uid, $accessGroups, $mountPointParameter);
185 59
    }
186
187
    /**
188
     * @param string $type
189
     * @param int $rootPageId
190
     * @param int $recordUid
191
     * @return string
192
     */
193
    protected function getDocumentId(string $type, int $rootPageId, int $recordUid): string
194 59
    {
195
        return Util::getDocumentId($type, $rootPageId, $recordUid);
196 59
    }
197 59
198 44
    /**
199
     * @param integer $pageId
200 59
     * @return Site
201
     */
202
    protected function getSiteByPageId($pageId)
203
    {
204
        $siteRepository = GeneralUtility::makeInstance(SiteRepository::class);
205
        return $siteRepository->getSiteByPageId($pageId);
206
    }
207
208 59
    /**
209
     * @param string $pageContent
210 59
     * @return Typo3PageContentExtractor
211 1
     */
212
    protected function getExtractorForPageContent($pageContent)
213 59
    {
214
        return GeneralUtility::makeInstance(Typo3PageContentExtractor::class, $pageContent);
215
    }
216
217
    /**
218
     * Builds the content for the rootline field.
219
     *
220
     * @param int $pageId
221 59
     * @param string $mountPointParameter
222
     * @return string
223 59
     */
224 58
    protected function getRootLineFieldValue($pageId, $mountPointParameter)
225
    {
226
        $rootline = $pageId;
227 1
        if ($mountPointParameter !== '') {
228 1
            $rootline .= ',' . $mountPointParameter;
229 1
        }
230
        return $rootline;
231 1
    }
232
233
    /**
234
     * Gets a comma separated list of frontend user groups to use for the
235
     * document ID.
236
     *
237
     * @param Rootline $pageAccessRootline
238
     * @return string A comma separated list of frontend user groups.
239 59
     */
240
    protected function getDocumentIdGroups(Rootline $pageAccessRootline)
241 59
    {
242 1
        $groups = $pageAccessRootline->getGroups();
243
        $groups = Rootline::cleanGroupArray($groups);
244 59
245
        if (empty($groups)) {
246
            $groups[] = 0;
247
        }
248
249
        $groups = implode(',', $groups);
250
251
        return $groups;
252
    }
253
254
    /**
255
     * Adds the access field to the document if needed.
256
     *
257
     * @param \Apache_Solr_Document $document
258
     * @param Rootline $pageAccessRootline
259
     */
260
    protected function addAccessField(\Apache_Solr_Document $document, Rootline $pageAccessRootline)
261
    {
262
        $access = (string)$pageAccessRootline;
263
        if (trim($access) !== '') {
264
            $document->setField('access', $access);
265
        }
266
    }
267
268
    /**
269
     * Adds the endtime field value to the Apache_Solr_Document.
270
     *
271
     * @param \Apache_Solr_Document $document
272
     * @param array $pageRecord
273
     */
274
    protected function addEndtimeField(\Apache_Solr_Document  $document, $pageRecord)
275
    {
276
        if ($pageRecord['endtime']) {
277
            $document->setField('endtime', $pageRecord['endtime']);
278
        }
279
    }
280
281
    /**
282
     * Adds keywords, multi valued.
283
     *
284
     * @param \Apache_Solr_Document $document
285
     * @param array $pageRecord
286
     */
287
    protected function addKeywordsField(\Apache_Solr_Document $document, $pageRecord)
288
    {
289
        if (!isset($pageRecord['keywords'])) {
290
            return;
291
        }
292
293
        $keywords = array_unique(GeneralUtility::trimExplode(',', $pageRecord['keywords'], true));
294
        foreach ($keywords as $keyword) {
295
            $document->addField('keywords', $keyword);
296
        }
297
    }
298
299
    /**
300
     * Add content from several tags like headers, anchors, ...
301
     *
302
     * @param \Apache_Solr_Document $document
303
     * @param array $tagContent
304
     */
305
    protected function addTagContentFields(\Apache_Solr_Document  $document, $tagContent = [])
306
    {
307
        foreach ($tagContent as $fieldName => $fieldValue) {
308
            $document->setField($fieldName, $fieldValue);
309
        }
310
    }
311
}
312