Passed
Push — master ( cc3f84...4a930e )
by Timo
23:43
created

SolrConnection::setClient()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
namespace ApacheSolrForTypo3\Solr\System\Solr;
3
4
/***************************************************************
5
 *  Copyright notice
6
 *
7
 *  (c) 2009-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\System\Configuration\TypoScriptConfiguration;
28
use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager;
29
use ApacheSolrForTypo3\Solr\System\Solr\Parser\SchemaParser;
30
use ApacheSolrForTypo3\Solr\System\Solr\Parser\StopWordParser;
31
use ApacheSolrForTypo3\Solr\System\Solr\Parser\SynonymParser;
32
use ApacheSolrForTypo3\Solr\System\Solr\Service\AbstractSolrService;
33
use ApacheSolrForTypo3\Solr\System\Solr\Service\SolrAdminService;
34
use ApacheSolrForTypo3\Solr\System\Solr\Service\SolrReadService;
35
use ApacheSolrForTypo3\Solr\System\Solr\Service\SolrWriteService;
36
use ApacheSolrForTypo3\Solr\Util;
37
use Solarium\Client;
38
use Solarium\Core\Client\Endpoint;
39
use TYPO3\CMS\Core\Utility\GeneralUtility;
40
41
/**
42
 * Solr Service Access
43
 *
44
 * @author Ingo Renner <[email protected]>
45
 */
