Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Tests\field\Kernel;
|
Chris@0
|
4
|
Chris@18
|
5 use Drupal\Core\Database\Database;
|
Chris@0
|
6 use Drupal\Core\Entity\EntityInterface;
|
Chris@0
|
7 use Drupal\field\Entity\FieldConfig;
|
Chris@0
|
8 use Drupal\field\Entity\FieldStorageConfig;
|
Chris@0
|
9
|
Chris@0
|
10 /**
|
Chris@0
|
11 * Bulk delete storages and fields, and clean up afterwards.
|
Chris@0
|
12 *
|
Chris@0
|
13 * @group field
|
Chris@0
|
14 */
|
Chris@0
|
15 class BulkDeleteTest extends FieldKernelTestBase {
|
Chris@0
|
16
|
Chris@0
|
17 /**
|
Chris@0
|
18 * The fields to use in this test.
|
Chris@0
|
19 *
|
Chris@0
|
20 * @var array
|
Chris@0
|
21 */
|
Chris@0
|
22 protected $fieldStorages;
|
Chris@0
|
23
|
Chris@0
|
24 /**
|
Chris@0
|
25 * The entities to use in this test.
|
Chris@0
|
26 *
|
Chris@0
|
27 * @var array
|
Chris@0
|
28 */
|
Chris@0
|
29 protected $entities;
|
Chris@0
|
30
|
Chris@0
|
31 /**
|
Chris@0
|
32 * The entities to use in this test, keyed by bundle.
|
Chris@0
|
33 *
|
Chris@0
|
34 * @var array
|
Chris@0
|
35 */
|
Chris@0
|
36 protected $entitiesByBundles;
|
Chris@0
|
37
|
Chris@0
|
38 /**
|
Chris@0
|
39 * The bundles for the entities used in this test.
|
Chris@0
|
40 *
|
Chris@0
|
41 * @var array
|
Chris@0
|
42 */
|
Chris@0
|
43 protected $bundles;
|
Chris@0
|
44
|
Chris@0
|
45 /**
|
Chris@0
|
46 * The entity type to be used in the test classes.
|
Chris@0
|
47 *
|
Chris@0
|
48 * @var string
|
Chris@0
|
49 */
|
Chris@0
|
50 protected $entityTypeId = 'entity_test';
|
Chris@0
|
51
|
Chris@0
|
52 /**
|
Chris@0
|
53 * Tests that the expected hooks have been invoked on the expected entities.
|
Chris@0
|
54 *
|
Chris@0
|
55 * @param $expected_hooks
|
Chris@0
|
56 * An array keyed by hook name, with one entry per expected invocation.
|
Chris@0
|
57 * Each entry is the value of the "$entity" parameter the hook is expected
|
Chris@0
|
58 * to have been passed.
|
Chris@0
|
59 * @param $actual_hooks
|
Chris@0
|
60 * The array of actual hook invocations recorded by field_test_memorize().
|
Chris@0
|
61 */
|
Chris@0
|
62 public function checkHooksInvocations($expected_hooks, $actual_hooks) {
|
Chris@0
|
63 foreach ($expected_hooks as $hook => $invocations) {
|
Chris@0
|
64 $actual_invocations = $actual_hooks[$hook];
|
Chris@0
|
65
|
Chris@0
|
66 // Check that the number of invocations is correct.
|
Chris@0
|
67 $this->assertEqual(count($actual_invocations), count($invocations), "$hook() was called the expected number of times.");
|
Chris@0
|
68
|
Chris@0
|
69 // Check that the hook was called for each expected argument.
|
Chris@0
|
70 foreach ($invocations as $argument) {
|
Chris@0
|
71 $found = FALSE;
|
Chris@0
|
72 foreach ($actual_invocations as $actual_arguments) {
|
Chris@0
|
73 // The argument we are looking for is either an array of entities as
|
Chris@0
|
74 // the second argument or a single entity object as the first.
|
Chris@0
|
75 if ($argument instanceof EntityInterface && $actual_arguments[0]->id() == $argument->id()) {
|
Chris@0
|
76 $found = TRUE;
|
Chris@0
|
77 break;
|
Chris@0
|
78 }
|
Chris@0
|
79 // In case of an array, compare the array size and make sure it
|
Chris@0
|
80 // contains the same elements.
|
Chris@0
|
81 elseif (is_array($argument) && count($actual_arguments[1]) == count($argument) && count(array_diff_key($actual_arguments[1], $argument)) == 0) {
|
Chris@0
|
82 $found = TRUE;
|
Chris@0
|
83 break;
|
Chris@0
|
84 }
|
Chris@0
|
85 }
|
Chris@0
|
86 $this->assertTrue($found, "$hook() was called on expected argument");
|
Chris@0
|
87 }
|
Chris@0
|
88 }
|
Chris@0
|
89 }
|
Chris@0
|
90
|
Chris@0
|
91 protected function setUp() {
|
Chris@0
|
92 parent::setUp();
|
Chris@0
|
93
|
Chris@0
|
94 $this->fieldStorages = [];
|
Chris@0
|
95 $this->entities = [];
|
Chris@0
|
96 $this->entitiesByBundles = [];
|
Chris@0
|
97
|
Chris@0
|
98 // Create two bundles.
|
Chris@0
|
99 $this->bundles = ['bb_1' => 'bb_1', 'bb_2' => 'bb_2'];
|
Chris@0
|
100 foreach ($this->bundles as $name => $desc) {
|
Chris@0
|
101 entity_test_create_bundle($name, $desc);
|
Chris@0
|
102 }
|
Chris@0
|
103
|
Chris@0
|
104 // Create two field storages.
|
Chris@0
|
105 $field_storage = FieldStorageConfig::create([
|
Chris@0
|
106 'field_name' => 'bf_1',
|
Chris@0
|
107 'entity_type' => $this->entityTypeId,
|
Chris@0
|
108 'type' => 'test_field',
|
Chris@17
|
109 'cardinality' => 1,
|
Chris@0
|
110 ]);
|
Chris@0
|
111 $field_storage->save();
|
Chris@0
|
112 $this->fieldStorages[] = $field_storage;
|
Chris@0
|
113 $field_storage = FieldStorageConfig::create([
|
Chris@0
|
114 'field_name' => 'bf_2',
|
Chris@0
|
115 'entity_type' => $this->entityTypeId,
|
Chris@0
|
116 'type' => 'test_field',
|
Chris@17
|
117 'cardinality' => 4,
|
Chris@0
|
118 ]);
|
Chris@0
|
119 $field_storage->save();
|
Chris@0
|
120 $this->fieldStorages[] = $field_storage;
|
Chris@0
|
121
|
Chris@0
|
122 // For each bundle, create each field, and 10 entities with values for the
|
Chris@0
|
123 // fields.
|
Chris@0
|
124 foreach ($this->bundles as $bundle) {
|
Chris@0
|
125 foreach ($this->fieldStorages as $field_storage) {
|
Chris@0
|
126 FieldConfig::create([
|
Chris@0
|
127 'field_storage' => $field_storage,
|
Chris@0
|
128 'bundle' => $bundle,
|
Chris@0
|
129 ])->save();
|
Chris@0
|
130 }
|
Chris@0
|
131 for ($i = 0; $i < 10; $i++) {
|
Chris@0
|
132 $entity = $this->container->get('entity_type.manager')
|
Chris@0
|
133 ->getStorage($this->entityTypeId)
|
Chris@0
|
134 ->create(['type' => $bundle]);
|
Chris@0
|
135 foreach ($this->fieldStorages as $field_storage) {
|
Chris@0
|
136 $entity->{$field_storage->getName()}->setValue($this->_generateTestFieldValues($field_storage->getCardinality()));
|
Chris@0
|
137 }
|
Chris@0
|
138 $entity->save();
|
Chris@0
|
139 }
|
Chris@0
|
140 }
|
Chris@0
|
141 $this->entities = $this->container->get('entity_type.manager')
|
Chris@0
|
142 ->getStorage($this->entityTypeId)->loadMultiple();
|
Chris@0
|
143 foreach ($this->entities as $entity) {
|
Chris@0
|
144 // This test relies on the entities having stale field definitions
|
Chris@0
|
145 // so that the deleted field can be accessed on them. Access the field
|
Chris@0
|
146 // now, so that they are always loaded.
|
Chris@0
|
147 $entity->bf_1->value;
|
Chris@0
|
148
|
Chris@0
|
149 // Also keep track of the entities per bundle.
|
Chris@0
|
150 $this->entitiesByBundles[$entity->bundle()][$entity->id()] = $entity;
|
Chris@0
|
151 }
|
Chris@0
|
152 }
|
Chris@0
|
153
|
Chris@0
|
154 /**
|
Chris@0
|
155 * Verify that deleting a field leaves the field data items in the database
|
Chris@0
|
156 * and that the appropriate Field API functions can operate on the deleted
|
Chris@0
|
157 * data and field definition.
|
Chris@0
|
158 *
|
Chris@0
|
159 * This tests how EntityFieldQuery interacts with field deletion and could be
|
Chris@0
|
160 * moved to FieldCrudTestCase, but depends on this class's setUp().
|
Chris@0
|
161 */
|
Chris@0
|
162 public function testDeleteField() {
|
Chris@0
|
163 $bundle = reset($this->bundles);
|
Chris@0
|
164 $field_storage = reset($this->fieldStorages);
|
Chris@0
|
165 $field_name = $field_storage->getName();
|
Chris@17
|
166 $storage = \Drupal::entityTypeManager()->getStorage('entity_test');
|
Chris@0
|
167
|
Chris@0
|
168 // There are 10 entities of this bundle.
|
Chris@17
|
169 $found = $storage
|
Chris@17
|
170 ->getQuery()
|
Chris@0
|
171 ->condition('type', $bundle)
|
Chris@0
|
172 ->execute();
|
Chris@0
|
173 $this->assertEqual(count($found), 10, 'Correct number of entities found before deleting');
|
Chris@0
|
174
|
Chris@0
|
175 // Delete the field.
|
Chris@0
|
176 $field = FieldConfig::loadByName($this->entityTypeId, $bundle, $field_name);
|
Chris@0
|
177 $field->delete();
|
Chris@0
|
178
|
Chris@0
|
179 // The field still exists, deleted.
|
Chris@0
|
180 $fields = entity_load_multiple_by_properties('field_config', ['field_storage_uuid' => $field_storage->uuid(), 'deleted' => TRUE, 'include_deleted' => TRUE]);
|
Chris@0
|
181 $this->assertEqual(count($fields), 1, 'There is one deleted field');
|
Chris@0
|
182 $field = $fields[$field->uuid()];
|
Chris@0
|
183 $this->assertEqual($field->getTargetBundle(), $bundle, 'The deleted field is for the correct bundle');
|
Chris@0
|
184
|
Chris@0
|
185 // Check that the actual stored content did not change during delete.
|
Chris@0
|
186 /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
|
Chris@0
|
187 $table_mapping = $storage->getTableMapping();
|
Chris@0
|
188 $table = $table_mapping->getDedicatedDataTableName($field_storage);
|
Chris@0
|
189 $column = $table_mapping->getFieldColumnName($field_storage, 'value');
|
Chris@18
|
190 $result = Database::getConnection()->select($table, 't')
|
Chris@0
|
191 ->fields('t')
|
Chris@0
|
192 ->execute();
|
Chris@0
|
193 foreach ($result as $row) {
|
Chris@0
|
194 $this->assertEqual($this->entities[$row->entity_id]->{$field_name}->value, $row->$column);
|
Chris@0
|
195 }
|
Chris@0
|
196
|
Chris@0
|
197 // There are 0 entities of this bundle with non-deleted data.
|
Chris@17
|
198 $found = $storage
|
Chris@17
|
199 ->getQuery()
|
Chris@0
|
200 ->condition('type', $bundle)
|
Chris@0
|
201 ->condition("$field_name.deleted", 0)
|
Chris@0
|
202 ->execute();
|
Chris@0
|
203 $this->assertFalse($found, 'No entities found after deleting');
|
Chris@0
|
204
|
Chris@0
|
205 // There are 10 entities of this bundle when deleted fields are allowed, and
|
Chris@0
|
206 // their values are correct.
|
Chris@17
|
207 $found = $storage
|
Chris@17
|
208 ->getQuery()
|
Chris@0
|
209 ->condition('type', $bundle)
|
Chris@0
|
210 ->condition("$field_name.deleted", 1)
|
Chris@0
|
211 ->sort('id')
|
Chris@0
|
212 ->execute();
|
Chris@0
|
213 $this->assertEqual(count($found), 10, 'Correct number of entities found after deleting');
|
Chris@0
|
214 $this->assertFalse(array_diff($found, array_keys($this->entities)));
|
Chris@0
|
215 }
|
Chris@0
|
216
|
Chris@0
|
217 /**
|
Chris@0
|
218 * Tests that recreating a field with the name as a deleted field works.
|
Chris@0
|
219 */
|
Chris@0
|
220 public function testPurgeWithDeletedAndActiveField() {
|
Chris@0
|
221 $bundle = reset($this->bundles);
|
Chris@0
|
222 // Create another field storage.
|
Chris@0
|
223 $field_name = 'bf_3';
|
Chris@0
|
224 $deleted_field_storage = FieldStorageConfig::create([
|
Chris@0
|
225 'field_name' => $field_name,
|
Chris@0
|
226 'entity_type' => $this->entityTypeId,
|
Chris@0
|
227 'type' => 'test_field',
|
Chris@17
|
228 'cardinality' => 1,
|
Chris@0
|
229 ]);
|
Chris@0
|
230 $deleted_field_storage->save();
|
Chris@0
|
231 // Create the field.
|
Chris@0
|
232 FieldConfig::create([
|
Chris@0
|
233 'field_storage' => $deleted_field_storage,
|
Chris@0
|
234 'bundle' => $bundle,
|
Chris@0
|
235 ])->save();
|
Chris@0
|
236
|
Chris@0
|
237 for ($i = 0; $i < 20; $i++) {
|
Chris@0
|
238 $entity = $this->container->get('entity_type.manager')
|
Chris@0
|
239 ->getStorage($this->entityTypeId)
|
Chris@0
|
240 ->create(['type' => $bundle]);
|
Chris@0
|
241 $entity->{$field_name}->setValue($this->_generateTestFieldValues(1));
|
Chris@0
|
242 $entity->save();
|
Chris@0
|
243 }
|
Chris@0
|
244
|
Chris@0
|
245 // Delete the field.
|
Chris@0
|
246 $deleted_field = FieldConfig::loadByName($this->entityTypeId, $bundle, $field_name);
|
Chris@0
|
247 $deleted_field->delete();
|
Chris@0
|
248 $deleted_field_uuid = $deleted_field->uuid();
|
Chris@0
|
249
|
Chris@0
|
250 // Reload the field storage.
|
Chris@0
|
251 $field_storages = entity_load_multiple_by_properties('field_storage_config', ['uuid' => $deleted_field_storage->uuid(), 'include_deleted' => TRUE]);
|
Chris@0
|
252 $deleted_field_storage = reset($field_storages);
|
Chris@0
|
253
|
Chris@0
|
254 // Create the field again.
|
Chris@0
|
255 $field_storage = FieldStorageConfig::create([
|
Chris@0
|
256 'field_name' => $field_name,
|
Chris@0
|
257 'entity_type' => $this->entityTypeId,
|
Chris@0
|
258 'type' => 'test_field',
|
Chris@17
|
259 'cardinality' => 1,
|
Chris@0
|
260 ]);
|
Chris@0
|
261 $field_storage->save();
|
Chris@0
|
262 FieldConfig::create([
|
Chris@0
|
263 'field_storage' => $field_storage,
|
Chris@0
|
264 'bundle' => $bundle,
|
Chris@0
|
265 ])->save();
|
Chris@0
|
266
|
Chris@0
|
267 // The field still exists, deleted, with the same field name.
|
Chris@0
|
268 $fields = entity_load_multiple_by_properties('field_config', ['uuid' => $deleted_field_uuid, 'include_deleted' => TRUE]);
|
Chris@0
|
269 $this->assertTrue(isset($fields[$deleted_field_uuid]) && $fields[$deleted_field_uuid]->isDeleted(), 'The field exists and is deleted');
|
Chris@0
|
270 $this->assertTrue(isset($fields[$deleted_field_uuid]) && $fields[$deleted_field_uuid]->getName() == $field_name);
|
Chris@0
|
271
|
Chris@0
|
272 for ($i = 0; $i < 10; $i++) {
|
Chris@0
|
273 $entity = $this->container->get('entity_type.manager')
|
Chris@0
|
274 ->getStorage($this->entityTypeId)
|
Chris@0
|
275 ->create(['type' => $bundle]);
|
Chris@0
|
276 $entity->{$field_name}->setValue($this->_generateTestFieldValues(1));
|
Chris@0
|
277 $entity->save();
|
Chris@0
|
278 }
|
Chris@0
|
279
|
Chris@0
|
280 // Check that the two field storages have different tables.
|
Chris@0
|
281 $storage = \Drupal::entityManager()->getStorage($this->entityTypeId);
|
Chris@0
|
282 /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
|
Chris@0
|
283 $table_mapping = $storage->getTableMapping();
|
Chris@0
|
284 $deleted_table_name = $table_mapping->getDedicatedDataTableName($deleted_field_storage, TRUE);
|
Chris@0
|
285 $active_table_name = $table_mapping->getDedicatedDataTableName($field_storage);
|
Chris@0
|
286
|
Chris@0
|
287 field_purge_batch(50);
|
Chris@0
|
288
|
Chris@0
|
289 // Ensure the new field still has its table and the deleted one has been
|
Chris@0
|
290 // removed.
|
Chris@0
|
291 $this->assertTrue(\Drupal::database()->schema()->tableExists($active_table_name));
|
Chris@0
|
292 $this->assertFalse(\Drupal::database()->schema()->tableExists($deleted_table_name));
|
Chris@0
|
293
|
Chris@0
|
294 // The field has been removed from the system.
|
Chris@0
|
295 $fields = entity_load_multiple_by_properties('field_config', ['field_storage_uuid' => $deleted_field_storage->uuid(), 'deleted' => TRUE, 'include_deleted' => TRUE]);
|
Chris@0
|
296 $this->assertEqual(count($fields), 0, 'The field is gone');
|
Chris@0
|
297
|
Chris@0
|
298 // Verify there are still 10 entries in the main table.
|
Chris@0
|
299 $count = \Drupal::database()
|
Chris@0
|
300 ->select('entity_test__' . $field_name, 'f')
|
Chris@0
|
301 ->fields('f', ['entity_id'])
|
Chris@0
|
302 ->condition('bundle', $bundle)
|
Chris@0
|
303 ->countQuery()
|
Chris@0
|
304 ->execute()
|
Chris@0
|
305 ->fetchField();
|
Chris@0
|
306 $this->assertEqual($count, 10);
|
Chris@0
|
307 }
|
Chris@0
|
308
|
Chris@0
|
309 /**
|
Chris@0
|
310 * Verify that field data items and fields are purged when a field storage is
|
Chris@0
|
311 * deleted.
|
Chris@0
|
312 */
|
Chris@0
|
313 public function testPurgeField() {
|
Chris@0
|
314 // Start recording hook invocations.
|
Chris@0
|
315 field_test_memorize();
|
Chris@0
|
316
|
Chris@0
|
317 $bundle = reset($this->bundles);
|
Chris@0
|
318 $field_storage = reset($this->fieldStorages);
|
Chris@0
|
319 $field_name = $field_storage->getName();
|
Chris@0
|
320
|
Chris@0
|
321 // Delete the field.
|
Chris@0
|
322 $field = FieldConfig::loadByName($this->entityTypeId, $bundle, $field_name);
|
Chris@0
|
323 $field->delete();
|
Chris@0
|
324
|
Chris@0
|
325 // No field hooks were called.
|
Chris@0
|
326 $mem = field_test_memorize();
|
Chris@0
|
327 $this->assertEqual(count($mem), 0, 'No field hooks were called');
|
Chris@0
|
328
|
Chris@0
|
329 $batch_size = 2;
|
Chris@0
|
330 for ($count = 8; $count >= 0; $count -= $batch_size) {
|
Chris@0
|
331 // Purge two entities.
|
Chris@0
|
332 field_purge_batch($batch_size);
|
Chris@0
|
333
|
Chris@0
|
334 // There are $count deleted entities left.
|
Chris@0
|
335 $found = \Drupal::entityQuery('entity_test')
|
Chris@0
|
336 ->condition('type', $bundle)
|
Chris@0
|
337 ->condition($field_name . '.deleted', 1)
|
Chris@0
|
338 ->execute();
|
Chris@0
|
339 $this->assertEqual(count($found), $count, 'Correct number of entities found after purging 2');
|
Chris@0
|
340 }
|
Chris@0
|
341
|
Chris@0
|
342 // Check hooks invocations.
|
Chris@0
|
343 // FieldItemInterface::delete() should have been called once for each entity in the
|
Chris@0
|
344 // bundle.
|
Chris@0
|
345 $actual_hooks = field_test_memorize();
|
Chris@0
|
346 $hooks = [];
|
Chris@0
|
347 $entities = $this->entitiesByBundles[$bundle];
|
Chris@0
|
348 foreach ($entities as $id => $entity) {
|
Chris@0
|
349 $hooks['field_test_field_delete'][] = $entity;
|
Chris@0
|
350 }
|
Chris@0
|
351 $this->checkHooksInvocations($hooks, $actual_hooks);
|
Chris@0
|
352
|
Chris@0
|
353 // The field still exists, deleted.
|
Chris@0
|
354 $fields = entity_load_multiple_by_properties('field_config', ['field_storage_uuid' => $field_storage->uuid(), 'deleted' => TRUE, 'include_deleted' => TRUE]);
|
Chris@0
|
355 $this->assertEqual(count($fields), 1, 'There is one deleted field');
|
Chris@0
|
356
|
Chris@0
|
357 // Purge the field.
|
Chris@0
|
358 field_purge_batch($batch_size);
|
Chris@0
|
359
|
Chris@0
|
360 // The field is gone.
|
Chris@0
|
361 $fields = entity_load_multiple_by_properties('field_config', ['field_storage_uuid' => $field_storage->uuid(), 'deleted' => TRUE, 'include_deleted' => TRUE]);
|
Chris@0
|
362 $this->assertEqual(count($fields), 0, 'The field is gone');
|
Chris@0
|
363
|
Chris@0
|
364 // The field storage still exists, not deleted, because it has a second
|
Chris@0
|
365 // field.
|
Chris@0
|
366 $storages = entity_load_multiple_by_properties('field_storage_config', ['uuid' => $field_storage->uuid(), 'include_deleted' => TRUE]);
|
Chris@0
|
367 $this->assertTrue(isset($storages[$field_storage->uuid()]), 'The field storage exists and is not deleted');
|
Chris@0
|
368 }
|
Chris@0
|
369
|
Chris@0
|
370 /**
|
Chris@0
|
371 * Verify that field storages are preserved and purged correctly as multiple
|
Chris@0
|
372 * fields are deleted and purged.
|
Chris@0
|
373 */
|
Chris@0
|
374 public function testPurgeFieldStorage() {
|
Chris@0
|
375 // Start recording hook invocations.
|
Chris@0
|
376 field_test_memorize();
|
Chris@0
|
377
|
Chris@0
|
378 $field_storage = reset($this->fieldStorages);
|
Chris@0
|
379 $field_name = $field_storage->getName();
|
Chris@0
|
380
|
Chris@0
|
381 // Delete the first field.
|
Chris@0
|
382 $bundle = reset($this->bundles);
|
Chris@0
|
383 $field = FieldConfig::loadByName($this->entityTypeId, $bundle, $field_name);
|
Chris@0
|
384 $field->delete();
|
Chris@0
|
385
|
Chris@0
|
386 // Assert that FieldItemInterface::delete() was not called yet.
|
Chris@0
|
387 $mem = field_test_memorize();
|
Chris@0
|
388 $this->assertEqual(count($mem), 0, 'No field hooks were called.');
|
Chris@0
|
389
|
Chris@0
|
390 // Purge the data.
|
Chris@0
|
391 field_purge_batch(10);
|
Chris@0
|
392
|
Chris@0
|
393 // Check hooks invocations.
|
Chris@0
|
394 // FieldItemInterface::delete() should have been called once for each entity in the
|
Chris@0
|
395 // bundle.
|
Chris@0
|
396 $actual_hooks = field_test_memorize();
|
Chris@0
|
397 $hooks = [];
|
Chris@0
|
398 $entities = $this->entitiesByBundles[$bundle];
|
Chris@0
|
399 foreach ($entities as $id => $entity) {
|
Chris@0
|
400 $hooks['field_test_field_delete'][] = $entity;
|
Chris@0
|
401 }
|
Chris@0
|
402 $this->checkHooksInvocations($hooks, $actual_hooks);
|
Chris@0
|
403
|
Chris@0
|
404 // The field still exists, deleted.
|
Chris@0
|
405 $fields = entity_load_multiple_by_properties('field_config', ['uuid' => $field->uuid(), 'include_deleted' => TRUE]);
|
Chris@0
|
406 $this->assertTrue(isset($fields[$field->uuid()]) && $fields[$field->uuid()]->isDeleted(), 'The field exists and is deleted');
|
Chris@0
|
407
|
Chris@0
|
408 // Purge again to purge the field.
|
Chris@0
|
409 field_purge_batch(0);
|
Chris@0
|
410
|
Chris@0
|
411 // The field is gone.
|
Chris@0
|
412 $fields = entity_load_multiple_by_properties('field_config', ['uuid' => $field->uuid(), 'include_deleted' => TRUE]);
|
Chris@0
|
413 $this->assertEqual(count($fields), 0, 'The field is purged.');
|
Chris@0
|
414 // The field storage still exists, not deleted.
|
Chris@0
|
415 $storages = entity_load_multiple_by_properties('field_storage_config', ['uuid' => $field_storage->uuid(), 'include_deleted' => TRUE]);
|
Chris@0
|
416 $this->assertTrue(isset($storages[$field_storage->uuid()]) && !$storages[$field_storage->uuid()]->isDeleted(), 'The field storage exists and is not deleted');
|
Chris@0
|
417
|
Chris@0
|
418 // Delete the second field.
|
Chris@0
|
419 $bundle = next($this->bundles);
|
Chris@0
|
420 $field = FieldConfig::loadByName($this->entityTypeId, $bundle, $field_name);
|
Chris@0
|
421 $field->delete();
|
Chris@0
|
422
|
Chris@0
|
423 // Assert that FieldItemInterface::delete() was not called yet.
|
Chris@0
|
424 $mem = field_test_memorize();
|
Chris@0
|
425 $this->assertEqual(count($mem), 0, 'No field hooks were called.');
|
Chris@0
|
426
|
Chris@0
|
427 // Purge the data.
|
Chris@0
|
428 field_purge_batch(10);
|
Chris@0
|
429
|
Chris@0
|
430 // Check hooks invocations (same as above, for the 2nd bundle).
|
Chris@0
|
431 $actual_hooks = field_test_memorize();
|
Chris@0
|
432 $hooks = [];
|
Chris@0
|
433 $entities = $this->entitiesByBundles[$bundle];
|
Chris@0
|
434 foreach ($entities as $id => $entity) {
|
Chris@0
|
435 $hooks['field_test_field_delete'][] = $entity;
|
Chris@0
|
436 }
|
Chris@0
|
437 $this->checkHooksInvocations($hooks, $actual_hooks);
|
Chris@0
|
438
|
Chris@0
|
439 // The field and the storage still exist, deleted.
|
Chris@0
|
440 $fields = entity_load_multiple_by_properties('field_config', ['uuid' => $field->uuid(), 'include_deleted' => TRUE]);
|
Chris@0
|
441 $this->assertTrue(isset($fields[$field->uuid()]) && $fields[$field->uuid()]->isDeleted(), 'The field exists and is deleted');
|
Chris@0
|
442 $storages = entity_load_multiple_by_properties('field_storage_config', ['uuid' => $field_storage->uuid(), 'include_deleted' => TRUE]);
|
Chris@0
|
443 $this->assertTrue(isset($storages[$field_storage->uuid()]) && $storages[$field_storage->uuid()]->isDeleted(), 'The field storage exists and is deleted');
|
Chris@0
|
444
|
Chris@0
|
445 // Purge again to purge the field and the storage.
|
Chris@0
|
446 field_purge_batch(0);
|
Chris@0
|
447
|
Chris@0
|
448 // The field and the storage are gone.
|
Chris@0
|
449 $fields = entity_load_multiple_by_properties('field_config', ['uuid' => $field->uuid(), 'include_deleted' => TRUE]);
|
Chris@0
|
450 $this->assertEqual(count($fields), 0, 'The field is purged.');
|
Chris@0
|
451 $storages = entity_load_multiple_by_properties('field_storage_config', ['uuid' => $field_storage->uuid(), 'include_deleted' => TRUE]);
|
Chris@0
|
452 $this->assertEqual(count($storages), 0, 'The field storage is purged.');
|
Chris@0
|
453 }
|
Chris@0
|
454
|
Chris@0
|
455 }
|