Completed
Push — master ( 5919d7...94bd1b )
by Rafael
05:28
created

SolrAdminService::initializeStopWordsUrl()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 0
1
<?php
2
namespace ApacheSolrForTypo3\Solr\System\Solr\Service;
3
4
/***************************************************************
5
 *  Copyright notice
6
 *
7
 *  (c) 2009-2017 Timo Hund <[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 2 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\Schema\Schema;
33
use TYPO3\CMS\Core\Utility\GeneralUtility;
34
35
/**
36
 * Class SolrAdminService
37
 * @package ApacheSolrForTypo3\System\Solr\Service
38
 */
39
class SolrAdminService extends AbstractSolrService
40
{
41
    const PLUGINS_SERVLET = 'admin/plugins';
42
    const LUKE_SERVLET = 'admin/luke';
43
    const SYSTEM_SERVLET = 'admin/system';
44
    const CORES_SERVLET = 'admin/cores';
45
    const FILE_SERVLET = 'admin/file';
46
    const SCHEMA_SERVLET = 'schema';
47
    const SYNONYMS_SERVLET = 'schema/analysis/synonyms/';
48
    const STOPWORDS_SERVLET = 'schema/analysis/stopwords/';
49
50
    /**
51
     * Constructed servlet URL for plugin information
52
     *
53
     * @var string
54
     */
55
    protected $_pluginsUrl;
56
57
    /**
58
     * Constructed servlet URL for Luke
59
     *
60
     * @var string
61
     */
62
    protected $_lukeUrl;
63
64
    /**
65
     * @var array
66
     */
67
    protected $lukeData = [];
68
69
    /**
70
     * @var string
71
     */
72
    protected $_coresUrl;
73
74
75
    protected $systemData = null;
76
77
    protected $pluginsData = null;
78
79
    /**
80
     * @var string|null
81
     */
82
    protected $solrconfigName;
83
84
    /**
85
     * @var string
86
     */
87
    protected $_schemaUrl;
88
89
    /**
90
     * @var SchemaParser
91
     */
92
    protected $schemaParser = null;
93
94
    /**
95
     * @var Schema
96
     */
97
    protected $schema;
98
99
    /**
100
     * @var string
101
     */
102
    protected $_synonymsUrl;
103
104
    /**
105
     * @var string
106
     */
107
    protected $_stopWordsUrl;
108
109
    /**
110
     * @var SynonymParser
111
     */
112
    protected $synonymParser = null;
113
114
    /**
115
     * @var StopWordParser
116
     */
117
    protected $stopWordParser = null;
118
119
    /**
120
     * Constructor
121
     *
122
     * @param string $host Solr host
123
     * @param string $port Solr port
124
     * @param string $path Solr path
125
     * @param string $scheme Scheme, defaults to http, can be https
126
     * @param TypoScriptConfiguration $typoScriptConfiguration
127
     * @param SynonymParser $synonymParser
128
     * @param StopWordParser $stopWordParser
129
     * @param SchemaParser $schemaParser
130
     * @param SolrLogManager $logManager
131
     */
132
    public function __construct(
133
        $host = '',
134
        $port = '8983',
135
        $path = '/solr/',
136
        $scheme = 'http',
137
        TypoScriptConfiguration $typoScriptConfiguration = null,
138
        SolrLogManager $logManager = null,
139
        SynonymParser $synonymParser = null,
140
        StopWordParser $stopWordParser = null,
141
        SchemaParser $schemaParser = null
142
    )
143
    {
144
        parent::__construct($host, $port, $path, $scheme, $typoScriptConfiguration);
145
146
        $this->synonymParser = is_null($synonymParser) ? GeneralUtility::makeInstance(SynonymParser::class) : $synonymParser;
147
        $this->stopWordParser = is_null($stopWordParser) ? GeneralUtility::makeInstance(StopWordParser::class) : $stopWordParser;
148
        $this->schemaParser = is_null($schemaParser) ? GeneralUtility::makeInstance(SchemaParser::class) : $schemaParser;
149
    }
150
151
    protected function _initUrls()
152
    {
153
        parent::_initUrls();
154
        $this->_pluginsUrl = $this->_constructUrl(
155
            self::PLUGINS_SERVLET,
156
            ['wt' => self::SOLR_WRITER]
157
        );
158
        $this->_lukeUrl = $this->_constructUrl(
159
            self::LUKE_SERVLET,
160
            [
161
                'numTerms' => '0',
162
                'wt' => self::SOLR_WRITER
163
            ]
164
        );
165
166
        $this->_coresUrl =
167
            $this->_scheme . '://' .
168
            $this->_host . ':' .
169
            $this->_port .
170
            $this->getCoreBasePath() .
171
            self::CORES_SERVLET;
172
173
        $this->_schemaUrl = $this->_constructUrl(self::SCHEMA_SERVLET);
174
    }
175
176
177
    /**
178
     * Gets information about the plugins installed in Solr
179
     *
180
     * @return array A nested array of plugin data.
181
     */
182
    public function getPluginsInformation()
183
    {
184
        if (empty($this->pluginsData)) {
185
            $pluginsInformation = $this->_sendRawGet($this->_pluginsUrl);
186
187
            // access a random property to trigger response parsing
188
            $pluginsInformation->responseHeader;
189
            $this->pluginsData = $pluginsInformation;
190
        }
191
192
        return $this->pluginsData;
193
    }
194
195
    /**
196
     * get field meta data for the index
197
     *
198
     * @param int $numberOfTerms Number of top terms to fetch for each field
199
     * @return array
200
     */
201
    public function getFieldsMetaData($numberOfTerms = 0)
202
    {
203
        return $this->getLukeMetaData($numberOfTerms)->fields;
204
    }
205
206
    /**
207
     * Retrieves meta data about the index from the luke request handler
208
     *
209
     * @param int $numberOfTerms Number of top terms to fetch for each field
210
     * @return \Apache_Solr_Response Index meta data
211
     */
212
    public function getLukeMetaData($numberOfTerms = 0)
213
    {
214
        if (!isset($this->lukeData[$numberOfTerms])) {
215
            $lukeUrl = $this->_constructUrl(
216
                self::LUKE_SERVLET, ['numTerms' => $numberOfTerms, 'wt' => self::SOLR_WRITER, 'fl' => '*']
217
            );
218
219
            $this->lukeData[$numberOfTerms] = $this->_sendRawGet($lukeUrl);
220
        }
221
222
        return $this->lukeData[$numberOfTerms];
223
    }
224
225
    /**
226
     * Gets information about the Solr server
227
     *
228
     * @return array A nested array of system data.
229
     */
230
    public function getSystemInformation()
231
    {
232
        if (empty($this->systemData)) {
233
            $systemInformation = $this->system();
234
235
            // access a random property to trigger response parsing
236
            $systemInformation->responseHeader;
237
            $this->systemData = $systemInformation;
238
        }
239
240
        return $this->systemData;
241
    }
242
243
    /**
244
     * Gets the name of the solrconfig.xml file installed and in use on the Solr
245
     * server.
246
     *
247
     * @return string Name of the active solrconfig.xml
248
     */
249
    public function getSolrconfigName()
250
    {
251
        if (is_null($this->solrconfigName)) {
252
            $solrconfigXmlUrl = $this->_constructUrl(self::FILE_SERVLET, ['file' => 'solrconfig.xml']);
253
            $response = $this->_sendRawGet($solrconfigXmlUrl);
254
            $solrconfigXml = simplexml_load_string($response->getRawResponse());
255
            if ($solrconfigXml === false) {
256
                throw new \InvalidArgumentException('No valid xml response from schema file: ' . $solrconfigXmlUrl);
257
            }
258
            $this->solrconfigName = (string)$solrconfigXml->attributes()->name;
259
        }
260
261
        return $this->solrconfigName;
262
    }
263
264
    /**
265
     * Gets the Solr server's version number.
266
     *
267
     * @return string Solr version number
268
     */
269
    public function getSolrServerVersion()
270
    {
271
        $systemInformation = $this->getSystemInformation();
272
        // don't know why $systemInformation->lucene->solr-spec-version won't work
273
        $luceneInformation = (array)$systemInformation->lucene;
274
        return $luceneInformation['solr-spec-version'];
275
    }
276
277
    /**
278
     * Reloads the current core
279
     *
280
     * @return \Apache_Solr_Response
281
     */
282
    public function reloadCore()
283
    {
284
        return $this->reloadCoreByName($this->getCoreName());
285
    }
286
287
    /**
288
     * Reloads a core of the connection by a given corename.
289
     *
290
     * @param string $coreName
291
     * @return \Apache_Solr_Response
292
     */
293
    public function reloadCoreByName($coreName)
294
    {
295
        $coreAdminReloadUrl = $this->_coresUrl . '?action=reload&core=' . $coreName;
296
        return $this->_sendRawGet($coreAdminReloadUrl);
297
    }
298
299
    /**
300
     * Get the configured schema for the current core.
301
     *
302
     * @return Schema
303
     */
304
    public function getSchema()
305
    {
306
        if ($this->schema !== null) {
307
            return $this->schema;
308
        }
309
        $response = $this->_sendRawGet($this->_schemaUrl);
310
        $this->schema = $this->schemaParser->parseJson($response->getRawResponse());
311
        return $this->schema;
312
    }
313
314
    /**
315
     * Get currently configured synonyms
316
     *
317
     * @param string $baseWord If given a base word, retrieves the synonyms for that word only
318
     * @return array
319
     */
320
    public function getSynonyms($baseWord = '')
321
    {
322
        $this->initializeSynonymsUrl();
323
        $synonymsUrl = $this->_synonymsUrl;
324
        if (!empty($baseWord)) {
325
            $synonymsUrl .= '/' . $baseWord;
326
        }
327
328
        $response = $this->_sendRawGet($synonymsUrl);
329
        return $this->synonymParser->parseJson($baseWord, $response->getRawResponse());
330
    }
331
332
    /**
333
     * Add list of synonyms for base word to managed synonyms map
334
     *
335
     * @param string $baseWord
336
     * @param array $synonyms
337
     *
338
     * @return \Apache_Solr_Response
339
     *
340
     * @throws \Apache_Solr_InvalidArgumentException If $baseWord or $synonyms are empty
341
     */
342
    public function addSynonym($baseWord, array $synonyms)
343
    {
344
        $this->initializeSynonymsUrl();
345
        $json = $this->synonymParser->toJson($baseWord, $synonyms);
346
        return $this->_sendRawPost($this->_synonymsUrl, $json,
347
            $this->getHttpTransport()->getDefaultTimeout(), 'application/json');
348
    }
349
350
    /**
351
     * Remove a synonym from the synonyms map
352
     *
353
     * @param string $baseWord
354
     * @return \Apache_Solr_Response
355
     * @throws \Apache_Solr_InvalidArgumentException
356
     */
357
    public function deleteSynonym($baseWord)
358
    {
359
        $this->initializeSynonymsUrl();
360
        if (empty($baseWord)) {
361
            throw new \Apache_Solr_InvalidArgumentException('Must provide base word.');
362
        }
363
364
        return $this->_sendRawDelete($this->_synonymsUrl . '/' . urlencode($baseWord));
365
    }
366
367
368
    /**
369
     * Get currently configured stop words
370
     *
371
     * @return array
372
     */
373
    public function getStopWords()
374
    {
375
        $this->initializeStopWordsUrl();
376
        $response = $this->_sendRawGet($this->_stopWordsUrl);
377
        return $this->stopWordParser->parseJson($response->getRawResponse());
378
    }
379
380
    /**
381
     * Adds stop words to the managed stop word list
382
     *
383
     * @param array|string $stopWords string for a single word, array for multiple words
384
     * @return \Apache_Solr_Response
385
     * @throws \Apache_Solr_InvalidArgumentException If $stopWords is empty
386
     */
387
    public function addStopWords($stopWords)
388
    {
389
        $this->initializeStopWordsUrl();
390
        $json = $this->stopWordParser->toJson($stopWords);
391
        return $this->_sendRawPost($this->_stopWordsUrl, $json,
392
            $this->getHttpTransport()->getDefaultTimeout(), 'application/json');
393
    }
394
395
    /**
396
     * Deletes a words from the managed stop word list
397
     *
398
     * @param string $stopWord stop word to delete
399
     * @return \Apache_Solr_Response
400
     * @throws \Apache_Solr_InvalidArgumentException If $stopWords is empty
401
     */
402
    public function deleteStopWord($stopWord)
403
    {
404
        $this->initializeStopWordsUrl();
405
        if (empty($stopWord)) {
406
            throw new \Apache_Solr_InvalidArgumentException('Must provide stop word.');
407
        }
408
409
        return $this->_sendRawDelete($this->_stopWordsUrl . '/' . urlencode($stopWord));
410
    }
411
412
    /**
413
     * @return void
414
     */
415
    protected function initializeSynonymsUrl()
416
    {
417
        if (trim($this->_synonymsUrl) !== '') {
418
            return;
419
        }
420
        $this->_synonymsUrl = $this->_constructUrl(self::SYNONYMS_SERVLET) . $this->getSchema()->getLanguage();
421
    }
422
423
    /**
424
     * @return void
425
     */
426
    protected function initializeStopWordsUrl()
427
    {
428
        if (trim($this->_stopWordsUrl) !== '') {
429
            return;
430
        }
431
432
        $this->_stopWordsUrl = $this->_constructUrl(self::STOPWORDS_SERVLET) . $this->getSchema()->getLanguage();
433
    }
434
}
435