3 namespace Drupal\search_api_synonym\Import;
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;
18 * Process and import synonyms data.
20 * @package Drupal\search_api_synonym
25 * The entity type manager.
27 * @var \Drupal\Core\Entity\EntityTypeManagerInterface
29 protected $entityManager;
32 * The entity repository.
34 * @var \Drupal\Core\Entity\EntityRepositoryInterface
36 protected $entityRepository;
41 * @var \Drupal\Core\Extension\ModuleHandlerInterface
43 protected $moduleHandler;
46 * The database connection used to check the IP against.
48 * @var \Drupal\Core\Database\Connection
50 protected $connection;
53 * Constructs Importer.
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');
63 * Execute the import of an array with synonyms.
67 * @param array $settings
71 * Array with info about the result.
73 public function execute(array $items, array $settings) {
75 $items = $this->prepare($items, $settings);
78 $results = $this->createSynonyms($items, $settings);
84 * Prepare and validate the data.
88 * @param array $settings
92 * Array with prepared data.
94 private function prepare(array $items, array $settings) {
97 foreach ($items as $item) {
98 // Decide which synonym type to use.
99 if ($settings['synonym_type'] != 'mixed') {
100 $type = $settings['synonym_type'];
103 $type = !empty($item['type']) ? $item['type'] : 'empty';
106 $prepared[$type][$item['word']][] = $item['synonym'];
115 * @param array $items
117 * @param array $settings
121 * Array with info about the result.
123 public function createSynonyms(array $items, array $settings) {
126 // Import with batch.
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)
139 // Add each item to the batch.
140 foreach ($item as $word => $synonyms) {
142 '\Drupal\search_api_synonym\Import\Importer::createSynonym',
143 [$word, $synonyms, $type, $settings]
149 'title' => t('Import synonyms...'),
150 'operations' => $operations,
151 'finished' => '\Drupal\search_api_synonym\Import\Importer::createSynonymBatchFinishedCallback',
155 return isset($context['results']) ? $context['results'] : NULL;
159 * Create / update a synonym.
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
167 * @param array $settings
169 * @param array $context
170 * Batch context - also used for storing results in non batch operations.
172 public static function createSynonym($word, array $synonyms, $type, array $settings, array &$context) {
173 $request_time = \Drupal::time()->getRequestTime();
175 // Check if we have an existing synonym entity we should update.
176 $sid = Importer::lookUpSynonym($word, $type, $settings['langcode']);
178 // Trim spaces from synonyms.
179 $synonyms = array_map('trim', $synonyms);
181 // Load and update existing synonym entity.
183 $entity = Synonym::load($sid);
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));
192 $synonyms_str = implode(',', $synonyms);
193 $entity->setSynonyms($synonyms_str);
195 // Create new entity.
197 $entity = Synonym::create([
198 'langcode' => $settings['langcode'],
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);
209 $entity->setChangedTime($request_time);
210 $entity->setActive($settings['status']);
214 if ($sid = $entity->id()) {
215 $context['results']['success'][] = $sid;
218 $context['results']['errors'][] = [
220 'synonyms' => $synonyms
226 * Batch finished callback.
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
234 * @param string $elapsed
235 * Formatted string with the time batch operation was running.
237 public static function createSynonymBatchFinishedCallback($success, $result, $operations, $elapsed) {
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.',
247 drupal_set_message($message);
255 * @param string $word
256 * The source word we add the synonym for.
257 * @param string $type
259 * @param string $langcode
263 * Entity id for the found synonym.
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);
272 return (int) $query->execute()->fetchField(0);