diff --git a/entitycache.module b/entitycache.module index dce177f..924656d 100644 --- a/entitycache.module +++ b/entitycache.module @@ -90,6 +90,15 @@ class EntityCacheControllerHelper extends DrupalDefaultEntityController { } } + // Ensure integer entity IDs are valid. + if (!empty($ids)) { + $ids = $this->cleanIds($ids); + // If all passed IDs have been filtered out, do not return any entities. + if (empty($ids)) { + return $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. @@ -145,6 +154,34 @@ class EntityCacheControllerHelper extends DrupalDefaultEntityController { return $entities; } + + /** + * Ensures integer entity IDs are valid. + * + * The identifier sanitization provided by this method has been introduced + * as Drupal used to rely on the database to facilitate this, which worked + * correctly with MySQL but led to errors with other DBMS such as PostgreSQL. + * + * @param array $ids + * The entity IDs to verify. + * @return array + * The sanitized list of entity IDs. + */ + protected function cleanIds($ids) { + $base_table_schema = drupal_get_schema($this->entityInfo['base table']); + if (isset($base_table_schema['fields'][$this->idKey]['type'])) { + $id_type = $base_table_schema['fields'][$this->idKey]['type']; + if ($id_type == 'serial' || $id_type == 'int') { + $ids = array_filter($ids, function ($id) { + return is_numeric($id) && $id == (int) $id; + }); + $ids = array_map('intval', $ids); + } + } + return $ids; + } + + public static function entityCacheGet($controller, $ids, $conditions = array()) { $cached_entities = array(); if ($ids && !$conditions) {