5defcc2ce66e1e5f9d3518a19f5134cb5d65b30d
[yaffs-website] / web / modules / contrib / search_api_synonym / src / Import / Importer.php
1 <?php
2
3 namespace Drupal\search_api_synonym\Import;
4
5 use Drupal\Core\Entity\EntityTypeManagerInterface;
6 use Drupal\Core\Entity\EntityRepositoryInterface;
7 use Drupal\Core\Extension\ModuleHandlerInterface;
8 use Drupal\Core\Datetime\DrupalDateTime;
9 use Drupal\Core\Database\Connection;
10 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
11 use Drupal\Core\StringTranslation\TranslationInterface;
12 use Drupal\search_api_synonym\Entity\Synonym;
13 use Symfony\Component\DependencyInjection\ContainerInterface;
14
15 /**
16  * Importer class.
17  *
18  * Process and import synonyms data.
19  *
20  * @package Drupal\search_api_synonym
21  */
22 class Importer {
23
24   /**
25    * The entity type manager.
26    *
27    * @var \Drupal\Core\Entity\EntityTypeManagerInterface
28    */
29   protected $entityManager;
30
31   /**
32    * The entity repository.
33    *
34    * @var \Drupal\Core\Entity\EntityRepositoryInterface
35    */
36   protected $entityRepository;
37
38   /**
39    * The module handler.
40    *
41    * @var \Drupal\Core\Extension\ModuleHandlerInterface
42    */
43   protected $moduleHandler;
44
45   /**
46    * The database connection used to check the IP against.
47    *
48    * @var \Drupal\Core\Database\Connection
49    */
50   protected $connection;
51
52   /**
53    * Constructs Importer.
54    */
55   public function __construct() {
56     $this->entityManager = \Drupal::service('entity.manager');
57     $this->entityRepository = \Drupal::service('entity.repository');
58     $this->moduleHandler = \Drupal::service('module_handler');
59     $this->connection = \Drupal::service('database');
60   }
61
62   /**
63    * Execute the import of an array with synonyms.
64    *
65    * @param array $items
66    *   Raw synonyms data.
67    * @param array $settings
68    *   Import settings.
69    *
70    * @return array
71    *   Array with info about the result.
72    */
73   public function execute(array $items, array $settings) {
74     // Prepare items.
75     $items = $this->prepare($items, $settings);
76
77     // Create synonyms.
78     $results = $this->createSynonyms($items, $settings);
79
80     return $results;
81   }
82
83   /**
84    * Prepare and validate the data.
85    *
86    * @param array $items
87    *   Raw synonyms data.
88    * @param array $settings
89    *   Import settings.
90    *
91    * @return array
92    *   Array with prepared data.
93    */
94   private function prepare(array $items, array $settings) {
95     $prepared = [];
96
97     foreach ($items as $item) {
98       // Decide which synonym type to use.
99       if ($settings['synonym_type'] != 'mixed') {
100         $type = $settings['synonym_type'];
101       }
102       else {
103         $type = !empty($item['type']) ? $item['type'] : 'empty';
104       }
105
106       $prepared[$type][$item['word']][] = $item['synonym'];
107     }
108
109     return $prepared;
110   }
111
112   /**
113    * Create synonyms.
114    *
115    * @param array $items
116    *   Raw synonyms data.
117    * @param array $settings
118    *   Import settings.
119    *
120    * @return array
121    *   Array with info about the result.
122    */
123   public function createSynonyms(array $items, array $settings) {
124     $context = [];
125
126     // Import with batch.
127     $operations = [];
128
129     foreach ($items as $type => $item) {
130       // Continue with next item if type is not valid.
131       if ($type == 'empty') {
132         $context['results']['errors'][] = [
133           'word' => key($item),
134           'synonyms' => current($item)
135         ];
136         continue;
137       }
138
139       // Add each item to the batch.
140       foreach ($item as $word => $synonyms) {
141         $operations[] = [
142           '\Drupal\search_api_synonym\Import\Importer::createSynonym',
143           [$word, $synonyms, $type, $settings]
144         ];
145       }
146     }
147
148     $batch = [
149       'title' => t('Import synonyms...'),
150       'operations' => $operations,
151       'finished' => '\Drupal\search_api_synonym\Import\Importer::createSynonymBatchFinishedCallback',
152     ];
153     batch_set($batch);
154
155     return isset($context['results']) ? $context['results'] : NULL;
156   }
157
158   /**
159    * Create / update a synonym.
160    *
161    * @param string $word
162    *   The source word we add the synonym for.
163    * @param array $synonyms
164    *   Simple array with synonyms.
165    * @param string $type
166    *   The synonym type.
167    * @param array $settings
168    *   Import settings.
169    * @param array $context
170    *   Batch context - also used for storing results in non batch operations.
171    */
172   public static function createSynonym($word, array $synonyms, $type, array $settings, array &$context) {
173     $request_time = \Drupal::time()->getRequestTime();
174
175     // Check if we have an existing synonym entity we should update.
176     $sid = Importer::lookUpSynonym($word, $type, $settings['langcode']);
177
178     // Trim spaces from synonyms.
179     $synonyms = array_map('trim', $synonyms);
180
181     // Load and update existing synonym entity.
182     if ($sid) {
183       $entity = Synonym::load($sid);
184
185       // Update method = Merge.
186       if ($settings['update_existing'] == 'merge') {
187         $existing = $entity->getSynonyms();
188         $existing = array_map('trim', explode(',', $existing));
189         $synonyms = array_unique(array_merge($existing, $synonyms));
190       }
191
192       $synonyms_str = implode(',', $synonyms);
193       $entity->setSynonyms($synonyms_str);
194     }
195     // Create new entity.
196     else {
197       $entity = Synonym::create([
198         'langcode' => $settings['langcode'],
199       ]);
200       $uid = \Drupal::currentUser()->id();
201       $entity->setOwnerId($uid);
202       $entity->setCreatedTime($request_time);
203       $entity->setType($type);
204       $entity->setWord($word);
205       $synonyms_str = implode(',', $synonyms);
206       $entity->setSynonyms($synonyms_str);
207     }
208
209     $entity->setChangedTime($request_time);
210     $entity->setActive($settings['status']);
211
212     $entity->save();
213
214     if ($sid = $entity->id()) {
215       $context['results']['success'][] = $sid;
216     }
217     else {
218       $context['results']['errors'][] = [
219         'word' => $word,
220         'synonyms' => $synonyms
221       ];
222     }
223   }
224
225   /**
226    * Batch finished callback.
227    *
228    * @param bool $success
229    *   Was the batch successful or not?
230    * @param array $result
231    *   Array with the result of the import.
232    * @param array $operations
233    *   Batch operations.
234    * @param string $elapsed
235    *   Formatted string with the time batch operation was running.
236    */
237   public static function createSynonymBatchFinishedCallback($success, $result, $operations, $elapsed) {
238     if ($success) {
239       // Set message before returning to form.
240       if (!empty($result['success'])) {
241         $count = count($result['success']);
242         $message = \Drupal::translation()->formatPlural($count,
243           '@count synonym was successfully imported.',
244           '@count synonyms was successfully imported.',
245           ['@count' => $count]
246         );
247         drupal_set_message($message);
248       }
249     }
250   }
251
252   /**
253    * Look up synonym.
254    *
255    * @param string $word
256    *   The source word we add the synonym for.
257    * @param string $type
258    *   Synonym type.
259    * @param string $langcode
260    *   Language code.
261    *
262    * @return int
263    *   Entity id for the found synonym.
264    */
265   public static function lookUpSynonym($word, $type, $langcode) {
266     $query = \Drupal::database()->select('search_api_synonym', 's');
267     $query->fields('s', ['sid']);
268     $query->condition('s.type', $type);
269     $query->condition('s.word', $word, 'LIKE');
270     $query->condition('s.langcode', $langcode);
271     $query->range(0, 1);
272     return (int) $query->execute()->fetchField(0);
273   }
274
275 }