diff --git a/entity.api.php b/entity.api.php index dff6cdc..f528f28 100644 --- a/entity.api.php +++ b/entity.api.php @@ -38,15 +38,24 @@ * additional keys are used by the entity CRUD API: * - name: (optional) The key of the entity property containing the unique, * machine readable name of the entity. If specified, this is used as - * uniform identifier of the entity, while the usual 'id' key is still - * required. If a name key is given, the name is used as identifier for all - * API functions like entity_load(), but the numeric id as specified by the - * 'id' key is still used to refer to the entity internally, i.e. in the - * database. - * For exportable entities, it's strongly recommended to use a machine name - * here as those are more portable across systems. + * identifier of the entity, while the usual 'id' key is still required and + * may be used when modules deal with entities generically, or to refer to + * the entity internally, i.e. in the database. + * If a name key is given, the name is used as entity identifier for most + * API functions and hooks. However note that for consistency all generic + * entity hooks like hook_entity_load() are invoked with the entities keyed + * by numeric id, while entity-type specific hooks like + * hook_{entity_type}_load() are invoked with the entities keyed by name. + * Also, just as entity_load_single() entity_load() may be called + * with names passed as the $ids parameter, while the results of + * entity_load() are always keyed by numeric id. Thus, it is suggested to + * make use of entity_load_multiple_by_name() to implement entity-type + * specific loading functions like {entity_type}_load_multiple(), as this + * function returns the entities keyed by name. + * For exportable entities, it is strongly recommended to make use of a + * machine name as names are portable across systems. * - module: (optional) A key for the module property used by the entity CRUD - * API to save the source module name for exportable entities, which are + * API to save the source module name for exportable entities that have been * provided in code. Defaults to 'module'. * - status: (optional) The name of the entity property used by the entity * CRUD API to save the exportable entity status using defined bit flags. diff --git a/entity.module b/entity.module index 432d469..96cb423 100644 --- a/entity.module +++ b/entity.module @@ -71,6 +71,57 @@ function entity_type_supports($entity_type, $op) { } /** + * A wrapper around entity_load() to load a single entity by name or numeric id. + * + * @todo: Re-name entity_load() to entity_load_multiple() in d8 core and this + * to entity_load(). + * + * @param $entity_type + * The entity type to load, e.g. node or user. + * @param $id + * The entity id, either the numeric id or the entity name. In case the entity + * type has specified a name key, both the numeric id and the name may be + * passed. + * + * @return + * The entity object, or FALSE. + * + * @see entity_load() + */ +function entity_load_single($entity_type, $id) { + $entities = entity_load($entity_type, array($id)); + return reset($entities); +} + +/** + * A wrapper around entity_load() to return entities keyed by name key if existing. + * + * @param $entity_type + * The entity type to load, e.g. node or user. + * @param $names + * An array of entity names or ids, or FALSE to load all entities. + * @param $conditions + * (deprecated) An associative array of conditions on the base table, where + * the keys are the database fields and the values are the values those + * fields must have. Instead, it is preferable to use EntityFieldQuery to + * retrieve a list of entity IDs loadable by this function. + * + * @return + * An array of entity objects indexed by their names (or ids if the entity + * type has no name key). + * + * @see entity_load() + */ +function entity_load_multiple_by_name($entity_type, $names = FALSE, $conditions = array()) { + $entities = entity_load($entity_type, $names, $conditions); + $info = entity_get_info($entity_type); + if (!isset($info['entity keys']['name'])) { + return $entities; + } + return entity_key_array_by_property($entities, $info['entity keys']['name']); +} + +/** * Permanently save an entity. * * In case of failures, an exception is thrown. @@ -127,7 +178,8 @@ function entity_delete($entity_type, $id) { * @param $entity_type * The type of the entity. * @param $ids - * An array of uniform identifiers of the entities to delete. + * An array of entity ids of the entities to delete. In case the entity makes + * use of a name key, both the names or numeric ids may be passed. * @return * FALSE if the given entity type isn't compatible to the CRUD API. */ @@ -251,11 +303,10 @@ function entity_build_content($entity_type, $entity, $view_mode = 'full', $langc } /** - * Returns the entity identifier. + * Returns the entity identifier, i.e. the entities name or numeric id. * - * Unlike entity_extract_ids() this function returns the uniform identifier, - * thus if an exportable entity makes use of a name key, the name of the entity - * is returned. Otherwise the usual numeric id is returned. + * Unlike entity_extract_ids() this function returns the name of the entity + * instead of the numeric id, in case the entity type has specified a name key. * * @param $entity_type * The type of the entity. @@ -276,19 +327,23 @@ function entity_id($entity_type, $entity) { /** * Generate an array for rendering the given entities. * + * Entities being viewed, are generally expected to be fully-loaded entity + * objects, thus have their name or id key set. However, it is possible to + * view a single entity without any id, e.g. for generating a preview during + * creation. + * * @param $entity_type * The type of the entity. * @param $entities - * An array of entities to render, keyed by their ids. E.g. as returned from - * entity_load(). + * An array of entities to render. * @param $view_mode * A view mode as used by this entity type, e.g. 'full', 'teaser'... * @param $langcode * (optional) A language code to use for rendering. Defaults to the global * content language of the current request. * @return - * The renderable array, or FALSE if there is no information how to view an - * entity. + * The renderable array, key by name key if existing or by numeric id else. + * If there is no information how to view an entity, FALSE is returned. */ function entity_view($entity_type, $entities, $view_mode = 'full', $langcode = NULL) { $info = entity_get_info($entity_type); @@ -298,6 +353,7 @@ function entity_view($entity_type, $entities, $view_mode = 'full', $langcode = N elseif (in_array('EntityAPIControllerInterface', class_implements($info['controller class']))) { return entity_get_controller($entity_type)->view($entities, $view_mode, $langcode); } + return FALSE; } /** @@ -327,6 +383,27 @@ function entity_access($op, $entity_type, $entity = NULL, $account = NULL) { } /** + * Converts an array of entities to be keyed by the values of a given property. + * + * @param array $entities + * The array of entities to convert. + * @param $property + * The name of entity property, by which the array should be keyed. To get + * reasonable results, the property has to have unique values. + * + * @return array + * The same entities in the same order, but keyed by their $property values. + */ +function entity_key_array_by_property(array $entities, $property) { + $ret = array(); + foreach ($entities as $entity) { + $key = isset($entity->$property) ? $entity->$property : NULL; + $ret[$key] = $entity; + } + return $ret; +} + +/** * Returns an array of entity info for the entity types provided via the entity CRUD API. */ function entity_crud_get_info() { @@ -492,11 +569,11 @@ function _entity_defaults_rebuild($entity_type) { drupal_alter($hook, $entities); // Remove defaults which are already overridden. - $overridden_entities = entity_load($entity_type, array_keys($entities), array($keys['status'] => ENTITY_OVERRIDDEN)); + $overridden_entities = entity_load_multiple_by_name($entity_type, array_keys($entities), array($keys['status'] => ENTITY_OVERRIDDEN)); $entities = array_diff_key($entities, $overridden_entities); // Determine already existing, custom entities and mark them as overridden. - $existing_entities = entity_load($entity_type, array_keys($entities), array($keys['status'] => ENTITY_CUSTOM)); + $existing_entities = entity_load_multiple_by_name($entity_type, array_keys($entities), array($keys['status'] => ENTITY_CUSTOM)); foreach ($existing_entities as $name => $entity) { $entity->{$keys['status']} |= ENTITY_OVERRIDDEN; $entity->{$keys['module']} = $entities[$name]->{$keys['module']}; @@ -524,8 +601,20 @@ function _entity_defaults_rebuild($entity_type) { * Implements hook_modules_enabled(). */ function entity_modules_enabled($modules) { + $built_types = variable_get('entity_defaults_built', array()); if ($entity_types = _entity_modules_get_default_types($modules)) { - entity_defaults_rebuild($entity_types); + // Determining the entity types might have triggered rebuilding already, in + // which case we do not need to rebuild again. So we make sure to only + // add entity-types for rebuilding that were not marked for rebuilding + // *before our check* anyway. + foreach ($entity_types as $key => $type) { + if (!isset($built_types[$type])) { + unset($entity_types[$key]); + } + } + if ($entity_types) { + entity_defaults_rebuild($entity_types); + } } } diff --git a/entity.test b/entity.test index 09a2551..d01ee1b 100644 --- a/entity.test +++ b/entity.test @@ -106,19 +106,21 @@ class EntityAPITestCase extends DrupalWebTestCase { function testExportables() { module_enable(array('entity_feature')); - $types = entity_load('entity_test_type', array('test', 'test2')); + $types = entity_load_multiple_by_name('entity_test_type', array('test2', 'test')); + + $this->assertEqual(array_keys($types), array('test2', 'test'), 'Entities have been loaded in the order as specified.'); $this->assertEqual($types['test']->label, 'label', 'Default type loaded.'); $this->assertTrue($types['test']->status & ENTITY_IN_CODE && !($types['test']->status & ENTITY_CUSTOM), 'Default type status is correct.'); // Test using a condition, which has to be applied on the defaults. - $types = entity_load('entity_test_type', FALSE, array('label' => 'label')); + $types = entity_load_multiple_by_name('entity_test_type', FALSE, array('label' => 'label')); $this->assertEqual($types['test']->label, 'label', 'Condition to default type applied.'); $types['test']->label = 'modified'; $types['test']->save(); // Ensure loading the changed entity works. - $types = entity_load('entity_test_type', FALSE, array('label' => 'modified')); + $types = entity_load_multiple_by_name('entity_test_type', FALSE, array('label' => 'modified')); $this->assertEqual($types['test']->label, 'modified', 'Modified type loaded.'); // Clear the cache to simulate a new page load. @@ -126,30 +128,30 @@ class EntityAPITestCase extends DrupalWebTestCase { // Test loading using a condition again, now they default may not appear any // more as it's overridden by an entity with another label. - $types = entity_load('entity_test_type', FALSE, array('label' => 'label')); + $types = entity_load_multiple_by_name('entity_test_type', FALSE, array('label' => 'label')); $this->assertTrue(empty($types), 'Conditions are applied to the overridden entity only.'); // But the overridden entity has to appear with another condition. - $types = entity_load('entity_test_type', FALSE, array('label' => 'modified')); + $types = entity_load_multiple_by_name('entity_test_type', FALSE, array('label' => 'modified')); $this->assertEqual($types['test']->label, 'modified', 'Modified default type loaded by condition.'); - $types = entity_load('entity_test_type', array('test', 'test2')); + $types = entity_load_multiple_by_name('entity_test_type', array('test', 'test2')); $this->assertEqual($types['test']->label, 'modified', 'Modified default type loaded by id.'); $this->assertTrue(entity_has_status('entity_test_type', $types['test'], ENTITY_OVERRIDDEN), 'Status of overridden type is correct.'); // Test rebuilding the defaults and make sure overridden entities stay. entity_defaults_rebuild(); - $types = entity_load('entity_test_type', array('test', 'test2')); + $types = entity_load_multiple_by_name('entity_test_type', array('test', 'test2')); $this->assertEqual($types['test']->label, 'modified', 'Overridden entity is still overridden.'); $this->assertTrue(entity_has_status('entity_test_type', $types['test'], ENTITY_OVERRIDDEN), 'Status of overridden type is correct.'); // Test reverting. $types['test']->delete(); - $types = entity_load('entity_test_type', array('test', 'test2')); + $types = entity_load_multiple_by_name('entity_test_type', array('test', 'test2')); $this->assertEqual($types['test']->label, 'label', 'Entity has been reverted.'); // Test loading an exportable by its numeric id. - $result = entity_load('entity_test_type', array($types['test']->id)); + $result = entity_load_multiple_by_name('entity_test_type', array($types['test']->id)); $this->assertTrue(isset($result['test']), 'Exportable entity loaded by the numeric id.'); // Test exporting an entity to JSON. @@ -174,6 +176,10 @@ class EntityAPITestCase extends DrupalWebTestCase { $this->assertTrue($_SESSION['entity_hook_test']['entity_insert'] == $insert, 'Hook entity_insert has been invoked.'); $this->assertTrue($_SESSION['entity_hook_test']['entity_test_type_insert'] == $insert, 'Hook entity_test_type_insert has been invoked.'); + // Load a default entity and make sure the rebuilt logic only ran once. + entity_load_single('entity_test_type', 'test'); + $this->assertTrue(!isset($_SESSION['entity_hook_test']['entity_test_type_update']), '"Entity-test-type" defaults have been rebuilt only once.'); + // Add a new test entity in DB and make sure the hook is invoked too. $test3 = entity_create('entity_test_type', array( 'name' => 'test3', @@ -187,7 +193,7 @@ class EntityAPITestCase extends DrupalWebTestCase { $this->assertTrue($_SESSION['entity_hook_test']['entity_test_type_insert'] == $insert, 'Hook entity_test_type_insert has been invoked.'); // Now override the 'test' entity and make sure it invokes the update hook. - $result = entity_load('entity_test_type', array('test')); + $result = entity_load_multiple_by_name('entity_test_type', array('test')); $result['test']->label = 'modified'; $result['test']->save(); @@ -202,7 +208,7 @@ class EntityAPITestCase extends DrupalWebTestCase { $this->assertTrue($_SESSION['entity_hook_test']['entity_test_type_delete'] == $delete, 'Hook entity_test_type_deleted has been invoked.'); // Now make sure 'test' is not overridden any more, but custom. - $result = entity_load('entity_test_type', array('test')); + $result = entity_load_multiple_by_name('entity_test_type', array('test')); $this->assertTrue(!$result['test']->hasStatus(ENTITY_OVERRIDDEN), 'Entity is not marked as overridden any more.'); $this->assertTrue(entity_has_status('entity_test_type', $result['test'], ENTITY_CUSTOM), 'Entity is marked as custom.'); @@ -219,7 +225,7 @@ class EntityAPITestCase extends DrupalWebTestCase { */ function testChanges() { module_enable(array('entity_feature')); - $types = entity_load('entity_test_type'); + $types = entity_load_multiple_by_name('entity_test_type'); // Override the default entity, such it gets saved in the DB. $types['test']->label ='test_changes'; @@ -239,7 +245,7 @@ class EntityAPITestCase extends DrupalWebTestCase { $this->assertEqual($types['test']->label, 'updated_presave_update', 'Changes have been determined.'); // Test the static load cache to be cleared. - $types = entity_load('entity_test_type'); + $types = entity_load_multiple_by_name('entity_test_type'); $this->assertEqual($types['test']->label, 'updated_presave', 'Static cache has been cleared.'); } @@ -933,7 +939,7 @@ class EntityMetadataIntegrationTestCase extends DrupalWebTestCase { if ($return === FALSE) { continue; // No support for deleting. } - $return = entity_load($entity_type, array($id)); + $return = entity_load_single($entity_type, $id); $this->assertFalse($return, "$entity_type has been successfully deleted."); } } diff --git a/includes/entity.controller.inc b/includes/entity.controller.inc index 83fe55e..c66b1e7 100644 --- a/includes/entity.controller.inc +++ b/includes/entity.controller.inc @@ -106,7 +106,7 @@ interface EntityAPIControllerInterface extends DrupalEntityControllerInterface { * (optional) A language code to use for rendering. Defaults to the global * content language of the current request. * @return - * The renderable array. + * The renderable array, keyed by entity name or numeric id. */ public function view($entities, $view_mode = 'full', $langcode = NULL); } @@ -117,7 +117,7 @@ interface EntityAPIControllerInterface extends DrupalEntityControllerInterface { */ class EntityAPIController extends DrupalDefaultEntityController implements EntityAPIControllerInterface { - protected $cacheComplete = FALSE; + protected $cacheComplete = FALSE, $entityCacheByName = array(); protected $nameKey, $statusKey, $moduleKey, $bundleKey; /** @@ -217,7 +217,7 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit $queried_entities = array(); foreach ($this->query($ids, $conditions, $revision_id) as $record) { // Skip entities already retrieved from cache. - if (isset($entities[$record->{$this->nameKey}])) { + if (isset($entities[$record->{$this->idKey}])) { continue; } @@ -237,7 +237,7 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit } } - $queried_entities[$record->{$this->nameKey}] = $record; + $queried_entities[$record->{$this->idKey}] = $record; } } @@ -254,7 +254,7 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit if (!empty($queried_entities) && !$revision_id) { $this->cacheSet($queried_entities); - // Remember we have cached all entities now. + // Remember if we have cached all entities now. if (!$conditions && $ids === FALSE) { $this->cacheComplete = TRUE; } @@ -262,15 +262,42 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit } // 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 && $passed_ids = array_intersect_key($passed_ids, $entities)) { + if ($passed_ids) { + if ($this->nameKey != $this->idKey && !is_numeric(key($passed_ids))) { + $entities = entity_key_array_by_property($entities, $this->nameKey); + } + $return = array(); foreach ($passed_ids as $id => $value) { - $passed_ids[$id] = $entities[$id]; + if (isset($entities[$id])) { + $return[$entities[$id]->{$this->idKey}] = $entities[$id]; + } } - $entities = $passed_ids; + $entities = $return; } return $entities; } + /** + * Overridden. + * @see DrupalDefaultEntityController::cacheGet() + */ + protected function cacheGet($ids, $conditions = array()) { + if (!empty($this->entityCache)) { + // First get the entities by ids, then apply the conditions. + if (!is_array($ids)) { + $entities = $this->entityCache; + } + elseif ($this->nameKey != $this->idKey && !is_numeric(reset($ids))) { + $entities = entity_key_array_by_property(array_intersect_key($this->entityCacheByName, array_flip($ids)), $this->idKey); + } + else { + $entities = array_intersect_key($this->entityCache, array_flip($ids)); + } + return $this->applyConditions($entities, $conditions); + } + return array(); + } + protected function applyConditions($entities, $conditions = array()) { if ($conditions) { foreach ($entities as $key => $entity) { @@ -285,37 +312,30 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit /** * Overridden. - * @see includes/DrupalDefaultEntityController#cacheGet($ids, $conditions) - * - * If there is nameKey given, we index our entities by this key. This - * overrides cacheGet() to respect that when applying $conditions. + * @see DrupalDefaultEntityController::cacheSet() */ - protected function cacheGet($ids, $conditions = array()) { - if (!empty($this->entityCache)) { - // First get the entities by ids, then apply the conditions. - $entities = is_array($ids) ? array_intersect_key($this->entityCache, array_flip($ids)) : $this->entityCache; - return $this->applyConditions($entities, $conditions); + protected function cacheSet($entities) { + $this->entityCache += $entities; + if ($this->nameKey != $this->idKey) { + $this->entityCacheByName += entity_key_array_by_property($entities, $this->nameKey); } - return array(); } /** * Overridden. * @see DrupalDefaultEntityController::attachLoad() * - * Fixed to make attaching fields to entities having a name key work. + * Changed to call type-specific hook with the entities keyed by name if they + * have one. */ protected function attachLoad(&$queried_entities, $revision_id = FALSE) { // Attach fields. if ($this->entityInfo['fieldable']) { - // Field API assumes queried entities are keyed by the idkey, thus - // adapt the array accordingly for it. - $entities = $this->getEntitiesKeyedByNumericID($queried_entities); if ($revision_id) { - field_attach_load_revision($this->entityType, $entities); + field_attach_load_revision($this->entityType, $queried_entities); } else { - field_attach_load($this->entityType, $entities); + field_attach_load($this->entityType, $queried_entities); } } @@ -327,29 +347,34 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit // Call hook_TYPE_load(). The first argument for hook_TYPE_load() are // always the queried entities, followed by additional arguments set in // $this->hookLoadArguments. - $args = array_merge(array($queried_entities), $this->hookLoadArguments); + // For entities with a name key, pass the entities keyed by name to the + // specific load hook. + if ($this->nameKey != $this->idKey) { + $entities_by_name = entity_key_array_by_property($queried_entities, $this->nameKey); + } + else { + $entities_by_name = $queried_entities; + } + $args = array_merge(array($entities_by_name), $this->hookLoadArguments); foreach (module_implements($this->entityInfo['load hook']) as $module) { call_user_func_array($module . '_' . $this->entityInfo['load hook'], $args); } } - /** - * Converts an array of entities in an array of entities keyed by numeric id, i.e. by id key. - */ - protected function getEntitiesKeyedByNumericID($entities) { - if ($this->nameKey != $this->idKey) { - $result = array(); - foreach ($entities as $entity) { - $result[$entity->{$this->idKey}] = $entity; - } - return $result; - } - return $entities; - } - public function resetCache(array $ids = NULL) { $this->cacheComplete = FALSE; - parent::resetCache($ids); + if (isset($ids)) { + foreach ($ids as $id) { + if (isset($this->entityCache[$id])) { + unset($this->entityCacheByName[$this->entityCache[$id]->{$this->nameKey}]); + unset($this->entityCache[$id]); + } + } + } + else { + $this->entityCache = array(); + $this->entityCacheByName = array(); + } } /** @@ -404,8 +429,10 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit $transaction = isset($transaction) ? $transaction : db_transaction(); try { + $ids = array_keys($entities); + db_delete($this->entityInfo['base table']) - ->condition($this->nameKey, array_keys($entities), 'IN') + ->condition($this->idKey, $ids, 'IN') ->execute(); // Reset the cache as soon as the changes have been applied. $this->resetCache($ids); @@ -458,7 +485,7 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit if (!empty($entity->{$this->idKey}) && empty($entity->is_new)) { $return = drupal_write_record($this->entityInfo['base table'], $entity, $this->idKey); - $this->resetCache(array($entity->{$this->nameKey})); + $this->resetCache(array($entity->{$this->idKey})); $this->invoke('update', $entity); } else { @@ -553,20 +580,22 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit * Implements EntityAPIControllerInterface. */ public function view($entities, $view_mode = 'full', $langcode = NULL) { + // For Field API and entity_prepare_view, the entities have to be keyed by + // (numeric) id. + $entities = entity_key_array_by_property($entities, $this->idKey); if (!empty($this->entityInfo['fieldable'])) { - // Field API assumes queried entities are keyed by the idkey, thus - // adapt the array accordingly for it. - field_attach_prepare_view($this->entityType, $this->getEntitiesKeyedByNumericID($entities), $view_mode); + field_attach_prepare_view($this->entityType, $entities, $view_mode); } entity_prepare_view($this->entityType, $entities); $langcode = isset($langcode) ? $langcode : $GLOBALS['language_content']->language; $view = array(); - foreach ($entities as $key => $entity) { + foreach ($entities as $entity) { $build = entity_build_content($this->entityType, $entity, $view_mode, $langcode); $build += array( // If the entity type provides an implementation, use this instead the // generic one. + // @see template_preprocess_entity() '#theme' => 'entity', '#entity_type' => $this->entityType, '#entity' => $entity, @@ -575,9 +604,9 @@ class EntityAPIController extends DrupalDefaultEntityController implements Entit ); // Allow modules to modify the structured entity. drupal_alter(array($this->entityType . '_view', 'entity_view'), $build, $this->entityType); + $key = isset($entity->{$this->nameKey}) ? $entity->{$this->nameKey} : NULL; $view[$this->entityType][$key] = $build; } return $view; } - } diff --git a/includes/entity.inc b/includes/entity.inc index 89903cd..5bbbaf7 100644 --- a/includes/entity.inc +++ b/includes/entity.inc @@ -48,21 +48,21 @@ class Entity { /** * Returns the internal, numeric identifier. * - * For exportable entities, this differs to the uniform identifier returned - * by Entity::identifier(). The internal identifier is supposed to be only - * used internally to refer to an entity, i.e. in the database. If unsure, use - * Entity:identifier(). + * Returns the numeric identifier, even if the entity type has specified a + * name key. In the latter case, the numeric identifier is supposed to be used + * when dealing generically with entities or internally to refer to an entity, + * i.e. in a relational database. If unsure, use Entity:identifier(). */ public function internalIdentifier() { return isset($this->{$this->idKey}) ? $this->{$this->idKey} : NULL; } /** - * Returns the unified identifer. + * Returns the entity identifier, i.e. the entities name or numeric id. * * @return - * The identifier of the entity. For exportable entities, this is their - * machine readable name. + * The identifier of the entity. If the entity type makes use of a name key, + * the name is returned, else the numeric id. * * @see entity_id() */ @@ -188,7 +188,7 @@ class Entity { * @see entity_view() */ public function view($view_mode = 'full', $langcode = NULL) { - return entity_get_controller($this->entityType)->view(array($this->identifier() => $this), $view_mode, $langcode); + return entity_get_controller($this->entityType)->view(array($this), $view_mode, $langcode); } /** diff --git a/tests/entity_test.module b/tests/entity_test.module index c1cf2d5..77baf72 100644 --- a/tests/entity_test.module +++ b/tests/entity_test.module @@ -66,11 +66,8 @@ function entity_test_entity_info_alter(&$entity_info) { * If set, the type with the given name is returned. */ function entity_test_get_types($name = NULL) { - $types = entity_load('entity_test_type', isset($name) ? array($name) : FALSE); - if (isset($name)) { - return isset($types[$name]) ? $types[$name] : FALSE; - } - return $types; + $types = entity_load_multiple_by_name('entity_test_type', isset($name) ? array($name) : FALSE); + return isset($name) ? reset($types) : $types; } /**