Completed
Push — ezp-31420-merge-up ( ec14fb...141a64 )
by
unknown
40:13 queued 27:42
created

SearchIndex::addWords()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 19
rs 9.6333
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
5
 * @license For full copyright and license information view LICENSE file distributed with this source code.
6
 */
7
namespace eZ\Publish\Core\Search\Legacy\Content\WordIndexer\Repository;
8
9
use eZ\Publish\Core\Persistence\Database\DatabaseHandler;
10
use eZ\Publish\Core\Persistence\Database\SelectQuery;
11
use PDO;
12
13
/**
14
 * A service encapsulating database operations on ezsearch* tables.
15
 */
16
class SearchIndex
17
{
18
    /**
19
     * Database handler.
20
     *
21
     * @var \eZ\Publish\Core\Persistence\Database\DatabaseHandler
22
     *
23
     * @deprecated Start to use DBAL $connection instead.
24
     */
25
    protected $dbHandler;
26
27
    /**
28
     * SearchIndex constructor.
29
     *
30
     * @param \eZ\Publish\Core\Persistence\Database\DatabaseHandler $dbHandler
31
     */
32
    public function __construct(
33
        DatabaseHandler $dbHandler
34
    ) {
35
        $this->dbHandler = $dbHandler;
36
    }
37
38
    /**
39
     * Fetch already indexed words from database (legacy db table: ezsearch_word).
40
     *
41
     * @param array $words
42
     *
43
     * @return array
44
     */
45
    public function getWords(array $words)
46
    {
47
        $query = $this->dbHandler->createSelectQuery();
48
49
        // use array_map as some DBMS-es do not cast integers to strings by default
50
        $query->select('*')
51
            ->from('ezsearch_word')
52
            ->where($query->expr->in('word', array_map('strval', $words)));
53
54
        $stmt = $query->prepare();
55
        $stmt->execute();
56
57
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
58
    }
59
60
    /**
61
     * Increase the object count of the given words by one.
62
     *
63
     * @param array $wordId
64
     */
65
    public function incrementWordObjectCount(array $wordId)
66
    {
67
        $this->updateWordObjectCount($wordId, ['object_count' => 'object_count + 1']);
68
    }
69
70
    /**
71
     * Decrease the object count of the given words by one.
72
     *
73
     * @param array $wordId
74
     */
75
    public function decrementWordObjectCount(array $wordId)
76
    {
77
        $this->updateWordObjectCount($wordId, ['object_count' => 'object_count - 1']);
78
    }
79
80
    /**
81
     * Insert new words (legacy db table: ezsearch_word).
82
     *
83
     * @param array $words
84
     */
85
    public function addWords(array $words)
86
    {
87
        $query = $this->dbHandler->createInsertQuery();
88
        $query->insertInto('ezsearch_word');
89
90
        $word = null;
91
92
        $query->set(
93
            'word',
94
            ':word'
95
        )->set(
96
            'object_count',
97
            '1'
98
        );
99
        $stmt = $query->prepare();
100
        foreach ($words as $word) {
101
            $stmt->execute(['word' => $word]);
102
        }
103
    }
104
105
    /**
106
     * Remove entire search index.
107
     */
108
    public function purge()
109
    {
110
        $this->dbHandler->beginTransaction();
111
        $query = $this->dbHandler->createDeleteQuery();
112
        $tables = [
113
            'ezsearch_object_word_link',
114
            'ezsearch_word',
115
        ];
116
        foreach ($tables as $tbl) {
117
            $query->deleteFrom($tbl);
118
            $stmt = $query->prepare();
119
            $stmt->execute();
120
        }
121
        $this->dbHandler->commit();
122
    }
123
124
    /**
125
     * Link word with specific content object (legacy db table: ezsearch_object_word_link).
126
     *
127
     * @param $wordId
128
     * @param $contentId
129
     * @param $frequency
130
     * @param $placement
131
     * @param $nextWordId
132
     * @param $prevWordId
133
     * @param $contentTypeId
134
     * @param $fieldTypeId
135
     * @param $published
136
     * @param $sectionId
137
     * @param $identifier
138
     * @param $integerValue
139
     * @param $languageMask
140
     */
141
    public function addObjectWordLink($wordId,
142
                                      $contentId,
143
                                      $frequency,
144
                                      $placement,
145
                                      $nextWordId,
146
                                      $prevWordId,
147
                                      $contentTypeId,
148
                                      $fieldTypeId,
149
                                      $published,
150
                                      $sectionId,
151
                                      $identifier,
152
                                      $integerValue,
153
                                      $languageMask
154
    ) {
155
        $assoc = [
156
            'word_id' => $wordId,
157
            'contentobject_id' => $contentId,
158
            'frequency' => $frequency,
159
            'placement' => $placement,
160
            'next_word_id' => $nextWordId,
161
            'prev_word_id' => $prevWordId,
162
            'contentclass_id' => $contentTypeId,
163
            'contentclass_attribute_id' => $fieldTypeId,
164
            'published' => $published,
165
            'section_id' => $sectionId,
166
            'identifier' => $identifier,
167
            'integer_value' => $integerValue,
168
            'language_mask' => $languageMask,
169
        ];
170
        $query = $this->dbHandler->createInsertQuery();
171
        $query->insertInto('ezsearch_object_word_link');
172
        foreach ($assoc as $column => $value) {
173
            $query->set($this->dbHandler->quoteColumn($column), $query->bindValue($value));
174
        }
175
        $stmt = $query->prepare();
176
        $stmt->execute();
177
    }
178
179
    /**
180
     * Get all words related to the content object (legacy db table: ezsearch_object_word_link).
181
     *
182
     * @param $contentId
183
     *
184
     * @return array
185
     */
186
    public function getContentObjectWords($contentId)
187
    {
188
        $query = $this->dbHandler->createSelectQuery();
189
190
        $this->setContentObjectWordsSelectQuery($query);
191
192
        $stmt = $query->prepare();
193
        $stmt->execute(['contentId' => $contentId]);
194
195
        $wordIDList = [];
196
197
        while (false !== ($row = $stmt->fetch(PDO::FETCH_NUM))) {
198
            $wordIDList[] = $row[0];
199
        }
200
201
        return $wordIDList;
202
    }
203
204
    /**
205
     * Delete words not related to any content object.
206
     */
207 View Code Duplication
    public function deleteWordsWithoutObjects()
208
    {
209
        $query = $this->dbHandler->createDeleteQuery();
210
211
        $query->deleteFrom($this->dbHandler->quoteTable('ezsearch_word'))
212
            ->where($query->expr->eq($this->dbHandler->quoteColumn('object_count'), ':c'));
213
214
        $stmt = $query->prepare();
215
        $stmt->execute(['c' => 0]);
216
    }
217
218
    /**
219
     * Delete relation between a word and a content object.
220
     *
221
     * @param $contentId
222
     */
223 View Code Duplication
    public function deleteObjectWordsLink($contentId)
224
    {
225
        $query = $this->dbHandler->createDeleteQuery();
226
        $query->deleteFrom($this->dbHandler->quoteTable('ezsearch_object_word_link'))
227
            ->where($query->expr->eq($this->dbHandler->quoteColumn('contentobject_id'), ':contentId'));
228
229
        $stmt = $query->prepare();
230
        $stmt->execute(['contentId' => $contentId]);
231
    }
232
233
    /**
234
     * Set query selecting word ids for content object (method was extracted to be reusable).
235
     *
236
     * @param \eZ\Publish\Core\Persistence\Database\SelectQuery $query
237
     */
238
    private function setContentObjectWordsSelectQuery(SelectQuery $query)
239
    {
240
        $query->select('word_id')
241
            ->from($this->dbHandler->quoteTable('ezsearch_object_word_link'))
242
            ->where($query->expr->eq($this->dbHandler->quoteColumn('contentobject_id'), ':contentId'));
243
    }
244
245
    /**
246
     * Update object count for words (legacy db table: ezsearch_word).
247
     *
248
     * @param array $wordId list of word IDs
249
     * @param array $columns map of columns and values to be updated ([column => value])
250
     */
251
    private function updateWordObjectCount(array $wordId, array $columns)
252
    {
253
        $query = $this->dbHandler->createUpdateQuery();
254
        $query->update($this->dbHandler->quoteTable('ezsearch_word'));
255
256
        foreach ($columns as $column => $value) {
257
            $query->set($this->dbHandler->quoteColumn($column), $value);
258
        }
259
260
        $query->where($query->expr->in($this->dbHandler->quoteColumn('id'), $wordId));
261
262
        $stmt = $query->prepare();
263
        $stmt->execute();
264
    }
265
}
266