diff --git a/makemeeting.module b/makemeeting.module index 727714b..ed98408 100755 --- a/makemeeting.module +++ b/makemeeting.module @@ -1424,21 +1424,98 @@ function _makemeeting_define_class_suffix(&$element, $count, $total, $prefix = ' * @param $entity_id */ function _makemeeting_clear_related_entity_cache($entity_type, $entity_id) { - $info = entity_get_info($entity_type); - if (variable_get('cache', FALSE) || !empty($info['entity cache'])) { + // Clear entity_type cache. + entity_get_controller($entity_type)->resetCache(); + + // Clear core page cache. + if (variable_get('cache', FALSE)) { $entities = entity_load($entity_type, array($entity_id)); $entity = reset($entities); - // Clear core page cache. - if (variable_get('cache', FALSE)) { - global $base_root; - $uri = entity_uri($entity_type, $entity); - cache_clear_all($base_root . base_path() . $uri['path'], 'cache_page'); + global $base_root; + $uri = entity_uri($entity_type, $entity); + // Clear the non-aliased page. + cache_clear_all($base_root . base_path() . $uri['path'], 'cache_page'); + // Clear the aliased page. + cache_clear_all(url($uri['path'], array('absolute'=>TRUE)), 'cache_page'); + } + + // Clear referencing entities cache. + if (module_exists('entityreference')) { + _makemeeting_clear_referencing_entity_cache($entity_type, $entity_id); + } +} + +/** + * Invalidate referencing entities caches. + * + * Recursive function clearing the cache for all the entities that references + * the given one using the entityreference module. + * + * @param $entity_type + * @param $entity_id + */ +function _makemeeting_clear_referencing_entity_cache($entity_type, $entity_id) { + $cleared = &drupal_static(__FUNCTION__, array()); + // Avoid the cache to be cleared twice for the same entity. + if (!empty($cleared[$entity_type][$entity_id])) { + return; + } + $cleared[$entity_type][$entity_id] = TRUE; + + // Get the entity bundle to retreive the field that can reference this kind + // of entities. + $entity = entity_load_single($entity_type, $entity_id); + list(, , $bundle) = entity_extract_ids($entity_type, $entity); + $fields_referencing = _makemeeting_clear_referencing_fields($entity_type, $bundle); + + // For each referencing field, get the entities that references the current + // entity using the field and clear their cache. + foreach ($fields_referencing as $field_name) { + $query = new EntityFieldQuery(); + $query->fieldCondition($field_name, 'target_id', $entity_id); + foreach ($query->execute() as $referent_entity_type => $referent_entities) { + foreach ($referent_entities as $referent_entity_id => $referent_entity) { + _makemeeting_clear_related_entity_cache($referent_entity_type, $referent_entity_id); + } } + } +} - // Clear contrib Entity Cache. - if (!empty($info['entity cache'])) { - cache_clear_all($entity_id, 'cache_entity_' . $entity_type); +/** + * Get all fields referencing a given bundle. + * + * @param $entity_type + * The entity type of the bundle. + * @param $bundle + * The referenced bundle. + * @return array + * An array of field names being able to reference the given bundle. + */ +function _makemeeting_clear_referencing_fields($entity_type, $bundle) { + $static = &drupal_static(__FUNCTION__, array()); + // Use a static temporary cache to avoid using too mush resources. + if (array_key_exists($entity_type, $static) && array_key_exists($bunde, $static[$entity_type])) { + return $static[$entity_type][$bundle]; + } + + $fields = field_info_fields(); + $static[$entity_type][$bundle] = array(); + foreach ($fields as $field_name => $field) { + // Check if the field is an entityreference field. + if ($field['type'] != 'entityreference') { + continue; } + // Check if the entity_type match the target_type of the field. + if ($field['settings']['target_type'] != $entity_type) { + continue; + } + // If the field is using the base handler check if the bundle is allowed. + if ($field['settings']['handler'] == 'base' && !in_array($bundle, $field['settings']['handler_settings']['target_bundles'])) { + continue; + } + $static[$entity_type][$bundle][] = $field_name; } + + return $static[$entity_type][$bundle]; }