46
class SolrConnection
47
{
48
    /**
49
     * @var SolrAdminService
50
     */
51
    protected $adminService;
52
53
    /**
54
     * @var SolrReadService
55
     */
56
    protected $readService;
57
58
    /**
59
     * @var SolrWriteService
60
     */
61
    protected $writeService;
62
63
    /**
64
     * @var TypoScriptConfiguration
65
     */
66
    protected $configuration;
67
68
    /**
69
     * @var SynonymParser
70
     */
71
    protected $synonymParser = null;
72
73
    /**
74
     * @var StopWordParser
75
     */
76
    protected $stopWordParser = null;
77
78
    /**
79
     * @var SchemaParser
80
     */
81
    protected $schemaParser = null;
82
83
    /**
84
     * @var string
85
     */
86
    protected $host = '';
87
88
    /**
89
     * @var string
90
     */
91
    protected $port = '8983';
92
93
    /**
94
     * @var string
95
     */
96
    protected $path = '/solr/';
97
98
    /**
99
     * @var string
100
     */
101
    protected $core = '';
102
103
    /**
104
     * @var string
105
     */
106
    protected $scheme = 'http';
107
108
    /**
109
     * @var string
110
     */
111
    protected $username = '';
112
113
    /**
114
     * @var string
115
     */
116
    protected $password = '';
117
118
    /**
119
     * @var SolrLogManager
120
     */
121
    protected $logger = null;
122
123
    /**
124
     * @var array
125
     */
126
    protected $clients = [];
127
128
    /**
129
     * Constructor
130
     *
131
     * @param string $host Solr host
132
     * @param string $port Solr port
133
     * @param string $path Solr path
134
     * @param string $scheme Scheme, defaults to http, can be https
135
     * @param string $username the username that should be used to authenticate
136
     * @param string $password the password that should be used to authenticate
137
     * @param TypoScriptConfiguration $typoScriptConfiguration
138
     * @param SynonymParser $synonymParser
139
     * @param StopWordParser $stopWordParser
140
     * @param SchemaParser $schemaParser
141
     * @param SolrLogManager $logManager
142
     */
143 118
    public function __construct(
144
        $host = '',
145
        $port = '8983',
146
        $path = '/solr/',
147
        $scheme = 'http',
148
        $username = '',
149
        $password = '',
150
        TypoScriptConfiguration $typoScriptConfiguration = null,
151
        SynonymParser $synonymParser = null,
152
        StopWordParser $stopWordParser = null,
153
        SchemaParser $schemaParser = null,
154
        SolrLogManager $logManager = null
155
    ) {
156 118
        $this->host = $host;
157 118
        $this->port = $port;
158 118
        $this->path = $this->getCoreBasePath($path);
159 118
        $this->core = $this->getCoreName($path);
160
161 118
        $this->scheme = $scheme;
162 118
        $this->username = $username;
163 118
        $this->password = $password;
164 118
        $this->configuration = $typoScriptConfiguration ?? Util::getSolrConfiguration();
165 118
        $this->synonymParser = $synonymParser;
166 118
        $this->stopWordParser = $stopWordParser;
167 118
        $this->schemaParser = $schemaParser;
168 118
        $this->logger = $logManager;
169 118
    }
170
171
    /**
172
     * Returns the core name from the configured path without the core name.
173
     *
174
     * @return string
175
     */
176 118
    protected function getCoreBasePath($path)
177
    {
178 118
        $pathWithoutLeadingAndTrailingSlashes = trim(trim($path), "/");
179 118
        $pathWithoutLastSegment = substr($pathWithoutLeadingAndTrailingSlashes, 0, strrpos($pathWithoutLeadingAndTrailingSlashes, "/"));
180 118
        return '/' . $pathWithoutLastSegment . '/';
181
    }
182
183
    /**
184
     * Returns the core name from the configured path.
185
     *
186
     * @return string
187
     */
188 118
    protected function getCoreName($path)
189
    {
190 118
        $paths = explode('/', trim($path, '/'));
191 118
        return (string)array_pop($paths);
192
    }
193
194
    /**
195
     * @return SolrAdminService
196
     */
197 8
    public function getAdminService()
198
    {
199 8
        if ($this->adminService === null) {
200 8
            $this->adminService = $this->buildAdminService();
201
        }
202
203 8
        return $this->adminService;
204
    }
205
206
    /**
207
     * @return SolrAdminService
208
     */
209 8
    protected function buildAdminService()
210
    {
211 8
        $client = $this->getClient('admin');
212 8
        $this->initializeClient($client);
213 8
        return GeneralUtility::makeInstance(SolrAdminService::class, $client, $this->configuration, $this->logger, $this->synonymParser, $this->stopWordParser, $this->schemaParser);
214
    }
215
216
    /**
217
     * @return SolrReadService
218
     */
219 57
    public function getReadService()
220
    {
221 57
        if ($this->readService === null) {
222 57
            $this->readService = $this->buildReadService();
223
        }
224
225 56
        return $this->readService;
226
    }
227
228
    /**
229
     * @return SolrReadService
230
     */
231 57
    protected function buildReadService()
232
    {
233 57
        $client = $this->getClient('read');
234 56
        $this->initializeClient($client);
235 56
        return GeneralUtility::makeInstance(SolrReadService::class, $client);
236
    }
237
238
    /**
239
     * @return SolrWriteService
240
     */
241 90
    public function getWriteService()
242
    {
243 90
        if ($this->writeService === null) {
244 90
            $this->writeService = $this->buildWriteService();
245
        }
246
247 90
        return $this->writeService;
248
    }
249
250
    /**
251
     * @return SolrWriteService
252
     */
253 90
    protected function buildWriteService()
254
    {
255 90
        $endpointKey = 'write';
256 90
        $client = $this->getClient($endpointKey);
257 90
        $this->initializeClient($client);
258 90
        return GeneralUtility::makeInstance(SolrWriteService::class, $client);
259
    }
260
261
    /**
262
     * @param Client $client
263
     * @return Client
264
     */
265 108
    protected function initializeClient(Client $client) {
266 108
        if (trim($this->username) === '') {
267 107
            return $client;
268
        }
269
270 1
        $this->setAuthenticationOnAllEndpoints($client);
271
272 1
        return $client;
273
    }
274
275
    /**
276
     * @param Client $client
277
     */
278 1
    protected function setAuthenticationOnAllEndpoints(Client $client)
279
    {
280 1
        foreach ($client->getEndpoints() as $endpoint) {
281 1
            $endpoint->setAuthentication($this->username, $this->password);
282
        }
283 1
    }
284
285
    /**
286
     * Creates a string representation of the Solr connection. Specifically
287
     * will return the Solr URL.
288
     *
289
     * @return string The Solr URL.
290
     */
291 11
    public function __toString()
292
    {
293 11
        return $this->scheme . '://' . $this->host . ':' . $this->port . $this->path . $this->core . '/';
294
    }
295
296
    /**
297
     * @param string $key
298
     * @param int $timeout
299
     * @return array
300
     */
301 106
    protected function getSolrClientOptions($key = 'read', $timeout = 5):array
302
    {
303 106
        return ['host' => $this->host, 'port' => $this->port, 'scheme' => $this->scheme, 'path' => $this->path, 'core' => $this->core, 'key' => $key, 'timeout' => $timeout];
304
    }
305
306
    /**
307
     * @param string $endpointKey
308
     * @return Client
309
     */
310 109
    protected function getClient($endpointKey): Client
311
    {
312 109
        if($this->clients[$endpointKey]) {
313 2
            return $this->clients[$endpointKey];
314
        }
315
316 107
        $client = new Client(['adapter' => 'Solarium\Core\Client\Adapter\Guzzle']);
317
318 107
        $client->clearEndpoints();
319
320 107
        $this->checkIfRequiredPropertyIsSet($this->scheme, 'scheme');
321 106
        $this->checkIfRequiredPropertyIsSet($this->host, 'host');
322 106
        $this->checkIfRequiredPropertyIsSet($this->port, 'port');
323 106
        $this->checkIfRequiredPropertyIsSet($this->path, 'path');
324 106
        $this->checkIfRequiredPropertyIsSet($this->core, 'core');
325
326 106
        $newEndpointOptions = $this->getSolrClientOptions($endpointKey, $this->configuration->getSolrTimeout());
327 106
        $client->createEndpoint($newEndpointOptions, true);
328
329 106
        $this->clients[$endpointKey] = $client;
330 106
        return $client;
331
    }
332
333
    /**
334
     * @param Client $client
335
     * @param string $endpointKey
336
     */
337 2
    public function setClient(Client $client, $endpointKey = 'read')
338
    {
339 2
        $this->clients[$endpointKey] = $client;
340 2
    }
341
342
    /**
343
     * @param mixed $property
344
     * @param string $name
345
     * @throws |UnexpectedValueException
346
     */
347 107
    protected function checkIfRequiredPropertyIsSet($property, $name)
348
    {
349 107
        if (empty($property)) {
350 1
            throw new \UnexpectedValueException('Required solr connection property ' . $name. ' is missing.');
351
        }
352 106
    }
353
354
}
355