Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\locale;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\Core\Database\Connection;
|
Chris@0
|
6 use Drupal\Core\Database\Query\Condition;
|
Chris@0
|
7
|
Chris@0
|
8 /**
|
Chris@0
|
9 * Defines a class to store localized strings in the database.
|
Chris@0
|
10 */
|
Chris@0
|
11 class StringDatabaseStorage implements StringStorageInterface {
|
Chris@0
|
12
|
Chris@0
|
13 /**
|
Chris@0
|
14 * The database connection.
|
Chris@0
|
15 *
|
Chris@0
|
16 * @var \Drupal\Core\Database\Connection
|
Chris@0
|
17 */
|
Chris@0
|
18 protected $connection;
|
Chris@0
|
19
|
Chris@0
|
20 /**
|
Chris@0
|
21 * Additional database connection options to use in queries.
|
Chris@0
|
22 *
|
Chris@0
|
23 * @var array
|
Chris@0
|
24 */
|
Chris@0
|
25 protected $options = [];
|
Chris@0
|
26
|
Chris@0
|
27 /**
|
Chris@0
|
28 * Constructs a new StringDatabaseStorage class.
|
Chris@0
|
29 *
|
Chris@0
|
30 * @param \Drupal\Core\Database\Connection $connection
|
Chris@0
|
31 * A Database connection to use for reading and writing configuration data.
|
Chris@0
|
32 * @param array $options
|
Chris@0
|
33 * (optional) Any additional database connection options to use in queries.
|
Chris@0
|
34 */
|
Chris@0
|
35 public function __construct(Connection $connection, array $options = []) {
|
Chris@0
|
36 $this->connection = $connection;
|
Chris@0
|
37 $this->options = $options;
|
Chris@0
|
38 }
|
Chris@0
|
39
|
Chris@0
|
40 /**
|
Chris@0
|
41 * {@inheritdoc}
|
Chris@0
|
42 */
|
Chris@0
|
43 public function getStrings(array $conditions = [], array $options = []) {
|
Chris@0
|
44 return $this->dbStringLoad($conditions, $options, 'Drupal\locale\SourceString');
|
Chris@0
|
45 }
|
Chris@0
|
46
|
Chris@0
|
47 /**
|
Chris@0
|
48 * {@inheritdoc}
|
Chris@0
|
49 */
|
Chris@0
|
50 public function getTranslations(array $conditions = [], array $options = []) {
|
Chris@0
|
51 return $this->dbStringLoad($conditions, ['translation' => TRUE] + $options, 'Drupal\locale\TranslationString');
|
Chris@0
|
52 }
|
Chris@0
|
53
|
Chris@0
|
54 /**
|
Chris@0
|
55 * {@inheritdoc}
|
Chris@0
|
56 */
|
Chris@0
|
57 public function findString(array $conditions) {
|
Chris@0
|
58 $values = $this->dbStringSelect($conditions)
|
Chris@0
|
59 ->execute()
|
Chris@0
|
60 ->fetchAssoc();
|
Chris@0
|
61
|
Chris@0
|
62 if (!empty($values)) {
|
Chris@0
|
63 $string = new SourceString($values);
|
Chris@0
|
64 $string->setStorage($this);
|
Chris@0
|
65 return $string;
|
Chris@0
|
66 }
|
Chris@0
|
67 }
|
Chris@0
|
68
|
Chris@0
|
69 /**
|
Chris@0
|
70 * {@inheritdoc}
|
Chris@0
|
71 */
|
Chris@0
|
72 public function findTranslation(array $conditions) {
|
Chris@0
|
73 $values = $this->dbStringSelect($conditions, ['translation' => TRUE])
|
Chris@0
|
74 ->execute()
|
Chris@0
|
75 ->fetchAssoc();
|
Chris@0
|
76
|
Chris@0
|
77 if (!empty($values)) {
|
Chris@0
|
78 $string = new TranslationString($values);
|
Chris@0
|
79 $this->checkVersion($string, \Drupal::VERSION);
|
Chris@0
|
80 $string->setStorage($this);
|
Chris@0
|
81 return $string;
|
Chris@0
|
82 }
|
Chris@0
|
83 }
|
Chris@0
|
84
|
Chris@0
|
85 /**
|
Chris@0
|
86 * {@inheritdoc}
|
Chris@0
|
87 */
|
Chris@0
|
88 public function getLocations(array $conditions = []) {
|
Chris@0
|
89 $query = $this->connection->select('locales_location', 'l', $this->options)
|
Chris@0
|
90 ->fields('l');
|
Chris@0
|
91 foreach ($conditions as $field => $value) {
|
Chris@0
|
92 // Cast scalars to array so we can consistently use an IN condition.
|
Chris@0
|
93 $query->condition('l.' . $field, (array) $value, 'IN');
|
Chris@0
|
94 }
|
Chris@0
|
95 return $query->execute()->fetchAll();
|
Chris@0
|
96 }
|
Chris@0
|
97
|
Chris@0
|
98 /**
|
Chris@0
|
99 * {@inheritdoc}
|
Chris@0
|
100 */
|
Chris@0
|
101 public function countStrings() {
|
Chris@0
|
102 return $this->dbExecute("SELECT COUNT(*) FROM {locales_source}")->fetchField();
|
Chris@0
|
103 }
|
Chris@0
|
104
|
Chris@0
|
105 /**
|
Chris@0
|
106 * {@inheritdoc}
|
Chris@0
|
107 */
|
Chris@0
|
108 public function countTranslations() {
|
Chris@0
|
109 return $this->dbExecute("SELECT t.language, COUNT(*) AS translated FROM {locales_source} s INNER JOIN {locales_target} t ON s.lid = t.lid GROUP BY t.language")->fetchAllKeyed();
|
Chris@0
|
110 }
|
Chris@0
|
111
|
Chris@0
|
112 /**
|
Chris@0
|
113 * {@inheritdoc}
|
Chris@0
|
114 */
|
Chris@0
|
115 public function save($string) {
|
Chris@0
|
116 if ($string->isNew()) {
|
Chris@0
|
117 $result = $this->dbStringInsert($string);
|
Chris@0
|
118 if ($string->isSource() && $result) {
|
Chris@0
|
119 // Only for source strings, we set the locale identifier.
|
Chris@0
|
120 $string->setId($result);
|
Chris@0
|
121 }
|
Chris@0
|
122 $string->setStorage($this);
|
Chris@0
|
123 }
|
Chris@0
|
124 else {
|
Chris@0
|
125 $this->dbStringUpdate($string);
|
Chris@0
|
126 }
|
Chris@0
|
127 // Update locations if they come with the string.
|
Chris@0
|
128 $this->updateLocation($string);
|
Chris@0
|
129 return $this;
|
Chris@0
|
130 }
|
Chris@0
|
131
|
Chris@0
|
132 /**
|
Chris@0
|
133 * Update locations for string.
|
Chris@0
|
134 *
|
Chris@0
|
135 * @param \Drupal\locale\StringInterface $string
|
Chris@0
|
136 * The string object.
|
Chris@0
|
137 */
|
Chris@0
|
138 protected function updateLocation($string) {
|
Chris@0
|
139 if ($locations = $string->getLocations(TRUE)) {
|
Chris@0
|
140 $created = FALSE;
|
Chris@0
|
141 foreach ($locations as $type => $location) {
|
Chris@0
|
142 foreach ($location as $name => $lid) {
|
Chris@0
|
143 // Make sure that the name isn't longer than 255 characters.
|
Chris@0
|
144 $name = substr($name, 0, 255);
|
Chris@0
|
145 if (!$lid) {
|
Chris@0
|
146 $this->dbDelete('locales_location', ['sid' => $string->getId(), 'type' => $type, 'name' => $name])
|
Chris@0
|
147 ->execute();
|
Chris@0
|
148 }
|
Chris@0
|
149 elseif ($lid === TRUE) {
|
Chris@0
|
150 // This is a new location to add, take care not to duplicate.
|
Chris@0
|
151 $this->connection->merge('locales_location', $this->options)
|
Chris@0
|
152 ->keys(['sid' => $string->getId(), 'type' => $type, 'name' => $name])
|
Chris@0
|
153 ->fields(['version' => \Drupal::VERSION])
|
Chris@0
|
154 ->execute();
|
Chris@0
|
155 $created = TRUE;
|
Chris@0
|
156 }
|
Chris@0
|
157 // Loaded locations have 'lid' integer value, nor FALSE, nor TRUE.
|
Chris@0
|
158 }
|
Chris@0
|
159 }
|
Chris@0
|
160 if ($created) {
|
Chris@0
|
161 // As we've set a new location, check string version too.
|
Chris@0
|
162 $this->checkVersion($string, \Drupal::VERSION);
|
Chris@0
|
163 }
|
Chris@0
|
164 }
|
Chris@0
|
165 }
|
Chris@0
|
166
|
Chris@0
|
167 /**
|
Chris@0
|
168 * Checks whether the string version matches a given version, fix it if not.
|
Chris@0
|
169 *
|
Chris@0
|
170 * @param \Drupal\locale\StringInterface $string
|
Chris@0
|
171 * The string object.
|
Chris@0
|
172 * @param string $version
|
Chris@0
|
173 * Drupal version to check against.
|
Chris@0
|
174 */
|
Chris@0
|
175 protected function checkVersion($string, $version) {
|
Chris@0
|
176 if ($string->getId() && $string->getVersion() != $version) {
|
Chris@0
|
177 $string->setVersion($version);
|
Chris@0
|
178 $this->connection->update('locales_source', $this->options)
|
Chris@0
|
179 ->condition('lid', $string->getId())
|
Chris@0
|
180 ->fields(['version' => $version])
|
Chris@0
|
181 ->execute();
|
Chris@0
|
182 }
|
Chris@0
|
183 }
|
Chris@0
|
184
|
Chris@0
|
185 /**
|
Chris@0
|
186 * {@inheritdoc}
|
Chris@0
|
187 */
|
Chris@0
|
188 public function delete($string) {
|
Chris@0
|
189 if ($keys = $this->dbStringKeys($string)) {
|
Chris@0
|
190 $this->dbDelete('locales_target', $keys)->execute();
|
Chris@0
|
191 if ($string->isSource()) {
|
Chris@0
|
192 $this->dbDelete('locales_source', $keys)->execute();
|
Chris@0
|
193 $this->dbDelete('locales_location', $keys)->execute();
|
Chris@0
|
194 $string->setId(NULL);
|
Chris@0
|
195 }
|
Chris@0
|
196 }
|
Chris@0
|
197 else {
|
Chris@0
|
198 throw new StringStorageException('The string cannot be deleted because it lacks some key fields: ' . $string->getString());
|
Chris@0
|
199 }
|
Chris@0
|
200 return $this;
|
Chris@0
|
201 }
|
Chris@0
|
202
|
Chris@0
|
203 /**
|
Chris@0
|
204 * {@inheritdoc}
|
Chris@0
|
205 */
|
Chris@0
|
206 public function deleteStrings($conditions) {
|
Chris@0
|
207 $lids = $this->dbStringSelect($conditions, ['fields' => ['lid']])->execute()->fetchCol();
|
Chris@0
|
208 if ($lids) {
|
Chris@0
|
209 $this->dbDelete('locales_target', ['lid' => $lids])->execute();
|
Chris@0
|
210 $this->dbDelete('locales_source', ['lid' => $lids])->execute();
|
Chris@0
|
211 $this->dbDelete('locales_location', ['sid' => $lids])->execute();
|
Chris@0
|
212 }
|
Chris@0
|
213 }
|
Chris@0
|
214
|
Chris@0
|
215 /**
|
Chris@0
|
216 * {@inheritdoc}
|
Chris@0
|
217 */
|
Chris@0
|
218 public function deleteTranslations($conditions) {
|
Chris@0
|
219 $this->dbDelete('locales_target', $conditions)->execute();
|
Chris@0
|
220 }
|
Chris@0
|
221
|
Chris@0
|
222 /**
|
Chris@0
|
223 * {@inheritdoc}
|
Chris@0
|
224 */
|
Chris@0
|
225 public function createString($values = []) {
|
Chris@0
|
226 return new SourceString($values + ['storage' => $this]);
|
Chris@0
|
227 }
|
Chris@0
|
228
|
Chris@0
|
229 /**
|
Chris@0
|
230 * {@inheritdoc}
|
Chris@0
|
231 */
|
Chris@0
|
232 public function createTranslation($values = []) {
|
Chris@0
|
233 return new TranslationString($values + [
|
Chris@0
|
234 'storage' => $this,
|
Chris@0
|
235 'is_new' => TRUE,
|
Chris@0
|
236 ]);
|
Chris@0
|
237 }
|
Chris@0
|
238
|
Chris@0
|
239 /**
|
Chris@0
|
240 * Gets table alias for field.
|
Chris@0
|
241 *
|
Chris@0
|
242 * @param string $field
|
Chris@0
|
243 * One of the field names of the locales_source, locates_location,
|
Chris@0
|
244 * locales_target tables to find the table alias for.
|
Chris@0
|
245 *
|
Chris@0
|
246 * @return string
|
Chris@0
|
247 * One of the following values:
|
Chris@0
|
248 * - 's' for "source", "context", "version" (locales_source table fields).
|
Chris@0
|
249 * - 'l' for "type", "name" (locales_location table fields)
|
Chris@0
|
250 * - 't' for "language", "translation", "customized" (locales_target
|
Chris@0
|
251 * table fields)
|
Chris@0
|
252 */
|
Chris@0
|
253 protected function dbFieldTable($field) {
|
Chris@0
|
254 if (in_array($field, ['language', 'translation', 'customized'])) {
|
Chris@0
|
255 return 't';
|
Chris@0
|
256 }
|
Chris@0
|
257 elseif (in_array($field, ['type', 'name'])) {
|
Chris@0
|
258 return 'l';
|
Chris@0
|
259 }
|
Chris@0
|
260 else {
|
Chris@0
|
261 return 's';
|
Chris@0
|
262 }
|
Chris@0
|
263 }
|
Chris@0
|
264
|
Chris@0
|
265 /**
|
Chris@0
|
266 * Gets table name for storing string object.
|
Chris@0
|
267 *
|
Chris@0
|
268 * @param \Drupal\locale\StringInterface $string
|
Chris@0
|
269 * The string object.
|
Chris@0
|
270 *
|
Chris@0
|
271 * @return string
|
Chris@0
|
272 * The table name.
|
Chris@0
|
273 */
|
Chris@0
|
274 protected function dbStringTable($string) {
|
Chris@0
|
275 if ($string->isSource()) {
|
Chris@0
|
276 return 'locales_source';
|
Chris@0
|
277 }
|
Chris@0
|
278 elseif ($string->isTranslation()) {
|
Chris@0
|
279 return 'locales_target';
|
Chris@0
|
280 }
|
Chris@0
|
281 }
|
Chris@0
|
282
|
Chris@0
|
283 /**
|
Chris@0
|
284 * Gets keys values that are in a database table.
|
Chris@0
|
285 *
|
Chris@0
|
286 * @param \Drupal\locale\StringInterface $string
|
Chris@0
|
287 * The string object.
|
Chris@0
|
288 *
|
Chris@0
|
289 * @return array
|
Chris@0
|
290 * Array with key fields if the string has all keys, or empty array if not.
|
Chris@0
|
291 */
|
Chris@0
|
292 protected function dbStringKeys($string) {
|
Chris@0
|
293 if ($string->isSource()) {
|
Chris@0
|
294 $keys = ['lid'];
|
Chris@0
|
295 }
|
Chris@0
|
296 elseif ($string->isTranslation()) {
|
Chris@0
|
297 $keys = ['lid', 'language'];
|
Chris@0
|
298 }
|
Chris@0
|
299 if (!empty($keys) && ($values = $string->getValues($keys)) && count($keys) == count($values)) {
|
Chris@0
|
300 return $values;
|
Chris@0
|
301 }
|
Chris@0
|
302 else {
|
Chris@0
|
303 return [];
|
Chris@0
|
304 }
|
Chris@0
|
305 }
|
Chris@0
|
306
|
Chris@0
|
307 /**
|
Chris@0
|
308 * Loads multiple string objects.
|
Chris@0
|
309 *
|
Chris@0
|
310 * @param array $conditions
|
Chris@0
|
311 * Any of the conditions used by dbStringSelect().
|
Chris@0
|
312 * @param array $options
|
Chris@0
|
313 * Any of the options used by dbStringSelect().
|
Chris@0
|
314 * @param string $class
|
Chris@0
|
315 * Class name to use for fetching returned objects.
|
Chris@0
|
316 *
|
Chris@0
|
317 * @return \Drupal\locale\StringInterface[]
|
Chris@0
|
318 * Array of objects of the class requested.
|
Chris@0
|
319 */
|
Chris@0
|
320 protected function dbStringLoad(array $conditions, array $options, $class) {
|
Chris@0
|
321 $strings = [];
|
Chris@0
|
322 $result = $this->dbStringSelect($conditions, $options)->execute();
|
Chris@0
|
323 foreach ($result as $item) {
|
Chris@0
|
324 /** @var \Drupal\locale\StringInterface $string */
|
Chris@0
|
325 $string = new $class($item);
|
Chris@0
|
326 $string->setStorage($this);
|
Chris@0
|
327 $strings[] = $string;
|
Chris@0
|
328 }
|
Chris@0
|
329 return $strings;
|
Chris@0
|
330 }
|
Chris@0
|
331
|
Chris@0
|
332 /**
|
Chris@0
|
333 * Builds a SELECT query with multiple conditions and fields.
|
Chris@0
|
334 *
|
Chris@0
|
335 * The query uses both 'locales_source' and 'locales_target' tables.
|
Chris@0
|
336 * Note that by default, as we are selecting both translated and untranslated
|
Chris@0
|
337 * strings target field's conditions will be modified to match NULL rows too.
|
Chris@0
|
338 *
|
Chris@0
|
339 * @param array $conditions
|
Chris@0
|
340 * An associative array with field => value conditions that may include
|
Chris@0
|
341 * NULL values. If a language condition is included it will be used for
|
Chris@0
|
342 * joining the 'locales_target' table.
|
Chris@0
|
343 * @param array $options
|
Chris@0
|
344 * An associative array of additional options. It may contain any of the
|
Chris@0
|
345 * options used by Drupal\locale\StringStorageInterface::getStrings() and
|
Chris@0
|
346 * these additional ones:
|
Chris@0
|
347 * - 'translation', Whether to include translation fields too. Defaults to
|
Chris@0
|
348 * FALSE.
|
Chris@0
|
349 *
|
Chris@0
|
350 * @return \Drupal\Core\Database\Query\Select
|
Chris@0
|
351 * Query object with all the tables, fields and conditions.
|
Chris@0
|
352 */
|
Chris@0
|
353 protected function dbStringSelect(array $conditions, array $options = []) {
|
Chris@0
|
354 // Start building the query with source table and check whether we need to
|
Chris@0
|
355 // join the target table too.
|
Chris@0
|
356 $query = $this->connection->select('locales_source', 's', $this->options)
|
Chris@0
|
357 ->fields('s');
|
Chris@0
|
358
|
Chris@0
|
359 // Figure out how to join and translate some options into conditions.
|
Chris@0
|
360 if (isset($conditions['translated'])) {
|
Chris@0
|
361 // This is a meta-condition we need to translate into simple ones.
|
Chris@0
|
362 if ($conditions['translated']) {
|
Chris@0
|
363 // Select only translated strings.
|
Chris@0
|
364 $join = 'innerJoin';
|
Chris@0
|
365 }
|
Chris@0
|
366 else {
|
Chris@0
|
367 // Select only untranslated strings.
|
Chris@0
|
368 $join = 'leftJoin';
|
Chris@0
|
369 $conditions['translation'] = NULL;
|
Chris@0
|
370 }
|
Chris@0
|
371 unset($conditions['translated']);
|
Chris@0
|
372 }
|
Chris@0
|
373 else {
|
Chris@0
|
374 $join = !empty($options['translation']) ? 'leftJoin' : FALSE;
|
Chris@0
|
375 }
|
Chris@0
|
376
|
Chris@0
|
377 if ($join) {
|
Chris@0
|
378 if (isset($conditions['language'])) {
|
Chris@0
|
379 // If we've got a language condition, we use it for the join.
|
Chris@0
|
380 $query->$join('locales_target', 't', "t.lid = s.lid AND t.language = :langcode", [
|
Chris@0
|
381 ':langcode' => $conditions['language'],
|
Chris@0
|
382 ]);
|
Chris@0
|
383 unset($conditions['language']);
|
Chris@0
|
384 }
|
Chris@0
|
385 else {
|
Chris@0
|
386 // Since we don't have a language, join with locale id only.
|
Chris@0
|
387 $query->$join('locales_target', 't', "t.lid = s.lid");
|
Chris@0
|
388 }
|
Chris@0
|
389 if (!empty($options['translation'])) {
|
Chris@0
|
390 // We cannot just add all fields because 'lid' may get null values.
|
Chris@0
|
391 $query->fields('t', ['language', 'translation', 'customized']);
|
Chris@0
|
392 }
|
Chris@0
|
393 }
|
Chris@0
|
394
|
Chris@0
|
395 // If we have conditions for location's type or name, then we need the
|
Chris@0
|
396 // location table, for which we add a subquery. We cast any scalar value to
|
Chris@0
|
397 // array so we can consistently use IN conditions.
|
Chris@0
|
398 if (isset($conditions['type']) || isset($conditions['name'])) {
|
Chris@0
|
399 $subquery = $this->connection->select('locales_location', 'l', $this->options)
|
Chris@0
|
400 ->fields('l', ['sid']);
|
Chris@0
|
401 foreach (['type', 'name'] as $field) {
|
Chris@0
|
402 if (isset($conditions[$field])) {
|
Chris@0
|
403 $subquery->condition('l.' . $field, (array) $conditions[$field], 'IN');
|
Chris@0
|
404 unset($conditions[$field]);
|
Chris@0
|
405 }
|
Chris@0
|
406 }
|
Chris@0
|
407 $query->condition('s.lid', $subquery, 'IN');
|
Chris@0
|
408 }
|
Chris@0
|
409
|
Chris@0
|
410 // Add conditions for both tables.
|
Chris@0
|
411 foreach ($conditions as $field => $value) {
|
Chris@0
|
412 $table_alias = $this->dbFieldTable($field);
|
Chris@0
|
413 $field_alias = $table_alias . '.' . $field;
|
Chris@0
|
414 if (is_null($value)) {
|
Chris@0
|
415 $query->isNull($field_alias);
|
Chris@0
|
416 }
|
Chris@0
|
417 elseif ($table_alias == 't' && $join === 'leftJoin') {
|
Chris@0
|
418 // Conditions for target fields when doing an outer join only make
|
Chris@0
|
419 // sense if we add also OR field IS NULL.
|
Chris@0
|
420 $query->condition((new Condition('OR'))
|
Chris@0
|
421 ->condition($field_alias, (array) $value, 'IN')
|
Chris@0
|
422 ->isNull($field_alias)
|
Chris@0
|
423 );
|
Chris@0
|
424 }
|
Chris@0
|
425 else {
|
Chris@0
|
426 $query->condition($field_alias, (array) $value, 'IN');
|
Chris@0
|
427 }
|
Chris@0
|
428 }
|
Chris@0
|
429
|
Chris@0
|
430 // Process other options, string filter, query limit, etc.
|
Chris@0
|
431 if (!empty($options['filters'])) {
|
Chris@0
|
432 if (count($options['filters']) > 1) {
|
Chris@0
|
433 $filter = new Condition('OR');
|
Chris@0
|
434 $query->condition($filter);
|
Chris@0
|
435 }
|
Chris@0
|
436 else {
|
Chris@0
|
437 // If we have a single filter, just add it to the query.
|
Chris@0
|
438 $filter = $query;
|
Chris@0
|
439 }
|
Chris@0
|
440 foreach ($options['filters'] as $field => $string) {
|
Chris@18
|
441 $filter->condition($this->dbFieldTable($field) . '.' . $field, '%' . $this->connection->escapeLike($string) . '%', 'LIKE');
|
Chris@0
|
442 }
|
Chris@0
|
443 }
|
Chris@0
|
444
|
Chris@0
|
445 if (!empty($options['pager limit'])) {
|
Chris@0
|
446 $query = $query->extend('Drupal\Core\Database\Query\PagerSelectExtender')->limit($options['pager limit']);
|
Chris@0
|
447 }
|
Chris@0
|
448
|
Chris@0
|
449 return $query;
|
Chris@0
|
450 }
|
Chris@0
|
451
|
Chris@0
|
452 /**
|
Chris@0
|
453 * Creates a database record for a string object.
|
Chris@0
|
454 *
|
Chris@0
|
455 * @param \Drupal\locale\StringInterface $string
|
Chris@0
|
456 * The string object.
|
Chris@0
|
457 *
|
Chris@0
|
458 * @return bool|int
|
Chris@0
|
459 * If the operation failed, returns FALSE.
|
Chris@0
|
460 * If it succeeded returns the last insert ID of the query, if one exists.
|
Chris@0
|
461 *
|
Chris@0
|
462 * @throws \Drupal\locale\StringStorageException
|
Chris@0
|
463 * If the string is not suitable for this storage, an exception is thrown.
|
Chris@0
|
464 */
|
Chris@0
|
465 protected function dbStringInsert($string) {
|
Chris@0
|
466 if ($string->isSource()) {
|
Chris@0
|
467 $string->setValues(['context' => '', 'version' => 'none'], FALSE);
|
Chris@0
|
468 $fields = $string->getValues(['source', 'context', 'version']);
|
Chris@0
|
469 }
|
Chris@0
|
470 elseif ($string->isTranslation()) {
|
Chris@0
|
471 $string->setValues(['customized' => 0], FALSE);
|
Chris@0
|
472 $fields = $string->getValues(['lid', 'language', 'translation', 'customized']);
|
Chris@0
|
473 }
|
Chris@0
|
474 if (!empty($fields)) {
|
Chris@0
|
475 return $this->connection->insert($this->dbStringTable($string), $this->options)
|
Chris@0
|
476 ->fields($fields)
|
Chris@0
|
477 ->execute();
|
Chris@0
|
478 }
|
Chris@0
|
479 else {
|
Chris@0
|
480 throw new StringStorageException('The string cannot be saved: ' . $string->getString());
|
Chris@0
|
481 }
|
Chris@0
|
482 }
|
Chris@0
|
483
|
Chris@0
|
484 /**
|
Chris@0
|
485 * Updates string object in the database.
|
Chris@0
|
486 *
|
Chris@0
|
487 * @param \Drupal\locale\StringInterface $string
|
Chris@0
|
488 * The string object.
|
Chris@0
|
489 *
|
Chris@0
|
490 * @return bool|int
|
Chris@0
|
491 * If the record update failed, returns FALSE. If it succeeded, returns
|
Chris@0
|
492 * SAVED_NEW or SAVED_UPDATED.
|
Chris@0
|
493 *
|
Chris@0
|
494 * @throws \Drupal\locale\StringStorageException
|
Chris@0
|
495 * If the string is not suitable for this storage, an exception is thrown.
|
Chris@0
|
496 */
|
Chris@0
|
497 protected function dbStringUpdate($string) {
|
Chris@0
|
498 if ($string->isSource()) {
|
Chris@0
|
499 $values = $string->getValues(['source', 'context', 'version']);
|
Chris@0
|
500 }
|
Chris@0
|
501 elseif ($string->isTranslation()) {
|
Chris@0
|
502 $values = $string->getValues(['translation', 'customized']);
|
Chris@0
|
503 }
|
Chris@0
|
504 if (!empty($values) && $keys = $this->dbStringKeys($string)) {
|
Chris@0
|
505 return $this->connection->merge($this->dbStringTable($string), $this->options)
|
Chris@0
|
506 ->keys($keys)
|
Chris@0
|
507 ->fields($values)
|
Chris@0
|
508 ->execute();
|
Chris@0
|
509 }
|
Chris@0
|
510 else {
|
Chris@0
|
511 throw new StringStorageException('The string cannot be updated: ' . $string->getString());
|
Chris@0
|
512 }
|
Chris@0
|
513 }
|
Chris@0
|
514
|
Chris@0
|
515 /**
|
Chris@0
|
516 * Creates delete query.
|
Chris@0
|
517 *
|
Chris@0
|
518 * @param string $table
|
Chris@0
|
519 * The table name.
|
Chris@0
|
520 * @param array $keys
|
Chris@0
|
521 * Array with object keys indexed by field name.
|
Chris@0
|
522 *
|
Chris@0
|
523 * @return \Drupal\Core\Database\Query\Delete
|
Chris@0
|
524 * Returns a new Delete object for the injected database connection.
|
Chris@0
|
525 */
|
Chris@0
|
526 protected function dbDelete($table, $keys) {
|
Chris@0
|
527 $query = $this->connection->delete($table, $this->options);
|
Chris@0
|
528 foreach ($keys as $field => $value) {
|
Chris@0
|
529 $query->condition($field, $value);
|
Chris@0
|
530 }
|
Chris@0
|
531 return $query;
|
Chris@0
|
532 }
|
Chris@0
|
533
|
Chris@0
|
534 /**
|
Chris@0
|
535 * Executes an arbitrary SELECT query string with the injected options.
|
Chris@0
|
536 */
|
Chris@0
|
537 protected function dbExecute($query, array $args = []) {
|
Chris@0
|
538 return $this->connection->query($query, $args, $this->options);
|
Chris@0
|
539 }
|
Chris@0
|
540
|
Chris@0
|
541 }
|