Passed
Pull Request — develop (#167)
by
unknown
20:25
created

PagesIndexer::fetchAccess()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 34
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 7

Importance

Changes 0
Metric Value
eloc 21
dl 0
loc 34
ccs 1
cts 1
cp 1
rs 8.6506
c 0
b 0
f 0
cc 7
nc 8
nop 2
crap 7
1
<?php
2
3
namespace Codappix\SearchCore\Domain\Index\TcaIndexer;
4
5
/*
6
 * Copyright (C) 2017  Daniel Siepmann <[email protected]>
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21
 * 02110-1301, USA.
22
 */
23
24
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
25
use Codappix\SearchCore\Connection\ConnectionInterface;
26
use Codappix\SearchCore\Domain\Index\TcaIndexer;
27
use TYPO3\CMS\Core\Utility\GeneralUtility;
28
use TYPO3\CMS\Core\Utility\RootlineUtility;
29
use TYPO3\CMS\Extbase\Object\ObjectManager;
30
31
/**
32
 * Specific indexer for Pages, will basically add content of page.
33
 */
34
class PagesIndexer extends TcaIndexer
35
{
36
    /**
37
     * @var TcaTableServiceInterface
38
     */
39
    protected $contentTableService;
40
41
    /**
42
     * @var \TYPO3\CMS\Core\Resource\FileRepository
43
     * @inject
44
     */
45
    protected $fileRepository;
46
47
    /**
48
     * @param TcaTableServiceInterface $tcaTableService
49
     * @param TcaTableServiceInterface $contentTableService
50
     * @param ConnectionInterface $connection
51 32
     * @param ConfigurationContainerInterface $configuration
52
     */
53
    public function __construct(
54
        TcaTableServiceInterface $tcaTableService,
55
        TcaTableServiceInterface $contentTableService,
56
        ConnectionInterface $connection,
57 32
        ConfigurationContainerInterface $configuration
58 32
    ) {
59 32
        parent::__construct($tcaTableService, $connection, $configuration);
60
        $this->contentTableService = $contentTableService;
61 8
    }
62
63 8
    /**
64
     * @param array $record
65 8
     */
66 8
    protected function prepareRecord(array &$record)
67 8
    {
68 8
        parent::prepareRecord($record);
69 8
70
        // Override access from parent rootline
71
        $record['search_access'] = $this->fetchAccess($record['uid'], (array)$record['search_access']);
72
73 8
        $possibleTitleFields = ['nav_title', 'tx_tqseo_pagetitle_rel', 'title'];
74 8
        foreach ($possibleTitleFields as $searchTitleField) {
75 8
            if (isset($record[$searchTitleField]) && trim($record[$searchTitleField])) {
76 8
                $record['search_title'] = trim($record[$searchTitleField]);
77 8
                break;
78
            }
79 8
        }
80
81 8
        $record['media'] = $this->fetchMediaForPage($record['uid']);
82
        $content = $this->fetchContentForPage($record['uid']);
83 8
        if ($content !== []) {
84
            $record['content'] = $content['content'];
85
            $record['media'] = array_values(array_unique(array_merge($record['media'], $content['images'])));
86
        }
87
    }
88
89
    /**
90
     * @param integer $uid
91
     * @return array
92
     */
93 8
    protected function fetchContentForPage(int $uid): array
94 8
    {
95 8
        if ($this->contentTableService instanceof TcaTableService) {
96 8
            $queryBuilder = $this->contentTableService->getQuery();
97 8
            $queryBuilder->andWhere(
98
                $queryBuilder->expr()->eq(
99
                    $this->contentTableService->getTableName() . '.pid',
100
                    $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
101 8
                )
102
            );
103
            $contentElements = $queryBuilder->execute()->fetchAll();
104
        } else {
105
            $contentElements = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
106 8
                $this->contentTableService->getFields(),
0 ignored issues
show
Bug introduced by
The method getFields() does not exist on Codappix\SearchCore\Doma...caTableServiceInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Codappix\SearchCore\Doma...caTableServiceInterface. ( Ignorable by Annotation )

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

106
                $this->contentTableService->/** @scrutinizer ignore-call */ 
107
                                            getFields(),
Loading history...
107 8
                $this->contentTableService->getTableClause(),
108 8
                $this->contentTableService->getWhereClause() .
0 ignored issues
show
Bug introduced by
The method getWhereClause() does not exist on Codappix\SearchCore\Doma...caTableServiceInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Codappix\SearchCore\Doma...caTableServiceInterface. ( Ignorable by Annotation )

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

108
                $this->contentTableService->/** @scrutinizer ignore-call */ 
109
                                            getWhereClause() .
Loading history...
109 8
                sprintf(' AND %s.pid = %u', $this->contentTableService->getTableName(), $uid)
110 2
            );
111 2
        }
112 2
113
        if ($contentElements === null) {
114 2
            $this->logger->debug('No content for page ' . $uid);
115
            return [];
116
        }
117
118
        $this->logger->debug('Fetched content for page ' . $uid);
119
        $images = [];
120
        $content = [];
121 8
        foreach ($contentElements as $contentElement) {
122 8
            $images = array_merge(
123
                $images,
124
                $this->getContentElementImages($contentElement['uid'])
125
            );
126 2
            $content[] = $this->getContentFromContentElement($contentElement);
127
        }
128 2
129
        return [
130
            // Remove Tags.
131 8
            // Interpret escaped new lines and special chars.
132
            // Trim, e.g. trailing or leading new lines.
133 8
            'content' => trim(stripcslashes(strip_tags(implode(' ', $content)))),
134
            'images' => $images,
135
        ];
136 8
    }
137
138 8
    /**
139 8
     * @param integer $uidOfContentElement
140
     * @return array
141 8
     */
142
    protected function getContentElementImages(int $uidOfContentElement): array
143
    {
144
        return $this->fetchSysFileReferenceUids($uidOfContentElement, 'tt_content', 'image');
145 8
    }
146
147
    /**
148 2
     * @param integer $uid
149
     * @return array
150 2
     */
151
    protected function fetchMediaForPage(int $uid): array
152 2
    {
153 2
        return $this->fetchSysFileReferenceUids($uid, 'pages', 'media');
154 2
    }
155 2
156
    /**
157 2
     * @param integer $uid
158 2
     * @param array $pageAccess
159 2
     * @return array
160
     */
161
    protected function fetchAccess(int $uid, array $pageAccess): array
162
    {
163 2
        try {
164
            $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
165
            $rootline = $objectManager->get(RootlineUtility::class, $uid)->get();
166
        } catch (\RuntimeException $e) {
167
            $this->logger->notice(
168
                sprintf('Could not fetch rootline for page %u, because: %s', $uid, $e->getMessage()),
169
                [$pageAccess, $e]
170
            );
171
            return $pageAccess;
172
        }
173
174
        $access = [$pageAccess];
175
        $extended = false;
176
        foreach ($rootline as $pageInRootLine) {
177
            if ($pageInRootLine['extendToSubpages'] && (!empty($pageInRootLine['fe_group']))) {
178
                $extended = true;
179
                $access[] = GeneralUtility::intExplode(
180
                    ',',
181
                    $pageInRootLine['fe_group'],
182
                    true
183
                );
184
            }
185
        }
186
187
        // Return combined rootline extended access and return unique id's
188
        $access = array_unique(array_merge(...$access));
189
190
        // Remove public value if fe_group is extended to this page
191
        if ($extended && ($key = array_search(0, $access, true)) !== false) {
192
            unset($access[$key]);
193
        }
194
        return array_values($access);
195
    }
196
197
    /**
198
     * @param integer $uid
199
     * @param string $tablename
200
     * @param string $fieldname
201
     * @return array
202
     */
203
    protected function fetchSysFileReferenceUids(int $uid, string $tablename, string $fieldname): array
204
    {
205
        $imageRelationUids = [];
206
        $imageRelations = $this->fileRepository->findByRelation($tablename, $fieldname, $uid);
207
208
        foreach ($imageRelations as $relation) {
209
            $imageRelationUids[] = $relation->getUid();
210
        }
211
212
        return $imageRelationUids;
213
    }
214
215
    /**
216
     * @param array $contentElement
217
     * @return string
218
     */
219
    protected function getContentFromContentElement(array $contentElement): string
220
    {
221
        $content = '';
222
223
        $fieldsWithContent = GeneralUtility::trimExplode(
224
            ',',
225
            $this->configuration->get('indexing.' . $this->identifier . '.contentFields'),
226
            true
227
        );
228
        foreach ($fieldsWithContent as $fieldWithContent) {
229
            if (isset($contentElement[$fieldWithContent]) && trim($contentElement[$fieldWithContent])) {
230
                $content .= trim($contentElement[$fieldWithContent]) . ' ';
231
            }
232
        }
233
234
        return trim($content);
235
    }
236
}
237