Failed Conditions
Push — task/2976_TYPO3.11_compatibili... ( 772e40...ecf396 )
by Rafael
23:49
created

getConnectionFromConfiguration()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 3.1406

Importance

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