Passed
Push — master ( e1aede...36be10 )
by Timo
33:39 queued 01:53
created

ConnectionManager::throwExceptionOnInvalidSite()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

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 2
nc 2
nop 2
crap 2.0625
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 InvalidArgumentException;
34
use TYPO3\CMS\Core\Registry;
35
use TYPO3\CMS\Core\SingletonInterface;
36
use TYPO3\CMS\Core\Utility\GeneralUtility;
37
use function json_encode;
38
39
/**
40
 * ConnectionManager is responsible to create SolrConnection objects.
41
 *
42
 * @author Ingo Renner <[email protected]>
43
 */
44
class ConnectionManager implements SingletonInterface
45
{
46
47
    /**
48
     * @var array
49
     */
50
    protected static $connections = [];
51
52
    /**
53
     * @var SystemLanguageRepository
54
     */
55
    protected $systemLanguageRepository;
56
57
    /**
58
     * @var PagesRepositoryAtExtSolr
59
     */
60
    protected $pagesRepositoryAtExtSolr;
61
62
    /**
63
     * @var SiteRepository
64
     */
65
    protected $siteRepository;
66
67
68
    /**
69
     * @param SystemLanguageRepository $systemLanguageRepository
70
     * @param PagesRepositoryAtExtSolr|null $pagesRepositoryAtExtSolr
71
     * @param SiteRepository $siteRepository
72
     */
73 118
    public function __construct(
74
        SystemLanguageRepository $systemLanguageRepository = null,
75
        PagesRepositoryAtExtSolr $pagesRepositoryAtExtSolr = null,
76
        SiteRepository $siteRepository = null
77
    )
78
    {
79 118
        $this->systemLanguageRepository = $systemLanguageRepository ?? GeneralUtility::makeInstance(SystemLanguageRepository::class);
80 118
        $this->siteRepository           = $siteRepository ?? GeneralUtility::makeInstance(SiteRepository::class);
81 118
        $this->pagesRepositoryAtExtSolr = $pagesRepositoryAtExtSolr ?? GeneralUtility::makeInstance(PagesRepositoryAtExtSolr::class);
82 118
    }
83
84
    /**
85
     * Creates a solr connection for read and write endpoints
86
     *
87
     * @param array $readNodeConfiguration
88
     * @param array $writeNodeConfiguration
89
     * @return SolrConnection|object
90
     */
91 105
    public function getSolrConnectionForNodes(array $readNodeConfiguration, array $writeNodeConfiguration)
92
    {
93 105
        $connectionHash = md5(json_encode($readNodeConfiguration) .  json_encode($writeNodeConfiguration));
94 105
        if (!isset(self::$connections[$connectionHash])) {
95 105
            $readNode = Node::fromArray($readNodeConfiguration);
96 105
            $writeNode = Node::fromArray($writeNodeConfiguration);
97 105
            self::$connections[$connectionHash] = GeneralUtility::makeInstance(SolrConnection::class, $readNode, $writeNode);
0 ignored issues
show
Bug introduced by
$readNode of type ApacheSolrForTypo3\Solr\System\Solr\Node is incompatible with the type array|array<mixed,mixed> expected by parameter $constructorArguments of TYPO3\CMS\Core\Utility\G...Utility::makeInstance(). ( Ignorable by Annotation )

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

97
            self::$connections[$connectionHash] = GeneralUtility::makeInstance(SolrConnection::class, /** @scrutinizer ignore-type */ $readNode, $writeNode);
Loading history...
98
        }
99 105
        return self::$connections[$connectionHash];
100
    }
101
102
    /**
103
     * Creates a solr configuration from the configuration array and returns it.
104
     *
105
     * @param array $config The solr configuration array
106
     * @return SolrConnection
107
     */
108 105
    public function getConnectionFromConfiguration(array $config)
109
    {
110 105
        if(empty($config['read']) && !empty($config['solrHost'])) {
111
            throw new InvalidArgumentException('Invalid registry data please re-initialize your solr connections');
112
        }
113
114 105
        return $this->getSolrConnectionForNodes($config['read'], $config['write']);
115
    }
116
117
    /**
118
     * Gets a Solr connection for a page ID.
119
     *
120
     * @param int $pageId A page ID.
121
     * @param int $language The language ID to get the connection for as the path may differ. Optional, defaults to 0.
122
     * @param string $mount Comma list of MountPoint parameters
123
     * @return SolrConnection A solr connection.
124
     * @throws NoSolrConnectionFoundException
125
     */
126 96
    public function getConnectionByPageId($pageId, $language = 0, $mount = '')
127
    {
128
        try {
129 96
            $site = $this->siteRepository->getSiteByPageId($pageId, $mount);
130 95
            $this->throwExceptionOnInvalidSite($site, 'No site for pageId ' . $pageId);
131 95
            $config = $site->getSolrConnectionConfiguration($language);
132 95
            $solrConnection = $this->getConnectionFromConfiguration($config);
133 95
            return $solrConnection;
134 2
        } catch(InvalidArgumentException $e) {
135 1
            $noSolrConnectionException = $this->buildNoConnectionExceptionForPageAndLanguage($pageId, $language);
136 1
            throw $noSolrConnectionException;
137
        }
138
    }
139
140
    /**
141
     * Gets a Solr connection for a root page ID.
142
     *
143
     * @param int $pageId A root page ID.
144
     * @param int $language The language ID to get the connection for as the path may differ. Optional, defaults to 0.
145
     * @return SolrConnection A solr connection.
146
     * @throws NoSolrConnectionFoundException
147
     */
148 13
    public function getConnectionByRootPageId($pageId, $language = 0)
149
    {
150
        try {
151 13
            $site = $this->siteRepository->getSiteByRootPageId($pageId);
152 12
            $this->throwExceptionOnInvalidSite($site, 'No site for pageId ' . $pageId);
153 12
            $config = $site->getSolrConnectionConfiguration($language);
154 12
            $solrConnection = $this->getConnectionFromConfiguration($config);
155 12
            return $solrConnection;
156 1
        } catch (InvalidArgumentException $e) {
157
            /* @var NoSolrConnectionFoundException $noSolrConnectionException */
158 1
            $noSolrConnectionException = $this->buildNoConnectionExceptionForPageAndLanguage($pageId, $language);
159 1
            throw $noSolrConnectionException;
160
        }
161
    }
162
163
    /**
164
     * Gets all connections found.
165
     *
166
     * @return SolrConnection[] An array of initialized ApacheSolrForTypo3\Solr\System\Solr\SolrConnection connections
167
     * @throws NoSolrConnectionFoundException
168
     */
169 4
    public function getAllConnections()
170
    {
171 4
        $solrConnections = [];
172 4
        foreach ($this->siteRepository->getAvailableSites() as $site) {
173
            foreach ($site->getAllSolrConnectionConfigurations() as $solrConfiguration) {
174
                $solrConnections[] = $this->getConnectionFromConfiguration($solrConfiguration);
175
            }
176
        }
177
178 4
        return $solrConnections;
179
    }
180
181
    /**
182
     * Gets all connections configured for a given site.
183
     *
184
     * @param Site $site A TYPO3 site
185
     * @return SolrConnection[] An array of Solr connection objects (ApacheSolrForTypo3\Solr\System\Solr\SolrConnection)
186
     * @throws NoSolrConnectionFoundException
187
     */
188 15
    public function getConnectionsBySite(Site $site)
189
    {
190 15
        $connections = [];
191
192 15
        foreach ($site->getAllSolrConnectionConfigurations() as $languageId => $solrConnectionConfiguration) {
193 15
            $connections[$languageId] = $this->getConnectionFromConfiguration($solrConnectionConfiguration);
194
        }
195
196 15
        return $connections;
197
    }
198
199
    /**
200
     * Creates a human readable label from the connections' configuration.
201
     *
202
     * @param array $connection Connection configuration
203
     * @return string Connection label
204
     */
205
    protected function buildConnectionLabel(array $connection)
206
    {
207
        return $connection['rootPageTitle']
208
            . ' (pid: ' . $connection['rootPageUid']
209
            . ', language: ' . $this->systemLanguageRepository->findOneLanguageTitleByLanguageId($connection['language'])
210
            . ') - Read node: '
211
            . $connection['read']['host'] . ':'
212
            . $connection['read']['port']
213
            . $connection['read']['path']
214
            .' - Write node: '
215
            . $connection['write']['host'] . ':'
216
            . $connection['write']['port']
217
            . $connection['write']['path'];
218
    }
219
220
    /**
221
     * @param $pageId
222
     * @param $language
223
     * @return NoSolrConnectionFoundException
224
     */
225 2
    protected function buildNoConnectionExceptionForPageAndLanguage($pageId, $language): NoSolrConnectionFoundException
226
    {
227 2
        $message = 'Could not find a Solr connection for page [' . $pageId . '] and language [' . $language . '].';
228 2
        $noSolrConnectionException = $this->buildNoConnectionException($message);
229
230 2
        $noSolrConnectionException->setLanguageId($language);
231 2
        return $noSolrConnectionException;
232
    }
233
234
    /**
235
     * Throws a no connection exception when no site was passed.
236
     *
237
     * @param Site|null $site
238
     * @param $message
239
     * @throws NoSolrConnectionFoundException
240
     */
241 97
    protected function throwExceptionOnInvalidSite(?Site $site, string $message)
242
    {
243 97
        if (!is_null($site)) {
244 97
            return;
245
        }
246
247
        throw $this->buildNoConnectionException($message);
248
    }
249
250
    /**
251
     * Build a NoSolrConnectionFoundException with the passed message.
252
     * @param string $message
253
     * @return NoSolrConnectionFoundException
254
     */
255 2
    protected function buildNoConnectionException(string $message): NoSolrConnectionFoundException
256
    {
257
        /* @var NoSolrConnectionFoundException $noSolrConnectionException */
258 2
        $noSolrConnectionException = GeneralUtility::makeInstance(
259 2
            NoSolrConnectionFoundException::class,
260
            /** @scrutinizer ignore-type */
261 2
            $message,
262
            /** @scrutinizer ignore-type */
263 2
            1575396474
264
        );
265 2
        return $noSolrConnectionException;
266
    }
267
}
268