Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.1210 diff -u -p -r1.1210 common.inc --- includes/common.inc 22 Aug 2010 12:46:21 -0000 1.1210 +++ includes/common.inc 26 Aug 2010 14:46:49 -0000 @@ -6718,6 +6718,31 @@ function entity_uri($entity_type, $entit } /** + * Returns the label of an entity. + * + * @param $entity_type + * The entity type; e.g. 'node' or 'user'. + * @param $entity + * The entity for which to generate a path. + * + * @return + * A string with the entity label (e.g. node title), or FALSE if not found. + */ +function entity_label($entity_type, $entity) { + $label = FALSE; + $info = entity_get_info($entity_type); + if (isset($info['label callback']) && function_exists($info['label callback'])) { + $label = $info['label callback']($entity); + } + elseif (!empty($info['entity keys']['label']) && isset($entity->{$info['entity keys']['label']})) { + $label = $entity->{$info['entity keys']['label']}; + } + + return $label; +} + + +/** * Helper function for attaching field API validation to entity forms. */ function entity_form_field_validate($entity_type, $form, &$form_state) { Index: modules/comment/comment.module =================================================================== RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v retrieving revision 1.892 diff -u -p -r1.892 comment.module --- modules/comment/comment.module 23 Aug 2010 14:53:50 -0000 1.892 +++ modules/comment/comment.module 26 Aug 2010 14:46:50 -0000 @@ -103,6 +103,7 @@ function comment_entity_info() { 'entity keys' => array( 'id' => 'cid', 'bundle' => 'node_type', + 'label' => 'subject', ), 'bundles' => array(), 'view modes' => array( Index: modules/field/tests/field.test =================================================================== RCS file: /cvs/drupal/drupal/modules/field/tests/field.test,v retrieving revision 1.39 diff -u -p -r1.39 field.test --- modules/field/tests/field.test 18 Aug 2010 00:44:52 -0000 1.39 +++ modules/field/tests/field.test 26 Aug 2010 14:46:50 -0000 @@ -2988,3 +2988,52 @@ class FieldBulkDeleteTestCase extends Fi $this->assertEqual(count($fields), 0, 'The field is purged.'); } } + + +/** + * Test properties of entity. + */ +class EntityProperties extends FieldTestCase { + public static function getInfo() { + return array( + 'name' => 'Entity tests', + 'description'=> 'Test entity functionality.', + 'group' => 'System', + ); + } + + function setUp() { + parent::setUp('field_test'); + } + + /** + * Test label key and label callback of an entity. + */ + function testEntityLabel() { + $entity_types = array( + 'test_entity_no_label', + 'test_entity_label', + 'test_entity_label_callback', + ); + + $entity = field_test_create_stub_entity(); + + foreach ($entity_types as $entity_type) { + $label = entity_label($entity_type, $entity); + + switch ($entity_type) { + case 'test_entity_no_label': + $this->assertFalse($label, 'Entity with no label property or callback returned FALSE.'); + break; + + case 'test_entity_label': + $this->assertEqual($label, $entity->ftlabel, 'Entity with label key returned correct label.'); + break; + + case 'test_entity_label_callback': + $this->assertEqual($label, 'label callback ' . $entity->ftlabel, 'Entity with label callback returned correct label.'); + break; + } + } + } +} Index: modules/field/tests/field_test.entity.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/field/tests/field_test.entity.inc,v retrieving revision 1.12 diff -u -p -r1.12 field_test.entity.inc --- modules/field/tests/field_test.entity.inc 17 Jun 2010 13:44:45 -0000 1.12 +++ modules/field/tests/field_test.entity.inc 26 Aug 2010 14:46:50 -0000 @@ -73,6 +73,50 @@ function field_test_entity_info() { 'bundles' => array('test_entity_2' => array('label' => 'Test entity 2')), 'view modes' => $test_entity_modes, ), + + 'test_entity_no_label' => array( + 'name' => t('Test entity without label'), + 'fieldable' => TRUE, + 'field cache' => FALSE, + 'base table' => 'test_entity', + 'entity keys' => array( + 'id' => 'ftid', + 'revision' => 'ftvid', + 'bundle' => 'fttype', + ), + 'bundles' => $bundles, + 'view modes' => $test_entity_modes, + ), + 'test_entity_label' => array( + 'name' => t('Test entity label'), + 'fieldable' => TRUE, + 'field cache' => FALSE, + 'base table' => 'test_entity', + 'entity keys' => array( + 'id' => 'ftid', + 'revision' => 'ftvid', + 'bundle' => 'fttype', + 'label' => 'ftlabel', + ), + 'bundles' => $bundles, + 'view modes' => $test_entity_modes, + ), + 'test_entity_label_callback' => array( + 'name' => t('Test entity label callback'), + 'fieldable' => TRUE, + 'field cache' => FALSE, + 'base table' => 'test_entity', + 'label callback' => 'field_test_entity_label_callback', + 'entity keys' => array( + 'id' => 'ftid', + 'revision' => 'ftvid', + 'bundle' => 'fttype', + ), + 'bundles' => $bundles, + 'view modes' => $test_entity_modes, + ), + + ); } @@ -163,7 +207,7 @@ function field_test_delete_bundle($bundle) { /** * Creates a basic test_entity entity. */ -function field_test_create_stub_entity($id = 1, $vid = 1, $bundle = 'test_bundle') { +function field_test_create_stub_entity($id = 1, $vid = 1, $bundle = 'test_bundle', $label = '') { $entity = new stdClass(); // Only set id and vid properties if they don't come as NULL (creation form). if (isset($id)) { @@ -174,6 +218,9 @@ function field_test_create_stub_entity($ } $entity->fttype = $bundle; + $label = !empty($label) ? $label : $bundle . ' label'; + $entity->ftlabel = $label; + return $entity; } Index: modules/field/tests/field_test.install =================================================================== RCS file: /cvs/drupal/drupal/modules/field/tests/field_test.install,v retrieving revision 1.3 diff -u -p -r1.3 field_test.install --- modules/field/tests/field_test.install 14 Jun 2010 15:41:02 -0000 1.3 +++ modules/field/tests/field_test.install 26 Aug 2010 14:46:50 -0000 @@ -44,6 +44,13 @@ function field_test_schema() { 'not null' => TRUE, 'default' => '', ), + 'ftlabel' => array( + 'description' => 'The label of this test_entity.', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), ), 'unique keys' => array( 'ftvid' => array('ftvid'), Index: modules/field/tests/field_test.module =================================================================== RCS file: /cvs/drupal/drupal/modules/field/tests/field_test.module,v retrieving revision 1.9 diff -u -p -r1.9 field_test.module --- modules/field/tests/field_test.module 8 Aug 2010 02:18:53 -0000 1.9 +++ modules/field/tests/field_test.module 26 Aug 2010 14:46:50 -0000 @@ -214,3 +214,16 @@ function field_test_dummy_field_storage_ ), ); } + +/** + * Entity label callback. + * + * @param $entity + * The entity object. + * + * @return + * The label of the entity prefixed with "label callback". + */ +function field_test_entity_label_callback($entity) { + return 'label callback ' . $entity->ftlabel; +} \ No newline at end of file Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.1293 diff -u -p -r1.1293 node.module --- modules/node/node.module 23 Aug 2010 22:15:34 -0000 1.1293 +++ modules/node/node.module 26 Aug 2010 14:46:50 -0000 @@ -181,6 +181,7 @@ function node_entity_info() { 'id' => 'nid', 'revision' => 'vid', 'bundle' => 'type', + 'label' => 'title', ), 'bundle keys' => array( 'bundle' => 'type', Index: modules/system/system.api.php =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.api.php,v retrieving revision 1.187 diff -u -p -r1.187 system.api.php --- modules/system/system.api.php 22 Aug 2010 13:55:53 -0000 1.187 +++ modules/system/system.api.php 26 Aug 2010 14:46:51 -0000 @@ -87,6 +87,11 @@ function hook_hook_info_alter(&$hooks) { * - uri callback: A function taking an entity as argument and returning the * uri elements of the entity, e.g. 'path' and 'options'. The actual entity * uri can be constructed by passing these elements to url(). + * - label callback: Optional; A function taking an entity as argument and + * returning the label of the entity, e.g. the title of a node, or the + * subject of a comment. This property can be used when the label is a + * result of complex logic, otherwise the "label" property under + * the "entity keys" array, should be used. * - fieldable: Set to TRUE if you want your entity type to be fieldable. * - entity keys: An array describing how the Field API can extract the * information it needs from the objects of the type. Elements: @@ -103,6 +108,11 @@ function hook_hook_info_alter(&$hooks) { * omitted if this entity type exposes a single bundle (all entities have * the same collection of fields). The name of this single bundle will be * the same as the entity type. + * - label: The name of the property that contains the entity label. For + * example, the value of this property in the node entity will be 'title'. + * Note that it is possible that an entity label is a result of more + * complex logic, in such a case the "label callback" should be used. + * see entity_label(). * - bundle keys: An array describing how the Field API can extract the * information it needs from the bundle objects for this type (e.g * $vocabulary objects for terms; not applicable for nodes). This entry can Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.957 diff -u -p -r1.957 system.module --- modules/system/system.module 22 Aug 2010 13:52:58 -0000 1.957 +++ modules/system/system.module 26 Aug 2010 14:46:51 -0000 @@ -264,6 +264,7 @@ function system_entity_info() { 'base table' => 'file_managed', 'entity keys' => array( 'id' => 'fid', + 'label' => 'filename', ), 'static cache' => FALSE, ), Index: modules/taxonomy/taxonomy.module =================================================================== RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v retrieving revision 1.603 diff -u -p -r1.603 taxonomy.module --- modules/taxonomy/taxonomy.module 22 Aug 2010 15:45:03 -0000 1.603 +++ modules/taxonomy/taxonomy.module 26 Aug 2010 14:46:51 -0000 @@ -100,6 +100,7 @@ function taxonomy_entity_info() { 'entity keys' => array( 'id' => 'tid', 'bundle' => 'vocabulary_machine_name', + 'label' => 'name', ), 'bundle keys' => array( 'bundle' => 'machine_name', @@ -131,6 +132,7 @@ function taxonomy_entity_info() { 'base table' => 'taxonomy_vocabulary', 'entity keys' => array( 'id' => 'vid', + 'label' => 'name', ), 'fieldable' => FALSE, ); Index: modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.1196 diff -u -p -r1.1196 user.module --- modules/user/user.module 26 Aug 2010 09:14:33 -0000 1.1196 +++ modules/user/user.module 26 Aug 2010 14:46:51 -0000 @@ -146,6 +146,7 @@ function user_entity_info() { 'controller class' => 'UserController', 'base table' => 'users', 'uri callback' => 'user_uri', + 'label callback' => 'user_label', 'fieldable' => TRUE, 'entity keys' => array( 'id' => 'uid', @@ -180,6 +181,20 @@ function user_uri($user) { } /** + * Entity label callback. + * + * @param $account + * The user object. + * @return + * The user name, using format_username(). + * + * @see entity_label() + */ +function user_label($account) { + return format_username($account); +} + +/** * Implements hook_field_extra_fields(). */ function user_field_extra_fields() {