Passed
Pull Request — master (#2809)
by
unknown
34:29
created

ConnectionManager::injectUnifiedConfiguration()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 4
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
namespace ApacheSolrForTypo3\Solr;
3
4
/*
5
 * This file is part of the TYPO3 CMS project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under
8
 * the terms of the GNU General Public License, either version 2
9
 * of the License, or any later version.
10
 *
11
 * For the full copyright and license information, please read the
12
 * LICENSE.txt file that was distributed with this source code.
13
 *
14
 * The TYPO3 project - inspiring people to share!
15
 */
16
17
use ApacheSolrForTypo3\Solr\Domain\Site\Site;
18
use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository;
19
use ApacheSolrForTypo3\Solr\System\Configuration\UnifiedConfiguration;
20
use ApacheSolrForTypo3\Solr\System\Records\Pages\PagesRepository as PagesRepositoryAtExtSolr;
21
use ApacheSolrForTypo3\Solr\System\Records\SystemLanguage\SystemLanguageRepository;
22
use ApacheSolrForTypo3\Solr\System\Solr\Node;
23
use ApacheSolrForTypo3\Solr\System\Solr\SolrConnection;
24
use InvalidArgumentException;
25
use TYPO3\CMS\Core\SingletonInterface;
26
use TYPO3\CMS\Core\Utility\GeneralUtility;
27
use function json_encode;
28
29
/**
30
 * ConnectionManager is responsible to create SolrConnection objects.
31
 *
32
 * @author Ingo Renner <[email protected]>
33
 * @copyright (c) 2010-2015 Ingo Renner <[email protected]>
34
 */
35
class ConnectionManager implements SingletonInterface
36
{
37
    /**
38
     * @var SolrConnection[]
39
     */
40
    protected static $connections = [];
41
42
    /**
43
     * @var SystemLanguageRepository
44
     */
45
    protected $systemLanguageRepository;
46
47
    /**
48
     * @var PagesRepositoryAtExtSolr
49
     */
50
    protected $pagesRepositoryAtExtSolr;
51
52
    /**
53
     * @var SiteRepository
54
     */
55
    protected $siteRepository;
56
57
    /**
58
     * @var UnifiedConfiguration
59
     */
60
    protected $unifiedConfiguration = null;
61
62
    /**
63
     * @param SystemLanguageRepository|null $systemLanguageRepository
64
     * @param PagesRepositoryAtExtSolr|null $pagesRepositoryAtExtSolr
65
     * @param SiteRepository|null $siteRepository
66
     */
67
    public function __construct(
68
        SystemLanguageRepository $systemLanguageRepository = null,
69
        PagesRepositoryAtExtSolr $pagesRepositoryAtExtSolr = null,
70
        SiteRepository $siteRepository = null
71
    ) {
72
        $this->systemLanguageRepository = $systemLanguageRepository ?? GeneralUtility::makeInstance(SystemLanguageRepository::class);
73 79
        $this->siteRepository           = $siteRepository ?? GeneralUtility::makeInstance(SiteRepository::class);
74
        $this->pagesRepositoryAtExtSolr = $pagesRepositoryAtExtSolr ?? GeneralUtility::makeInstance(PagesRepositoryAtExtSolr::class);
75
        $this->unifiedConfiguration = GeneralUtility::makeInstance(UnifiedConfiguration::class, 0);
76
    }
77
78
    /**
79 79
     * Inject the unified configuration
80 79
     *
81 79
     * @param UnifiedConfiguration $unifiedConfiguration
82 79
     * @return $this
83
     */
84
    public function injectUnifiedConfiguration(UnifiedConfiguration $unifiedConfiguration): ConnectionManager
85
    {
86
        $this->unifiedConfiguration = $unifiedConfiguration;
87
        return $this;
88
    }
89
90
    /**
91 66
     * Creates a solr connection for read and write endpoints
92
     *
93 66
     * @param array $readNodeConfiguration
94 66
     * @param array $writeNodeConfiguration
95 66
     * @return SolrConnection
96 66
     */
97 66
    public function getSolrConnectionForNodes(array $readNodeConfiguration, array $writeNodeConfiguration)
98
    {
99 66
        $connectionHash = md5(json_encode($readNodeConfiguration) .  json_encode($writeNodeConfiguration));
100
        if (!isset(self::$connections[$connectionHash])) {
101
            $readNode = Node::fromArray($readNodeConfiguration);
102
            $writeNode = Node::fromArray($writeNodeConfiguration);
103
            self::$connections[$connectionHash] = GeneralUtility::makeInstance(
104
                SolrConnection::class,
105
                $readNode,
106
                $writeNode,
107
                $this->unifiedConfiguration
108 66
            );
109
        }
110 66
        return self::$connections[$connectionHash];
111
    }
112
113
    /**
114 66
     * Creates a solr configuration from the configuration array and returns it.
115
     *
116
     * @param array $config The solr configuration array
117
     * @return SolrConnection
118
     * @throws InvalidArgumentException
119
     */
120
    public function getConnectionFromConfiguration(array $config)
121
    {
122
        if (empty($config['read']) && !empty($config['solrHost'])) {
123
            throw new InvalidArgumentException('Invalid registry data please re-initialize your solr connections');
124
        }
125
126 56
        return $this->getSolrConnectionForNodes($config['read'], $config['write']);
127
    }
128
129 56
    /**
130 55
     * Gets a Solr connection for a page ID.
131 55
     *
132 55
     * @param int $pageId A page ID.
133 55
     * @param int $language The language ID to get the connection for as the path may differ. Optional, defaults to 0.
134 3
     * @param string $mount Comma list of MountPoint parameters
135 2
     * @return SolrConnection A solr connection.
136 2
     * @throws NoSolrConnectionFoundException
137
     */
138
    public function getConnectionByPageId($pageId, $language = 0, $mount = '')
139
    {
140
        try {
141
            $site = $this->siteRepository->getSiteByPageId($pageId, $mount);
142
            $this->throwExceptionOnInvalidSite($site, 'No site for pageId ' . $pageId);
143
            $config = $site->getSolrConnectionConfiguration($language);
144
            $solrConnection = $this->getConnectionFromConfiguration($config);
145
            return $solrConnection;
146
        } catch (InvalidArgumentException $e) {
147
            $noSolrConnectionException = $this->buildNoConnectionExceptionForPageAndLanguage($pageId, $language);
148 13
            throw $noSolrConnectionException;
149
        }
150
    }
151 13
152 12
    /**
153 12
     * Gets a Solr connection for a root page ID.
154 12
     *
155 12
     * @param int $pageId A root page ID.
156 1
     * @param int $language The language ID to get the connection for as the path may differ. Optional, defaults to 0.
157
     * @return SolrConnection A solr connection.
158 1
     * @throws NoSolrConnectionFoundException
159 1
     */
160
    public function getConnectionByRootPageId($pageId, $language = 0)
161
    {
162
        try {
163
            $site = $this->siteRepository->getSiteByRootPageId($pageId);
164
            $this->throwExceptionOnInvalidSite($site, 'No site for pageId ' . $pageId);
165
            $config = $site->getSolrConnectionConfiguration($language);
166
            $solrConnection = $this->getConnectionFromConfiguration($config);
167
            return $solrConnection;
168
        } catch (InvalidArgumentException $e) {
169 4
            $noSolrConnectionException = $this->buildNoConnectionExceptionForPageAndLanguage($pageId, $language);
170
            throw $noSolrConnectionException;
171 4
        }
172 4
    }
173
174
    /**
175
     * Gets all connections found.
176
     *
177
     * @return SolrConnection[] An array of initialized ApacheSolrForTypo3\Solr\System\Solr\SolrConnection connections
178 4
     * @throws NoSolrConnectionFoundException
179
     */
180
    public function getAllConnections()
181
    {
182
        $solrConnections = [];
183
        foreach ($this->siteRepository->getAvailableSites() as $site) {
184
            foreach ($site->getAllSolrConnectionConfigurations() as $solrConfiguration) {
185
                $solrConnections[] = $this->getConnectionFromConfiguration($solrConfiguration);
186
            }
187
        }
188 16
189
        return $solrConnections;
190 16
    }
191
192 16
    /**
193 16
     * Gets all connections configured for a given site.
194
     *
195
     * @param Site $site A TYPO3 site
196 16
     * @return SolrConnection[] An array of Solr connection objects (ApacheSolrForTypo3\Solr\System\Solr\SolrConnection)
197
     * @throws NoSolrConnectionFoundException
198
     */
199
    public function getConnectionsBySite(Site $site)
200
    {
201
        $connections = [];
202
203
        foreach ($site->getAllSolrConnectionConfigurations() as $languageId => $solrConnectionConfiguration) {
204
            $connections[$languageId] = $this->getConnectionFromConfiguration($solrConnectionConfiguration);
205
        }
206
207
        return $connections;
208
    }
209
210
    /**
211
     * Creates a human readable label from the connections' configuration.
212
     *
213
     * @param array $connection Connection configuration
214
     * @return string Connection label
215
     */
216
    protected function buildConnectionLabel(array $connection): string
217
    {
218
        return $connection['rootPageTitle']
219
            . ' (pid: ' . $connection['rootPageUid']
220
            . ', language: ' . $this->systemLanguageRepository->findOneLanguageTitleByLanguageId($connection['language'])
221
            . ') - Read node: '
222
            . $connection['read']['host'] . ':'
223
            . $connection['read']['port']
224
            . $connection['read']['path']
225 3
            .' - Write node: '
226
            . $connection['write']['host'] . ':'
227 3
            . $connection['write']['port']
228 3
            . $connection['write']['path'];
229
    }
230 3
231 3
    /**
232
     * @param $pageId
233
     * @param $language
234
     * @return NoSolrConnectionFoundException
235
     */
236
    protected function buildNoConnectionExceptionForPageAndLanguage($pageId, $language): NoSolrConnectionFoundException
237
    {
238
        $message = 'Could not find a Solr connection for page [' . $pageId . '] and language [' . $language . '].';
239
        $noSolrConnectionException = $this->buildNoConnectionException($message);
240
241 57
        $noSolrConnectionException->setLanguageId($language);
242
        return $noSolrConnectionException;
243 57
    }
244 57
245
    /**
246
     * Throws a no connection exception when no site was passed.
247
     *
248
     * @param Site|null $site
249
     * @param $message
250
     * @throws NoSolrConnectionFoundException
251
     */
252
    protected function throwExceptionOnInvalidSite(?Site $site, string $message)
253
    {
254
        if (!is_null($site)) {
255 3
            return;
256
        }
257
258 3
        throw $this->buildNoConnectionException($message);
259 3
    }
260
261 3
    /**
262
     * Build a NoSolrConnectionFoundException with the passed message.
263 3
     * @param string $message
264
     * @return NoSolrConnectionFoundException
265 3
     */
266
    protected function buildNoConnectionException(string $message): NoSolrConnectionFoundException
267
    {
268
        /* @var NoSolrConnectionFoundException $noSolrConnectionException */
269
        $noSolrConnectionException = GeneralUtility::makeInstance(
270
            NoSolrConnectionFoundException::class,
271
            /** @scrutinizer ignore-type */
272
            $message,
273
            /** @scrutinizer ignore-type */
274
            1575396474
275
        );
276
        return $noSolrConnectionException;
277
    }
278
}
279