Passed
Pull Request — main (#3)
by
unknown
10:19 queued 09:11
created

SearchIndex::getDefaultName()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 8
nc 3
nop 0
dl 0
loc 14
rs 10
c 1
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace BEdita\ElasticSearch\Model\Index;
5
6
use Cake\Database\DriverInterface;
7
use Cake\Datasource\ConnectionManager;
8
use Cake\Datasource\EntityInterface;
9
use Cake\ElasticSearch\Index;
10
use Cake\ElasticSearch\Query;
11
use Cake\ElasticSearch\QueryBuilder;
12
use Cake\Log\Log;
13
use Cake\Utility\Inflector;
14
use Elastica\Query\AbstractQuery;
15
16
/**
17
 * Base search index for ElasticSearch.
18
 */
19
class SearchIndex extends Index implements AdapterCompatibleInterface
20
{
21
    use IndexTrait;
22
23
    /**
24
     * Returns the index name.
25
     *
26
     * If it isn't set, it is constructed from the default collection schema and the alias for the index.
27
     *
28
     * @return string
29
     */
30
    public function getName(): string
31
    {
32
        if ($this->_name === null) {
33
            $defaultName = $this->getDefaultName();
34
            if ($defaultName !== null) {
35
                $this->_name = $defaultName;
36
            }
37
        }
38
39
        return parent::getName();
40
    }
41
42
    /**
43
     * Returns the default index name, constructed from the default collection schema and the alias for the index.
44
     *
45
     * @return string|null
46
     */
47
    protected function getDefaultName(): string|null
48
    {
49
        $driver = ConnectionManager::get('default')->getDriver();
50
        if (!$driver instanceof DriverInterface) {
51
            return null;
52
        }
53
54
        $prefix = $driver->schema();
55
        $suffix = Inflector::underscore($this->getAlias());
56
        if (empty($prefix) || empty($suffix)) {
57
            return null;
58
        }
59
60
        return $prefix . '_' . $suffix;
61
    }
62
63
    /**
64
     * Delete a document from the index knowing its ID, or throw an exception upon failure.
65
     *
66
     * @param string $id Document ID.
67
     * @param array $options Options to be passed to {@see \Cake\ElasticSearch\Index::delete()} method.
68
     * @return void
69
     */
70
    public function deleteByIdOrFail(string $id, array $options = []): void
71
    {
72
        $document = $this->getIfExists($id);
73
        if ($document === null) {
74
            return;
75
        }
76
77
        $this->deleteOrFail($document, $options);
78
    }
79
80
    /**
81
     * Prepare data for indexing. This method may be overridden by implementations to customize indexed fields.
82
     *
83
     * If `null` is returned, entity indexing is skipped (and an entity with such ID is removed
84
     * from index if already present).
85
     *
86
     * @param \Cake\Datasource\EntityInterface $entity Entity to be indexed.
87
     * @return array<string, mixed>|null
88
     */
89
    protected function prepareData(EntityInterface $entity): array|null
90
    {
91
        return $entity->toArray();
92
    }
93
94
    /**
95
     * @inheritDoc
96
     */
97
    public function reindex(EntityInterface $entity, string $operation): void
98
    {
99
        $id = (string)$entity->id;
100
        switch ($operation) {
101
            case 'edit':
102
                $data = $this->prepareData($entity);
103
                if ($data === null) {
104
                    $this->deleteByIdOrFail($id);
105
                } else {
106
                    $document = $this->patchEntity($this->getIfExists($id) ?: $this->newEmptyEntity(), $data);
107
                    $this->saveOrFail($document);
108
                }
109
                break;
110
111
            case 'delete':
112
                $this->deleteByIdOrFail($id);
113
                break;
114
115
            default:
116
                Log::warning(sprintf('Unknown operation on ElasticSearch reindex: %s', $operation));
117
        }
118
    }
119
120
    /**
121
     * @inheritDoc
122
     */
123
    public function findQuery(Query $query, array $options): Query
124
    {
125
        return $query->queryMust(
126
            fn (QueryBuilder $builder): AbstractQuery => $builder->simpleQueryString('title', $options['query']),
127
        );
128
    }
129
}
130