Issue #1371938 by yched, Everett Zufelt, xjm, casey: Fixed hook_field_delete() no longer invoked during field_purge_data().
parent
8a3f461360
commit
123249f208
|
@ -194,8 +194,10 @@ function _field_invoke($op, $entity_type, $entity, &$a = NULL, &$b = NULL, $opti
|
|||
// Iterate through the instances and collect results.
|
||||
$return = array();
|
||||
foreach ($instances as $instance) {
|
||||
$field_name = $instance['field_name'];
|
||||
$field = field_info_field($field_name);
|
||||
// field_info_field() is not available for deleted fields, so use
|
||||
// field_info_field_by_id().
|
||||
$field = field_info_field_by_id($instance['field_id']);
|
||||
$field_name = $field['field_name'];
|
||||
$function = $options['default'] ? 'field_default_' . $op : $field['module'] . '_field_' . $op;
|
||||
if (function_exists($function)) {
|
||||
// Determine the list of languages to iterate on.
|
||||
|
@ -703,7 +705,8 @@ function field_attach_load($entity_type, $entities, $age = FIELD_LOAD_CURRENT, $
|
|||
}
|
||||
|
||||
// Invoke field-type module's hook_field_load().
|
||||
_field_invoke_multiple('load', $entity_type, $queried_entities, $age, $options);
|
||||
$null = NULL;
|
||||
_field_invoke_multiple('load', $entity_type, $queried_entities, $age, $null, $options);
|
||||
|
||||
// Invoke hook_field_attach_load(): let other modules act on loading the
|
||||
// entitiy.
|
||||
|
|
|
@ -2994,22 +2994,54 @@ class FieldBulkDeleteTestCase extends FieldTestCase {
|
|||
*/
|
||||
function _generateStubEntities($entity_type, $entities, $field_name = NULL) {
|
||||
$stubs = array();
|
||||
foreach ($entities as $entity) {
|
||||
foreach ($entities as $id => $entity) {
|
||||
$stub = entity_create_stub_entity($entity_type, entity_extract_ids($entity_type, $entity));
|
||||
if (isset($field_name)) {
|
||||
$stub->{$field_name} = $entity->{$field_name};
|
||||
}
|
||||
$stubs[] = $stub;
|
||||
$stubs[$id] = $stub;
|
||||
}
|
||||
return $stubs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the expected hooks have been invoked on the expected entities.
|
||||
*
|
||||
* @param $expected_hooks
|
||||
* An array keyed by hook name, with one entry per expected invocation.
|
||||
* Each entry is the value of the "$entity" parameter the hook is expected
|
||||
* to have been passed.
|
||||
* @param $actual_hooks
|
||||
* The array of actual hook invocations recorded by field_test_memorize().
|
||||
*/
|
||||
function checkHooksInvocations($expected_hooks, $actual_hooks) {
|
||||
foreach ($expected_hooks as $hook => $invocations) {
|
||||
$actual_invocations = $actual_hooks[$hook];
|
||||
|
||||
// Check that the number of invocations is correct.
|
||||
$this->assertEqual(count($actual_invocations), count($invocations), "$hook() was called the expected number of times.");
|
||||
|
||||
// Check that the hook was called for each expected argument.
|
||||
foreach ($invocations as $argument) {
|
||||
$found = FALSE;
|
||||
foreach ($actual_invocations as $actual_arguments) {
|
||||
if ($actual_arguments[1] == $argument) {
|
||||
$found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->assertTrue($found, "$hook() was called on expected argument");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('field_test');
|
||||
|
||||
// Clean up data from previous test cases.
|
||||
$this->fields = array();
|
||||
$this->instances = array();
|
||||
$this->entities = array();
|
||||
$this->entities_by_bundles = array();
|
||||
|
||||
// Create two bundles.
|
||||
$this->bundles = array('bb_1' => 'bb_1', 'bb_2' => 'bb_2');
|
||||
|
@ -3045,7 +3077,10 @@ class FieldBulkDeleteTestCase extends FieldTestCase {
|
|||
foreach ($this->fields as $field) {
|
||||
$entity->{$field['field_name']}[LANGUAGE_NONE] = $this->_generateTestFieldValues($field['cardinality']);
|
||||
}
|
||||
|
||||
$this->entities[$id] = $entity;
|
||||
// Also keep track of the entities per bundle.
|
||||
$this->entities_by_bundles[$bundle][$id] = $entity;
|
||||
field_attach_insert($this->entity_type, $entity);
|
||||
$id++;
|
||||
}
|
||||
|
@ -3110,6 +3145,7 @@ class FieldBulkDeleteTestCase extends FieldTestCase {
|
|||
* instance is deleted.
|
||||
*/
|
||||
function testPurgeInstance() {
|
||||
// Start recording hook invocations.
|
||||
field_test_memorize();
|
||||
|
||||
$bundle = reset($this->bundles);
|
||||
|
@ -3124,7 +3160,7 @@ class FieldBulkDeleteTestCase extends FieldTestCase {
|
|||
$this->assertEqual(count($mem), 0, 'No field hooks were called');
|
||||
|
||||
$batch_size = 2;
|
||||
for ($count = 8; $count >= 0; $count -= 2) {
|
||||
for ($count = 8; $count >= 0; $count -= $batch_size) {
|
||||
// Purge two entities.
|
||||
field_purge_batch($batch_size);
|
||||
|
||||
|
@ -3138,19 +3174,21 @@ class FieldBulkDeleteTestCase extends FieldTestCase {
|
|||
$this->assertEqual($count ? count($found['test_entity']) : count($found), $count, 'Correct number of entities found after purging 2');
|
||||
}
|
||||
|
||||
// hook_field_delete() was called on a pseudo-entity for each entity. Each
|
||||
// pseudo entity has a $field property that matches the original entity,
|
||||
// but no others.
|
||||
$mem = field_test_memorize();
|
||||
$this->assertEqual(count($mem['field_test_field_delete']), 10, 'hook_field_delete was called for the right number of entities');
|
||||
$stubs = $this->_generateStubEntities($this->entity_type, $this->entities, $field['field_name']);
|
||||
$count = count($stubs);
|
||||
foreach ($mem['field_test_field_delete'] as $args) {
|
||||
$entity = $args[1];
|
||||
$this->assertEqual($stubs[$entity->ftid], $entity, 'hook_field_delete() called with the correct stub');
|
||||
unset($stubs[$entity->ftid]);
|
||||
// Check hooks invocations.
|
||||
// - hook_field_load() (multiple hook) should have been called on all
|
||||
// entities by pairs of two.
|
||||
// - hook_field_delete() should have been called once for each entity in the
|
||||
// bundle.
|
||||
$actual_hooks = field_test_memorize();
|
||||
$hooks = array();
|
||||
$stubs = $this->_generateStubEntities($this->entity_type, $this->entities_by_bundles[$bundle], $field['field_name']);
|
||||
foreach (array_chunk($stubs, $batch_size, TRUE) as $chunk) {
|
||||
$hooks['field_test_field_load'][] = $chunk;
|
||||
}
|
||||
$this->assertEqual(count($stubs), $count-10, 'hook_field_delete was called with each entity once');
|
||||
foreach ($stubs as $stub) {
|
||||
$hooks['field_test_field_delete'][] = $stub;
|
||||
}
|
||||
$this->checkHooksInvocations($hooks, $actual_hooks);
|
||||
|
||||
// The instance still exists, deleted.
|
||||
$instances = field_read_instances(array('field_id' => $field['id'], 'deleted' => 1), array('include_deleted' => 1, 'include_inactive' => 1));
|
||||
|
@ -3173,15 +3211,37 @@ class FieldBulkDeleteTestCase extends FieldTestCase {
|
|||
* instances are deleted and purged.
|
||||
*/
|
||||
function testPurgeField() {
|
||||
// Start recording hook invocations.
|
||||
field_test_memorize();
|
||||
|
||||
$field = reset($this->fields);
|
||||
|
||||
// Delete the first instance.
|
||||
$instance = field_info_instance($this->entity_type, $field['field_name'], 'bb_1');
|
||||
$bundle = reset($this->bundles);
|
||||
$instance = field_info_instance($this->entity_type, $field['field_name'], $bundle);
|
||||
field_delete_instance($instance);
|
||||
|
||||
// Assert that hook_field_delete() was not called yet.
|
||||
$mem = field_test_memorize();
|
||||
$this->assertEqual(count($mem), 0, 'No field hooks were called.');
|
||||
|
||||
// Purge the data.
|
||||
field_purge_batch(10);
|
||||
|
||||
// Check hooks invocations.
|
||||
// - hook_field_load() (multiple hook) should have been called once, for all
|
||||
// entities in the bundle.
|
||||
// - hook_field_delete() should have been called once for each entity in the
|
||||
// bundle.
|
||||
$actual_hooks = field_test_memorize();
|
||||
$hooks = array();
|
||||
$stubs = $this->_generateStubEntities($this->entity_type, $this->entities_by_bundles[$bundle], $field['field_name']);
|
||||
$hooks['field_test_field_load'][] = $stubs;
|
||||
foreach ($stubs as $stub) {
|
||||
$hooks['field_test_field_delete'][] = $stub;
|
||||
}
|
||||
$this->checkHooksInvocations($hooks, $actual_hooks);
|
||||
|
||||
// Purge again to purge the instance.
|
||||
field_purge_batch(0);
|
||||
|
||||
|
@ -3190,12 +3250,27 @@ class FieldBulkDeleteTestCase extends FieldTestCase {
|
|||
$this->assertTrue(isset($fields[$field['id']]) && !$fields[$field['id']]['deleted'], 'The field exists and is not deleted');
|
||||
|
||||
// Delete the second instance.
|
||||
$instance = field_info_instance($this->entity_type, $field['field_name'], 'bb_2');
|
||||
$bundle = next($this->bundles);
|
||||
$instance = field_info_instance($this->entity_type, $field['field_name'], $bundle);
|
||||
field_delete_instance($instance);
|
||||
|
||||
// Assert that hook_field_delete() was not called yet.
|
||||
$mem = field_test_memorize();
|
||||
$this->assertEqual(count($mem), 0, 'No field hooks were called.');
|
||||
|
||||
// Purge the data.
|
||||
field_purge_batch(10);
|
||||
|
||||
// Check hooks invocations (same as above, for the 2nd bundle).
|
||||
$actual_hooks = field_test_memorize();
|
||||
$hooks = array();
|
||||
$stubs = $this->_generateStubEntities($this->entity_type, $this->entities_by_bundles[$bundle], $field['field_name']);
|
||||
$hooks['field_test_field_load'][] = $stubs;
|
||||
foreach ($stubs as $stub) {
|
||||
$hooks['field_test_field_delete'][] = $stub;
|
||||
}
|
||||
$this->checkHooksInvocations($hooks, $actual_hooks);
|
||||
|
||||
// The field still exists, deleted.
|
||||
$fields = field_read_fields(array('id' => $field['id']), array('include_deleted' => 1));
|
||||
$this->assertTrue(isset($fields[$field['id']]) && $fields[$field['id']]['deleted'], 'The field exists and is deleted');
|
||||
|
|
|
@ -58,6 +58,9 @@ function field_test_field_update_forbid($field, $prior_field, $has_data) {
|
|||
* Implements hook_field_load().
|
||||
*/
|
||||
function field_test_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
|
||||
$args = func_get_args();
|
||||
field_test_memorize(__FUNCTION__, $args);
|
||||
|
||||
foreach ($items as $id => $item) {
|
||||
// To keep the test non-intrusive, only act for instances with the
|
||||
// test_hook_field_load setting explicitly set to TRUE.
|
||||
|
@ -72,6 +75,30 @@ function field_test_field_load($entity_type, $entities, $field, $instances, $lan
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_insert().
|
||||
*/
|
||||
function field_test_field_insert($entity_type, $entity, $field, $instance, $items) {
|
||||
$args = func_get_args();
|
||||
field_test_memorize(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_update().
|
||||
*/
|
||||
function field_test_field_update($entity_type, $entity, $field, $instance, $items) {
|
||||
$args = func_get_args();
|
||||
field_test_memorize(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_delete().
|
||||
*/
|
||||
function field_test_field_delete($entity_type, $entity, $field, $instance, $items) {
|
||||
$args = func_get_args();
|
||||
field_test_memorize(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_validate().
|
||||
*
|
||||
|
@ -79,6 +106,9 @@ function field_test_field_load($entity_type, $entities, $field, $instances, $lan
|
|||
* - 'field_test_invalid': The value is invalid.
|
||||
*/
|
||||
function field_test_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
|
||||
$args = func_get_args();
|
||||
field_test_memorize(__FUNCTION__, $args);
|
||||
|
||||
foreach ($items as $delta => $item) {
|
||||
if ($item['value'] == -1) {
|
||||
$errors[$field['field_name']][$langcode][$delta][] = array(
|
||||
|
|
|
@ -182,30 +182,6 @@ function field_test_field_create_field($field) {
|
|||
field_test_memorize(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Memorize calls to hook_field_insert().
|
||||
*/
|
||||
function field_test_field_insert($entity_type, $entity, $field, $instance, $items) {
|
||||
$args = func_get_args();
|
||||
field_test_memorize(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Memorize calls to hook_field_update().
|
||||
*/
|
||||
function field_test_field_update($entity_type, $entity, $field, $instance, $items) {
|
||||
$args = func_get_args();
|
||||
field_test_memorize(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Memorize calls to hook_field_delete().
|
||||
*/
|
||||
function field_test_field_delete($entity_type, $entity, $field, $instance, $items) {
|
||||
$args = func_get_args();
|
||||
field_test_memorize(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_query_alter().
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue