Index: entitycache.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/entitycache/entitycache.module,v
retrieving revision 1.48
diff -u -r1.48 entitycache.module
--- entitycache.module	8 Feb 2011 14:25:42 -0000	1.48
+++ entitycache.module	8 Feb 2011 22:45:22 -0000
@@ -12,121 +12,47 @@
 function entitycache_entity_info_alter(&$entity_info) {
   foreach (entitycache_supported_core_entities(TRUE) as $type => $controller) {
     $entity_info[$type]['field cache'] = FALSE;
+    $entity_info[$type]['static cache'] = TRUE;
     $entity_info[$type]['entity cache'] = TRUE;
     $entity_info[$type]['controller class'] = $controller;
   }
 }
 
 /**
- * Base controller.
+ * Entity cache helper.
+ *
+ * Note: while this class is not a real entity controller it needs to extend
+ * DrupalDefaultEntityController to get access to protected properties.
  */
-class EntityCacheBaseController extends DrupalDefaultEntityController {
+class EntityCacheControllerHelper extends DrupalDefaultEntityController {
 
-  public function resetCache(array $ids = NULL) {
-    parent::resetCache($ids);
-    // Also reset the persistent cache.
+  public static function resetEntityCache($controller, array $ids = NULL) {
+    // Reset the persistent cache.
     if (isset($ids)) {
-      cache_clear_all($ids, 'cache_entity_' . $this->entityType);
+      cache_clear_all($ids, 'cache_entity_' . $controller->entityType);
     }
   }
 
-  public function load($ids = array(), $conditions = array()) {
-    $entities = array();
+  public static function entityCacheGet($controller, &$ids, $conditions = array()) {
     $cached_entities = array();
-    $queried_entities = array();
-
-    // Revisions are not statically cached, and require a different query to
-    // other conditions, so separate the revision id into its own variable.
-    if ($this->revisionKey && isset($conditions[$this->revisionKey])) {
-      $revision_id = $conditions[$this->revisionKey];
-      unset($conditions[$this->revisionKey]);
-    }
-    else {
-      $revision_id = FALSE;
-    }
-
-    // Create a new variable which is either a prepared version of the $ids
-    // array for later comparison with the entity cache, or FALSE if no $ids
-    // were passed. The $ids array is reduced as items are loaded from cache,
-    // and we need to know if it's empty for this reason to avoid querying the
-    // database when all requested entities are loaded from cache.
-    $passed_ids = !empty($ids) ? array_flip($ids) : FALSE;
-    // Try to load entities from the static cache, if the entity type supports
-    // static caching.
-    if ($this->cache && !$revision_id) {
-      $entities += $this->cacheGet($ids, $conditions);
-      // If any entities were loaded, remove them from the ids still to load.
-      if ($passed_ids) {
-        $ids = array_keys(array_diff_key($passed_ids, $entities));
-      }
-    }
-
-    if (!$revision_id && !empty($this->entityInfo['entity cache']) && $ids && !$conditions) {
-      $cached = cache_get_multiple($ids, 'cache_entity_' . $this->entityType);
-      foreach ($cached as $item) {
-        $cached_entities[$item->cid] = $item->data;
-      }
+    if (!empty($controller->entityInfo['entity cache']) && $ids && !$conditions) {
+      // Exclude entities that are already in the static cache.
+      $ids = array_diff($ids, array_keys($controller->entityCache));
+      $cached = cache_get_multiple($ids, 'cache_entity_' . $controller->entityType);
       if ($cached) {
-        $ids = array_diff($ids, array_keys($cached_entities));
-      }
-    }
-
-    // Load any remaining entities from the database. This is the case if $ids
-    // is set to FALSE (so we load all entities), if there are any ids left to
-    // load, if loading a revision, or if $conditions was passed without $ids.
-    if ($ids === FALSE || $ids || $revision_id || ($conditions && !$passed_ids)) {
-      // Build the query.
-      $query = $this->buildQuery($ids, $conditions, $revision_id);
-      $queried_entities = $query
-        ->execute()
-        ->fetchAllAssoc($this->idKey);
-    }
-
-    // Pass all entities loaded from the database through $this->attachLoad(),
-    // which attaches fields (if supported by the entity type) and calls the
-    // entity type specific load callback, for example hook_node_load().
-    if (!empty($queried_entities)) {
-      $this->attachLoad($queried_entities, $revision_id);
-      $entities += $queried_entities;
-    }
-
-    if ($passed_ids && !empty($queried_entities)) {
-      // Add entities to the cache if we are not loading a revision.
-      if (!empty($this->entityInfo['entity cache']) && !$revision_id) {
-        foreach ($queried_entities as $item) {
-          cache_set($item->{$this->idKey}, $item, 'cache_entity_' . $this->entityType);
+        foreach ($cached as $item) {
+          $cached_entities[$item->cid] = $item->data;
         }
+        self::entityCacheAttachLoad($controller, $cached_entities);
       }
     }
-    $new_entities = $queried_entities + $cached_entities;
-
-    if (!empty($new_entities)) {
-      $this->attachAfterLoad($new_entities);
-      if (!$revision_id) {
-        $this->cacheSet($new_entities);
-      }
-      $entities += $cached_entities;
-    }
-
-    if ($this->cache) {
-      // Add entities to the cache if we are not loading a revision.
-      if (!empty($queried_entities) && !$revision_id) {
-        $this->cacheSet($queried_entities);
-      }
-    }
+    return $cached_entities;
+  }
 
-    // Ensure that the returned array is ordered the same as the original
-    // $ids array if this was passed in and remove any invalid ids.
-    if ($passed_ids) {
-      // Remove any invalid ids from the array.
-      $passed_ids = array_intersect_key($passed_ids, $entities);
-      foreach ($entities as $entity) {
-        $passed_ids[$entity->{$this->idKey}] = $entity;
-      }
-      $entities = $passed_ids;
+  public static function entityCacheSet($controller, $entities) {
+    foreach ($entities as $item) {
+      cache_set($item->{$controller->idKey}, $item, 'cache_entity_' . $controller->entityType);
     }
-
-    return $entities;
   }
 
   /**
@@ -136,26 +62,47 @@
    * to add data to objects during the request which can't be cached.
    * @see entitycache_entitycache_node_load()
    */
-  protected function attachAfterLoad($new_entities) {
-    foreach (module_implements('entitycache_' . $this->entityType . '_load') as $module) {
-      $function = $module . '_entitycache_' . $this->entityType . '_load';
-      $function($new_entities);
+  protected static function entityCacheAttachLoad($controller, $entities) {
+    foreach (module_implements('entitycache_' . $controller->entityType . '_load') as $module) {
+      $function = $module . '_entitycache_' . $controller->entityType . '_load';
+      $function($entities);
     }
   }
 }
 
 /**
- * Controller class for nodes.
- *
- * This extends the EntityCacheBaseController class, adding required
- * special handling for node objects.
+ * Default entity controller with persistent cache.
+ */
+class EntityCacheDefaultEntityController extends DrupalDefaultEntityController {
+  public function resetCache(array $ids = NULL) {
+    EntityCacheControllerHelper::resetEntityCache($this, $ids);
+    parent::resetCache($ids);
+  }
+  protected function cacheGet($ids, $conditions = array()) {
+    EntityCacheControllerHelper::entityCacheGet($this, $ids, $conditions);
+    return parent::cacheGet($ids, $conditions);
+  }
+  protected function cacheSet($entities) {
+    EntityCacheControllerHelper::entityCacheSet($this, $entities);
+    parent::cacheSet($entities);
+  }
+}
+
+/**
+ * Node entity controller with persistent cache.
  */
-class EntityCacheNodeController extends EntityCacheBaseController {
-  function attachLoad(&$nodes, $revision_id = FALSE) {
-    NodeController::attachLoad($nodes, $revision_id);
+class EntityCacheNodeController extends NodeController {
+  public function resetCache(array $ids = NULL) {
+    EntityCacheControllerHelper::resetEntityCache($this, $ids);
+    parent::resetCache($ids);
+  }
+  protected function cacheGet($ids, $conditions = array()) {
+    EntityCacheControllerHelper::entityCacheGet($this, $ids, $conditions);
+    return parent::cacheGet($ids, $conditions);
   }
-  protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) {
-    return NodeController::buildQuery($ids, $conditions, $revision_id);
+  protected function cacheSet($entities) {
+    EntityCacheControllerHelper::entityCacheSet($this, $entities);
+    parent::cacheSet($entities);
   }
 }
 
@@ -171,52 +118,79 @@
   return $bins;
 }
 
-/**
- * Controller class for taxonomy terms.
- *
- * Currently an exact copy of TaxonomyTermController.
- */
-class EntityCacheTaxonomyTermController extends EntityCacheBaseController {
-  protected $type;
-  protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) {
-    return TaxonomyTermController::buildQuery($ids, $conditions, $revision_id);
+if (module_exists('taxonomy')) {
+  /**
+   * Taxonomy term entity controller with persistent cache.
+   */
+  class EntityCacheTaxonomyTermController extends TaxonomyTermController {
+    public function resetCache(array $ids = NULL) {
+      EntityCacheControllerHelper::resetEntityCache($this, $ids);
+      parent::resetCache($ids);
+    }
+    protected function cacheGet($ids, $conditions = array()) {
+      EntityCacheControllerHelper::entityCacheGet($this, $ids, $conditions);
+      return parent::cacheGet($ids, $conditions);
+    }
+    protected function cacheSet($entities) {
+      EntityCacheControllerHelper::entityCacheSet($this, $entities);
+      parent::cacheSet($entities);
+    }
   }
 
-  protected function cacheGet($ids, $conditions = array()) {
-    return TaxonomyTermController::cacheGet($ids, $conditions = array());
+  /**
+   * Taxonomy vocabulary entity controller with persistent cache.
+   */
+  class EntityCacheTaxonomyVocabularyController extends TaxonomyVocabularyController {
+    public function resetCache(array $ids = NULL) {
+      EntityCacheControllerHelper::resetEntityCache($this, $ids);
+      parent::resetCache($ids);
+    }
+    protected function cacheGet($ids, $conditions = array()) {
+      EntityCacheControllerHelper::entityCacheGet($this, $ids, $conditions);
+      return parent::cacheGet($ids, $conditions);
+    }
+    protected function cacheSet($entities) {
+      EntityCacheControllerHelper::entityCacheSet($this, $entities);
+      parent::cacheSet($entities);
+    }
   }
 }
 
-/**
- * Controller class for taxonomy vocabularies.
- */
-class EntityCacheTaxonomyVocabularyController extends EntityCacheBaseController {
-  protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) {
-    return TaxonomyVocabularyController::buildQuery($ids, $conditions, $revision_id);
+if (module_exists('comment')) {
+  /**
+   * Comment entity controller with persistent cache.
+   */
+  class EntityCacheCommentController extends CommentController {
+    public function resetCache(array $ids = NULL) {
+      EntityCacheControllerHelper::resetEntityCache($this, $ids);
+      parent::resetCache($ids);
+    }
+    protected function cacheGet($ids, $conditions = array()) {
+      EntityCacheControllerHelper::entityCacheGet($this, $ids, $conditions);
+      return parent::cacheGet($ids, $conditions);
+    }
+    protected function cacheSet($entities) {
+      EntityCacheControllerHelper::entityCacheSet($this, $entities);
+      parent::cacheSet($entities);
+    }
   }
 }
 
 /**
- * Controller class for comments.
- *
- * Currently a direct copy of CommentController.
+ * User entity controller with persistent cache.
  */
-class EntityCacheCommentController extends EntityCacheBaseController {
-  protected function buildQuery($ids, $conditions = array(), $revision_id = FALSE) {
-    return CommentController::buildQuery($ids, $conditions, $revision_id);
+class EntityCacheUserController extends UserController {
+  public function resetCache(array $ids = NULL) {
+    EntityCacheControllerHelper::resetEntityCache($this, $ids);
+    parent::resetCache($ids);
   }
-
-  protected function attachLoad(&$comments, $revision_id = FALSE) {
-    CommentController::attachLoad($comments, $revision_id = FALSE);
+  protected function cacheGet($ids, $conditions = array()) {
+    EntityCacheControllerHelper::entityCacheGet($this, $ids, $conditions);
+    return parent::cacheGet($ids, $conditions);
   }
-}
-
-/**
- * Controller class for users.
- */
-class EntityCacheUserController extends EntityCacheBaseController {
-  protected function attachLoad(&$users, $revision_id = FALSE) {
-    UserController::attachLoad($users, $revision_id);
+  protected function cacheSet($entities) {
+    EntityCacheControllerHelper::entityCacheSet($this, $entities);
+    parent::cacheSet($entities);
   }
 }
 
@@ -232,7 +206,7 @@
 function entitycache_supported_core_entities($enabled = FALSE) {
   $return = array(
     'comment' => 'EntityCacheCommentController',
-    'file' => 'EntityCacheBaseController',
+    'file' => 'EntityCacheDefaultEntityController',
     'node' => 'EntityCacheNodeController',
     'taxonomy_term' => 'EntityCacheTaxonomyTermController',
     'taxonomy_vocabulary' => 'EntityCacheTaxonomyVocabularyController',
@@ -324,7 +298,9 @@
       $polls[$node->nid] = $node;
     }
   }
-  poll_load($polls);
+  if (!empty($polls)) {
+    poll_load($polls);
+  }
 }
 
 /**
