Mercurial > hg > isophonics-drupal-site
comparison modules/contrib/migrate_plus/src/Plugin/migrate/process/EntityLookup.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * @file | |
5 * Contains Drupal\migrate_plus\Plugin\migrate\process\EntityGenerate. | |
6 */ | |
7 | |
8 namespace Drupal\migrate_plus\Plugin\migrate\process; | |
9 | |
10 use Drupal\Core\Entity\EntityManagerInterface; | |
11 use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface; | |
12 use Drupal\Core\Plugin\ContainerFactoryPluginInterface; | |
13 use Drupal\migrate\Plugin\MigrationInterface; | |
14 use Drupal\migrate\MigrateException; | |
15 use Drupal\migrate\MigrateExecutableInterface; | |
16 use Drupal\migrate\ProcessPluginBase; | |
17 use Drupal\migrate\Row; | |
18 use Symfony\Component\DependencyInjection\ContainerInterface; | |
19 | |
20 /** | |
21 * This plugin looks for existing entities. | |
22 * | |
23 * @MigrateProcessPlugin( | |
24 * id = "entity_lookup", | |
25 * handle_multiples = TRUE | |
26 * ) | |
27 * | |
28 * In its most simple form, this plugin needs no configuration. However, if the | |
29 * lookup properties cannot be determined through introspection, define them via | |
30 * configuration. | |
31 * | |
32 * Example usage with minimal configuration: | |
33 * @code | |
34 * destination: | |
35 * plugin: 'entity:node' | |
36 * process: | |
37 * type: | |
38 * plugin: default_value | |
39 * default_value: page | |
40 * field_tags: | |
41 * plugin: entity_lookup | |
42 * source: tags | |
43 * @endcode | |
44 * | |
45 * Example usage with full configuration: | |
46 * @code | |
47 * field_tags: | |
48 * plugin: entity_lookup | |
49 * source: tags | |
50 * value_key: name | |
51 * bundle_key: vid | |
52 * bundle: tags | |
53 * entity_type: taxonomy_term | |
54 * ignore_case: true | |
55 * @endcode | |
56 */ | |
57 class EntityLookup extends ProcessPluginBase implements ContainerFactoryPluginInterface { | |
58 | |
59 /** @var \Drupal\Core\Entity\EntityManagerInterface */ | |
60 protected $entityManager; | |
61 | |
62 /** @var \Drupal\migrate\Plugin\MigrationInterface */ | |
63 protected $migration; | |
64 | |
65 /** @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface */ | |
66 protected $selectionPluginManager; | |
67 | |
68 /** @var string */ | |
69 protected $destinationEntityType; | |
70 | |
71 /** @var string|bool */ | |
72 protected $destinationBundleKey; | |
73 | |
74 /** @var string */ | |
75 protected $lookupValueKey; | |
76 | |
77 /** @var string */ | |
78 protected $lookupBundleKey; | |
79 | |
80 /** @var string */ | |
81 protected $lookupBundle; | |
82 | |
83 /** @var string */ | |
84 protected $lookupEntityType; | |
85 | |
86 /** @var string */ | |
87 protected $destinationProperty; | |
88 | |
89 /** | |
90 * {@inheritdoc} | |
91 */ | |
92 public function __construct(array $configuration, $pluginId, $pluginDefinition, MigrationInterface $migration, EntityManagerInterface $entityManager, SelectionPluginManagerInterface $selectionPluginManager) { | |
93 parent::__construct($configuration, $pluginId, $pluginDefinition); | |
94 $this->migration = $migration; | |
95 $this->entityManager = $entityManager; | |
96 $this->selectionPluginManager = $selectionPluginManager; | |
97 $pluginIdParts = explode(':', $this->migration->getDestinationPlugin()->getPluginId()); | |
98 $this->destinationEntityType = empty($pluginIdParts[1]) ?: $pluginIdParts[1]; | |
99 $this->destinationBundleKey = !$this->destinationEntityType ?: $this->entityManager->getDefinition($this->destinationEntityType)->getKey('bundle'); | |
100 } | |
101 | |
102 /** | |
103 * {@inheritdoc} | |
104 */ | |
105 public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition, MigrationInterface $migration = NULL) { | |
106 return new static( | |
107 $configuration, | |
108 $pluginId, | |
109 $pluginDefinition, | |
110 $migration, | |
111 $container->get('entity.manager'), | |
112 $container->get('plugin.manager.entity_reference_selection') | |
113 ); | |
114 } | |
115 | |
116 /** | |
117 * {@inheritdoc} | |
118 */ | |
119 public function transform($value, MigrateExecutableInterface $migrateExecutable, Row $row, $destinationProperty) { | |
120 $this->determineLookupProperties($destinationProperty); | |
121 | |
122 $this->destinationProperty = $this->configuration['destination_field']; | |
123 | |
124 return $this->query($value); | |
125 } | |
126 | |
127 /** | |
128 * Determine the lookup properties from config or target field configuration. | |
129 * | |
130 * @param string $destinationProperty | |
131 * The destination property currently worked on. This is only used together | |
132 * with the $row above. | |
133 */ | |
134 protected function determineLookupProperties($destinationProperty) { | |
135 if (!empty($this->configuration['value_key'])) { | |
136 $this->lookupValueKey = $this->configuration['value_key']; | |
137 } | |
138 if (!empty($this->configuration['bundle_key'])) { | |
139 $this->lookupBundleKey = $this->configuration['bundle_key']; | |
140 } | |
141 if (!empty($this->configuration['bundle'])) { | |
142 $this->lookupBundle = $this->configuration['bundle']; | |
143 } | |
144 if (!empty($this->configuration['entity_type'])) { | |
145 $this->lookupEntityType = $this->configuration['entity_type']; | |
146 } | |
147 | |
148 if (empty($this->lookupValueKey) || empty($this->lookupBundleKey) || empty($this->lookupBundle) || empty($this->lookupEntityType)) { | |
149 // See if we can introspect the lookup properties from the destination field. | |
150 if (!empty($this->migration->getProcess()[$this->destinationBundleKey][0]['default_value'])) { | |
151 $destinationEntityBundle = $this->migration->getProcess()[$this->destinationBundleKey][0]['default_value']; | |
152 $fieldConfig = $this->entityManager->getFieldDefinitions($this->destinationEntityType, $destinationEntityBundle)[$destinationProperty]->getConfig($destinationEntityBundle); | |
153 if ($fieldConfig->getType() != 'entity_reference') { | |
154 throw new MigrateException('The entity_lookup plugin found no entity reference field.'); | |
155 } | |
156 | |
157 if (empty($this->lookupBundle)) { | |
158 $handlerSettings = $fieldConfig->getSetting('handler_settings'); | |
159 $bundles = array_filter((array) $handlerSettings['target_bundles']); | |
160 if (count($bundles) == 1) { | |
161 $this->lookupBundle = reset($bundles); | |
162 } | |
163 // This was added in 8.1.x is not supported in 8.0.x. | |
164 elseif (!empty($handlerSettings['auto_create']) && !empty($handlerSettings['auto_create_bundle'])) { | |
165 $this->lookupBundle = reset($handlerSettings['auto_create_bundle']); | |
166 } | |
167 } | |
168 | |
169 // Make an assumption that if the selection handler can target more than | |
170 // one type of entity that we will use the first entity type. | |
171 $this->lookupEntityType = $this->lookupEntityType ?: reset($this->selectionPluginManager->createInstance($fieldConfig->getSetting('handler'))->getPluginDefinition()['entity_types']); | |
172 $this->lookupValueKey = $this->lookupValueKey ?: $this->entityManager->getDefinition($this->lookupEntityType)->getKey('label'); | |
173 $this->lookupBundleKey = $this->lookupBundleKey ?: $this->entityManager->getDefinition($this->lookupEntityType)->getKey('bundle'); | |
174 } | |
175 } | |
176 | |
177 // If there aren't enough lookup properties available by now, then bail. | |
178 if (empty($this->lookupValueKey)) { | |
179 throw new MigrateException('The entity_lookup plugin requires a value_key, none located.'); | |
180 } | |
181 if (!empty($this->lookupBundleKey) && empty($this->lookupBundle)) { | |
182 throw new MigrateException('The entity_lookup plugin found no bundle but destination entity requires one.'); | |
183 } | |
184 if (empty($this->lookupEntityType)) { | |
185 throw new MigrateException('The entity_lookup plugin requires a entity_type, none located.'); | |
186 } | |
187 } | |
188 | |
189 /** | |
190 * Checks for the existence of some value. | |
191 * | |
192 * @param $value | |
193 * The value to query. | |
194 * | |
195 * @return mixed|null | |
196 * Entity id if the queried entity exists. Otherwise NULL. | |
197 */ | |
198 protected function query($value) { | |
199 // Entity queries typically are case-insensitive. Therefore, we need to | |
200 // handle case sensitive filtering as a post-query step. By default, it | |
201 // filters case insensitive. Change to true if that is not the desired | |
202 // outcome. | |
203 $ignoreCase = !empty($this->configuration['ignore_case']) ?: FALSE; | |
204 | |
205 $multiple = is_array($value); | |
206 | |
207 $query = $this->entityManager->getStorage($this->lookupEntityType) | |
208 ->getQuery() | |
209 ->condition($this->lookupValueKey, $value, $multiple ? 'IN' : NULL); | |
210 | |
211 if ($this->lookupBundleKey) { | |
212 $query->condition($this->lookupBundleKey, $this->lookupBundle); | |
213 } | |
214 $results = $query->execute(); | |
215 | |
216 if (empty($results)) { | |
217 return NULL; | |
218 } | |
219 | |
220 if ($multiple && !empty($this->destinationProperty)) { | |
221 array_walk($results, function (&$value) { | |
222 $value = [$this->destinationProperty => $value]; | |
223 }); | |
224 | |
225 return array_values($results); | |
226 } | |
227 | |
228 // By default do a case-sensitive comparison. | |
229 if (!$ignoreCase) { | |
230 // Returns the entity's identifier. | |
231 foreach ($results as $identifier) { | |
232 if ($value === $this->entityManager->getStorage($this->lookupEntityType)->load($identifier)->{$this->lookupValueKey}->value) { | |
233 return $identifier; | |
234 } | |
235 } | |
236 } | |
237 | |
238 return reset($results); | |
239 } | |
240 | |
241 } |