Passed
Push — main ( 74e495...77a257 )
by Simon
01:15
created

ElasticIndex::indexExists()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * class ElasticIndex|Firesphere\ElasticSearch\Indexes\ElasticIndex is the base for indexing items
4
 *
5
 * @package Firesphere\Elastic\Search
6
 * @author Simon `Firesphere` Erkelens; Marco `Sheepy` Hermo
7
 * @copyright Copyright (c) 2018 - now() Firesphere & Sheepy
8
 */
9
10
namespace Firesphere\ElasticSearch\Indexes;
11
12
use Elastic\Elasticsearch\Exception\ClientResponseException;
13
use Elastic\Elasticsearch\Exception\MissingParameterException;
14
use Elastic\Elasticsearch\Exception\ServerResponseException;
15
use Firesphere\ElasticSearch\Queries\Builders\QueryBuilder;
16
use Firesphere\ElasticSearch\Queries\ElasticQuery;
17
use Firesphere\ElasticSearch\Results\SearchResult;
18
use Firesphere\ElasticSearch\Services\ElasticCoreService;
19
use Firesphere\ElasticSearch\Traits\IndexTraits\BaseIndexTrait;
20
use Firesphere\SearchBackend\Indexes\CoreIndex;
21
use Firesphere\SearchBackend\Traits\QueryTraits\QueryFilterTrait;
22
use LogicException;
23
use SilverStripe\Core\Config\Configurable;
24
use SilverStripe\Core\Extensible;
25
use SilverStripe\Core\Injector\Injectable;
26
use SilverStripe\Core\Injector\Injector;
27
use SilverStripe\Dev\Deprecation;
28
29
/**
30
 * Base for managing a Elastic core.
31
 *
32
 * Base index settings and methods. Should be extended with at least a name for the index.
33
 * This is an abstract class that can not be instantiated on it's own
34
 *
35
 * @package Firesphere\Elastic\Search
36
 */
37
abstract class ElasticIndex extends CoreIndex
38
{
39
    use Extensible;
40
    use Configurable;
41
    use Injectable;
42
    use QueryFilterTrait;
43
    use BaseIndexTrait;
44
45
    /**
46
     * @var array
47
     */
48
    protected $clientQuery;
49
50
    /**
51
     * @var array Classes to index
52
     */
53
    protected $class = [];
54
55
    public function __construct()
56
    {
57
        $this->client = Injector::inst()->get(ElasticCoreService::class)->getClient();
58
59
        $this->extend('onBeforeInit');
60
        $this->init();
61
        $this->extend('onAfterInit');
62
    }
63
64
65
    /**
66
     * Required to initialise the fields.
67
     * It's loaded in to the non-static properties for backward compatibility with FTS
68
     * Also, it's a tad easier to use this way, loading the other way around would be very
69
     * memory intensive, as updating the config for each item is not efficient
70
     */
71
    public function init()
72
    {
73
        $config = self::config()->get($this->getIndexName());
74
        if (!$config) {
75
            Deprecation::notice('5', 'Please set an index name and use a config yml');
76
        }
77
78
        if (!empty($this->getClasses())) {
79
            if (!$this->usedAllFields) {
80
                Deprecation::notice('5', 'It is advised to use a config YML for most cases');
81
            }
82
83
            return;
84
        }
85
86
        $this->initFromConfig($config);
87
    }
88
89
    /**
90
     * @return bool
91
     * @throws ClientResponseException
92
     * @throws MissingParameterException
93
     * @throws ServerResponseException
94
     */
95
    public function indexExists(): bool
96
    {
97
        return $this->getClient()
98
            ->indices()
99
            ->exists(['index' => $this->getIndexName()])
100
            ->asBool();
0 ignored issues
show
Bug introduced by
The method asBool() does not exist on Http\Promise\Promise. ( Ignorable by Annotation )

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

100
            ->/** @scrutinizer ignore-call */ asBool();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
101
    }
102
103
    abstract public function getIndexName();
104
105
    /**
106
     * Get classes
107
     *
108
     * @return array
109
     */
110
    public function getClasses(): array
111
    {
112
        return $this->class;
113
    }
114
115
    /**
116
     * Generate the config from yml if possible
117
     * @param array|null $config
118
     */
119
    protected function initFromConfig($config): void
120
    {
121
        if (!$config || !array_key_exists('Classes', $config)) {
122
            throw new LogicException('No classes or config to index found!');
123
        }
124
125
        $this->setClasses($config['Classes']);
126
127
        // For backward compatibility, copy the config to the protected values
128
        // Saves doubling up further down the line
129
        foreach (parent::$fieldTypes as $type) {
130
            if (array_key_exists($type, $config)) {
131
                $method = 'set' . $type;
132
                if (method_exists($this, $method)) {
133
                    $this->$method($config[$type]);
134
                }
135
            }
136
        }
137
    }
138
139
    /**
140
     * Set the classes
141
     *
142
     * @param array $class
143
     * @return $this
144
     */
145
    public function setClasses($class): self
146
    {
147
        $this->class = $class;
148
149
        return $this;
150
    }
151
152
    /**
153
     * @param ElasticQuery $query
154
     * @return SearchResult
155
     * @throws ClientResponseException
156
     * @throws ServerResponseException
157
     */
158
    public function doSearch(ElasticQuery $query)
159
    {
160
        $this->clientQuery = QueryBuilder::buildQuery($query, $this);
161
162
        $result = $this->client->search($this->clientQuery);
163
164
        $result = new SearchResult($result, $query, $this);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type Http\Promise\Promise; however, parameter $result of Firesphere\ElasticSearch...chResult::__construct() does only seem to accept Elastic\Elasticsearch\Response\Elasticsearch, maybe add an additional type check? ( Ignorable by Annotation )

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

164
        $result = new SearchResult(/** @scrutinizer ignore-type */ $result, $query, $this);
Loading history...
165
166
        return $result;
167
    }
168
169
    /**
170
     * Add a class to index or query
171
     * $options is not used anymore, added for backward compatibility
172
     *
173
     * @param $class
174
     * @param array $options unused
175
     * @return $this
176
     */
177
    public function addClass($class, $options = []): self
178
    {
179
        $this->class[] = $class;
180
181
        return $this;
182
    }
183
184
    public function getClientQuery(): array
185
    {
186
        return $this->clientQuery;
187
    }
188
189
    public function setClientQuery(array $clientQuery): void
190
    {
191
        $this->clientQuery = $clientQuery;
192
    }
193
}
194