0cebbd07c82432446afbd02e507e019b498828fc
[yaffs-website] / destination / Entity.php
1 <?php
2
3 namespace Drupal\migrate\Plugin\migrate\destination;
4
5 use Drupal\Component\Plugin\DependentPluginInterface;
6 use Drupal\Core\Entity\DependencyTrait;
7 use Drupal\Core\Entity\EntityStorageInterface;
8 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
9 use Drupal\migrate\Plugin\MigrationInterface;
10 use Drupal\migrate\Row;
11 use Symfony\Component\DependencyInjection\ContainerInterface;
12
13 /**
14  * Provides a generic destination to import entities.
15  *
16  * Available configuration keys:
17  * - translations: (optional) Boolean, if TRUE, the destination will be
18  *   associated with the langcode provided by the source plugin. Defaults to
19  *   FALSE.
20  *
21  * Examples:
22  *
23  * @code
24  * source:
25  *   plugin: d7_node
26  * process:
27  *   nid: tnid
28  *   vid: vid
29  *   langcode: language
30  *   title: title
31  *   ...
32  *   revision_timestamp: timestamp
33  * destination:
34  *   plugin: entity:node
35  * @endcode
36  *
37  * This will save the processed, migrated row as a node.
38  *
39  * @code
40  * source:
41  *   plugin: d7_node
42  * process:
43  *   nid: tnid
44  *   vid: vid
45  *   langcode: language
46  *   title: title
47  *   ...
48  *   revision_timestamp: timestamp
49  * destination:
50  *   plugin: entity:node
51  *   translations: true
52  * @endcode
53  *
54  * This will save the processed, migrated row as a node with the relevant
55  * langcode because the translations configuration is set to "true".
56  *
57  * @MigrateDestination(
58  *   id = "entity",
59  *   deriver = "Drupal\migrate\Plugin\Derivative\MigrateEntity"
60  * )
61  */
62 abstract class Entity extends DestinationBase implements ContainerFactoryPluginInterface, DependentPluginInterface {
63
64   use DependencyTrait;
65
66   /**
67    * The entity storage.
68    *
69    * @var \Drupal\Core\Entity\EntityStorageInterface
70    */
71   protected $storage;
72
73   /**
74    * The list of the bundles of this entity type.
75    *
76    * @var array
77    */
78   protected $bundles;
79
80   /**
81    * Construct a new entity.
82    *
83    * @param array $configuration
84    *   A configuration array containing information about the plugin instance.
85    * @param string $plugin_id
86    *   The plugin_id for the plugin instance.
87    * @param mixed $plugin_definition
88    *   The plugin implementation definition.
89    * @param \Drupal\migrate\Plugin\MigrationInterface $migration
90    *   The migration.
91    * @param \Drupal\Core\Entity\EntityStorageInterface $storage
92    *   The storage for this entity type.
93    * @param array $bundles
94    *   The list of bundles this entity type has.
95    */
96   public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles) {
97     $plugin_definition += [
98       'label' => $storage->getEntityType()->getPluralLabel(),
99     ];
100
101     parent::__construct($configuration, $plugin_id, $plugin_definition, $migration);
102     $this->storage = $storage;
103     $this->bundles = $bundles;
104     $this->supportsRollback = TRUE;
105   }
106
107   /**
108    * {@inheritdoc}
109    */
110   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) {
111     $entity_type_id = static::getEntityTypeId($plugin_id);
112     return new static(
113       $configuration,
114       $plugin_id,
115       $plugin_definition,
116       $migration,
117       $container->get('entity.manager')->getStorage($entity_type_id),
118       array_keys($container->get('entity.manager')->getBundleInfo($entity_type_id))
119     );
120   }
121
122   /**
123    * Finds the entity type from configuration or plugin ID.
124    *
125    * @param string $plugin_id
126    *   The plugin ID.
127    *
128    * @return string
129    *   The entity type.
130    */
131   protected static function getEntityTypeId($plugin_id) {
132     // Remove "entity:".
133     return substr($plugin_id, 7);
134   }
135
136   /**
137    * Gets the bundle for the row taking into account the default.
138    *
139    * @param \Drupal\migrate\Row $row
140    *   The current row we're importing.
141    *
142    * @return string
143    *   The bundle for this row.
144    */
145   public function getBundle(Row $row) {
146     $default_bundle = isset($this->configuration['default_bundle']) ? $this->configuration['default_bundle'] : '';
147     $bundle_key = $this->getKey('bundle');
148     return $row->getDestinationProperty($bundle_key) ?: $default_bundle;
149   }
150
151   /**
152    * {@inheritdoc}
153    */
154   public function fields(MigrationInterface $migration = NULL) {
155     // TODO: Implement fields() method.
156   }
157
158   /**
159    * Creates or loads an entity.
160    *
161    * @param \Drupal\migrate\Row $row
162    *   The row object.
163    * @param array $old_destination_id_values
164    *   The old destination IDs.
165    *
166    * @return \Drupal\Core\Entity\EntityInterface
167    *   The entity we are importing into.
168    */
169   protected function getEntity(Row $row, array $old_destination_id_values) {
170     $entity_id = reset($old_destination_id_values) ?: $this->getEntityId($row);
171     if (!empty($entity_id) && ($entity = $this->storage->load($entity_id))) {
172       // Allow updateEntity() to change the entity.
173       $entity = $this->updateEntity($entity, $row) ?: $entity;
174     }
175     else {
176       // Attempt to ensure we always have a bundle.
177       if ($bundle = $this->getBundle($row)) {
178         $row->setDestinationProperty($this->getKey('bundle'), $bundle);
179       }
180
181       // Stubs might need some required fields filled in.
182       if ($row->isStub()) {
183         $this->processStubRow($row);
184       }
185       $entity = $this->storage->create($row->getDestination());
186       $entity->enforceIsNew();
187     }
188     return $entity;
189   }
190
191   /**
192    * Gets the entity ID of the row.
193    *
194    * @param \Drupal\migrate\Row $row
195    *   The row of data.
196    *
197    * @return string
198    *   The entity ID for the row that we are importing.
199    */
200   protected function getEntityId(Row $row) {
201     return $row->getDestinationProperty($this->getKey('id'));
202   }
203
204   /**
205    * Returns a specific entity key.
206    *
207    * @param string $key
208    *   The name of the entity key to return.
209    *
210    * @return string|bool
211    *   The entity key, or FALSE if it does not exist.
212    *
213    * @see \Drupal\Core\Entity\EntityTypeInterface::getKeys()
214    */
215   protected function getKey($key) {
216     return $this->storage->getEntityType()->getKey($key);
217   }
218
219   /**
220    * {@inheritdoc}
221    */
222   public function rollback(array $destination_identifier) {
223     // Delete the specified entity from Drupal if it exists.
224     $entity = $this->storage->load(reset($destination_identifier));
225     if ($entity) {
226       $entity->delete();
227     }
228   }
229
230   /**
231    * {@inheritdoc}
232    */
233   public function calculateDependencies() {
234     $this->addDependency('module', $this->storage->getEntityType()->getProvider());
235     return $this->dependencies;
236   }
237
238 }