Commit 65f364ed authored by fago's avatar fago

#1093918 improve entity property query support

parent d65122b0
......@@ -261,8 +261,12 @@ function entity_metadata_hook_entity_info() {
* - 'setter permission': Optionally a permission, that describes whether
* a user has permission to set ('edit') this property. This permission
* should only be taken into account, if no 'access callback' is given.
* - 'schema field': (optional) In case the property is directly based upon
* a field specified in the entity's hook_schema(), the name of the field.
* - 'query callback: Optionally a callback for querying for entities
* having the given property value. See entity_metadata_entity_query().
* having the given property value. See entity_property_query().
* In case a 'schema field' has been specified, it is not necessary to
* specify a callback as it will default to 'entity_metadata_table_query'.
* - required: Optionally, this may be set to TRUE, if this property is
* required for the creation of a new instance of its entity. See
* entity_property_values_create_entity().
......
......@@ -130,7 +130,7 @@ function entity_metadata_convert_schema($table) {
$properties[$name] = array(
'type' => $type,
'label' => drupal_ucfirst($name),
'query callback' => 'entity_metadata_table_query',
'schema field' => $name,
// As we cannot know about any setter access, leave out the setter
// callback. For getting usually no further access callback is needed.
);
......
......@@ -596,13 +596,16 @@ class EntityMetadataTestCase extends DrupalWebTestCase {
function testEntityQuery() {
$title = '<b>Is it bold?<b>';
$values[LANGUAGE_NONE][0] = array('value' => 'foo');
$node = $this->drupalCreateNode(array($this->field_name => $values, 'title' => $title));
$node = $this->drupalCreateNode(array($this->field_name => $values, 'title' => $title, 'uid' => $GLOBALS['user']->uid));
$results = entity_property_query('node', 'title', $title);
$this->assertEqual($results, array($node->nid), 'Queried nodes with a given title.');
$results = entity_property_query('node', $this->field_name, 'foo');
$this->assertEqual($results, array($node->nid), 'Queried nodes with a given field value.');
$results = entity_property_query('node', 'author', $GLOBALS['user']);
$this->assertEqual($results, array($node->nid), 'Queried nodes with a given auhtor.');
}
/**
......
......@@ -93,8 +93,14 @@ function entity_get_all_property_info($entity_type = NULL) {
*/
function entity_property_query($entity_type, $property, $value, $limit = 30) {
$properties = entity_get_all_property_info($entity_type);
if (isset($properties[$property]['query callback'])) {
return $properties[$property]['query callback']($entity_type, $property, $value, $limit);
$info = $properties[$property] + array('type' => 'text', 'query callback' => isset($properties[$property]['schema field']) ? 'entity_metadata_table_query' : FALSE);
// Make sure an entity or a list of entities are passed on as identifiers.
$wrapper = entity_metadata_wrapper($info['type'], $value);
$value = $wrapper->value(array('identifier' => TRUE));
if (!empty($info['query callback'])) {
return $info['query callback']($entity_type, $property, $value, $limit);
}
}
......
......@@ -649,7 +649,7 @@ class EntityDrupalWrapper extends EntityStructureWrapper {
* @see entity_id()
*/
public function getIdentifier() {
return $this->dataAvailable() && $this->value() ? $this->id : NULL;
return $this->dataAvailable() ? $this->value(array('identifier' => TRUE)) : NULL;
}
/**
......@@ -664,10 +664,17 @@ class EntityDrupalWrapper extends EntityStructureWrapper {
/**
* Overridden.
*
* @param $options
* An array of options. Known keys:
* - identifier: If set to TRUE, the entity identifier is returned.
*/
public function value(array $options = array()) {
$this->setEntity(parent::value());
if (!$this->data && !empty($this->id)) {
if (!empty($options['identifier'])) {
return $this->id;
}
elseif (!$this->data && !empty($this->id)) {
// Lazy load the entity if necessary.
$return = entity_load($this->type, array($this->id));
$this->data = reset($return);
......@@ -878,8 +885,8 @@ class EntityListWrapper extends EntityMetadataWrapper implements IteratorAggrega
/**
* @param $options
* An array of options. Known keys:
* identifier: If set to TRUE for a list of entities, it won't be returned
* as list of fully loaded entity objects, but as a list of entity ids.
* - identifier: If set to TRUE for a list of entities, it won't be returned
* as list of fully loaded entity objects, but as a list of entity ids.
*/
public function value(array $options = array()) {
// For lists of entities fetch full entity objects before returning.
......
......@@ -727,9 +727,12 @@ function entity_metadata_view_single($entities, $view_mode = 'full', $langcode =
* entities main db table.
*/
function entity_metadata_table_query($entity_type, $property, $value, $limit) {
$properties = entity_get_all_property_info($entity_type);
$info = $properties[$property] + array('schema field' => $property);
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', $entity_type, '=')
->propertyCondition($property, $value, '=')
->propertyCondition($info['schema field'], $value, '=')
->range(0, $limit);
$result = $query->execute();
......
......@@ -18,10 +18,12 @@ function entity_metadata_comment_entity_property_info() {
'label' => t("Comment ID"),
'type' => 'integer',
'description' => t("The unique ID of the comment."),
'schema field' => 'cid',
);
$properties['hostname'] = array(
'label' => t("IP Address"),
'description' => t("The IP address of the computer the comment was posted from."),
'schema field' => 'hostname',
);
$properties['name'] = array(
'label' => t("Name"),
......@@ -30,6 +32,7 @@ function entity_metadata_comment_entity_property_info() {
'setter callback' => 'entity_property_verbatim_set',
'setter permission' => 'administer comments',
'sanitize' => 'filter_xss',
'schema field' => 'name',
);
$properties['mail'] = array(
'label' => t("Email address"),
......@@ -38,6 +41,7 @@ function entity_metadata_comment_entity_property_info() {
'setter callback' => 'entity_property_verbatim_set',
'setter permission' => 'administer comments',
'validation callback' => 'valid_email_address',
'schema field' => 'mail',
);
$properties['homepage'] = array(
'label' => t("Home page"),
......@@ -45,6 +49,7 @@ function entity_metadata_comment_entity_property_info() {
'sanitize' => 'filter_xss_bad_protocol',
'setter callback' => 'entity_property_verbatim_set',
'setter permission' => 'administer comments',
'schema field' => 'homepage',
);
$properties['subject'] = array(
'label' => t("Subject"),
......@@ -53,6 +58,7 @@ function entity_metadata_comment_entity_property_info() {
'setter permission' => 'administer comments',
'sanitize' => 'filter_xss',
'required' => TRUE,
'schema field' => 'subject',
);
$properties['url'] = array(
'label' => t("URL"),
......@@ -72,12 +78,14 @@ function entity_metadata_comment_entity_property_info() {
'type' => 'date',
'setter callback' => 'entity_property_verbatim_set',
'setter permission' => 'administer comments',
'schema field' => 'created',
);
$properties['parent'] = array(
'label' => t("Parent"),
'description' => t("The comment's parent, if comment threading is active."),
'type' => 'comment',
'getter callback' => 'entity_metadata_comment_get_properties',
'schema field' => 'pid',
);
$properties['node'] = array(
'label' => t("Node"),
......@@ -87,6 +95,7 @@ function entity_metadata_comment_entity_property_info() {
'setter callback' => 'entity_metadata_comment_setter',
'setter permission' => 'administer comments',
'required' => TRUE,
'schema field' => 'nid',
);
$properties['author'] = array(
'label' => t("Author"),
......@@ -96,6 +105,7 @@ function entity_metadata_comment_entity_property_info() {
'setter callback' => 'entity_metadata_comment_setter',
'setter permission' => 'administer comments',
'required' => TRUE,
'schema field' => 'uid',
);
return $info;
}
......
......@@ -18,13 +18,13 @@ function entity_metadata_node_entity_property_info() {
'label' => t("Node ID"),
'type' => 'integer',
'description' => t("The unique ID of the node."),
'query callback' => 'entity_metadata_table_query',
'schema field' => 'nid',
);
$properties['vid'] = array(
'label' => t("Revision ID"),
'type' => 'integer',
'description' => t("The unique ID of the node's revision."),
'query callback' => 'entity_metadata_table_query',
'schema field' => 'vid',
);
$properties['is_new'] = array(
'label' => t("Is new"),
......@@ -40,13 +40,13 @@ function entity_metadata_node_entity_property_info() {
'setter permission' => 'administer nodes',
'options list' => 'node_type_get_names',
'required' => TRUE,
'query callback' => 'entity_metadata_table_query',
'schema field' => 'type',
);
$properties['title'] = array(
'label' => t("Title"),
'description' => t("The title of the node."),
'setter callback' => 'entity_property_verbatim_set',
'query callback' => 'entity_metadata_table_query',
'schema field' => 'title',
'required' => TRUE,
);
$properties['language'] = array(
......@@ -54,7 +54,7 @@ function entity_metadata_node_entity_property_info() {
'description' => t("The language the node is written in."),
'setter callback' => 'entity_property_verbatim_set',
'options list' => 'entity_metadata_language_list',
'query callback' => 'entity_metadata_table_query',
'schema field' => 'language',
'setter permission' => 'administer nodes',
);
$properties['url'] = array(
......@@ -74,7 +74,7 @@ function entity_metadata_node_entity_property_info() {
'description' => t("Whether the node is published."),
'setter callback' => 'entity_property_verbatim_set',
'setter permission' => 'administer nodes',
'query callback' => 'entity_metadata_table_query',
'schema field' => 'status',
'type' => 'boolean',
);
$properties['promote'] = array(
......@@ -82,7 +82,7 @@ function entity_metadata_node_entity_property_info() {
'description' => t("Whether the node is promoted to the frontpage."),
'setter callback' => 'entity_property_verbatim_set',
'setter permission' => 'administer nodes',
'query callback' => 'entity_metadata_table_query',
'schema field' => 'promote',
'type' => 'boolean',
);
$properties['sticky'] = array(
......@@ -90,7 +90,7 @@ function entity_metadata_node_entity_property_info() {
'description' => t("Whether the node is displayed at the top of lists in which it appears."),
'setter callback' => 'entity_property_verbatim_set',
'setter permission' => 'administer nodes',
'query callback' => 'entity_metadata_table_query',
'schema field' => 'sticky',
'type' => 'boolean',
);
$properties['created'] = array(
......@@ -99,12 +99,12 @@ function entity_metadata_node_entity_property_info() {
'description' => t("The date the node was posted."),
'setter callback' => 'entity_property_verbatim_set',
'setter permission' => 'administer nodes',
'query callback' => 'entity_metadata_table_query',
'schema field' => 'created',
);
$properties['changed'] = array(
'label' => t("Date changed"),
'type' => 'date',
'query callback' => 'entity_metadata_table_query',
'schema field' => 'changed',
'description' => t("The date the node was most recently updated."),
);
$properties['author'] = array(
......@@ -115,6 +115,7 @@ function entity_metadata_node_entity_property_info() {
'setter callback' => 'entity_metadata_node_set_properties',
'setter permission' => 'administer nodes',
'required' => TRUE,
'schema field' => 'uid',
);
$properties['source'] = array(
'label' => t("Translation source node"),
......
......@@ -88,23 +88,27 @@ function entity_metadata_system_entity_property_info() {
'description' => t("The unique ID of the uploaded file."),
'type' => 'integer',
'validation callback' => 'entity_metadata_validate_integer_positive',
'schema field' => 'fid',
);
$properties['name'] = array(
'label' => t("File name"),
'description' => t("The name of the file on disk."),
'getter callback' => 'entity_metadata_system_get_file_properties',
'schema field' => 'filename',
);
$properties['mime'] = array(
'label' => t("MIME type"),
'description' => t("The MIME type of the file."),
'getter callback' => 'entity_metadata_system_get_file_properties',
'sanitize' => 'filter_xss',
'schema field' => 'filemime',
);
$properties['size'] = array(
'label' => t("File size"),
'description' => t("The size of the file, in kilobytes."),
'getter callback' => 'entity_metadata_system_get_file_properties',
'type' => 'integer',
'schema field' => 'filesize',
);
$properties['url'] = array(
'label' => t("URL"),
......@@ -115,12 +119,14 @@ function entity_metadata_system_entity_property_info() {
'label' => t("Timestamp"),
'description' => t("The date the file was most recently changed."),
'type' => 'date',
'schema field' => 'timestamp',
);
$properties['owner'] = array(
'label' => t("Owner"),
'description' => t("The user who originally uploaded the file."),
'type' => 'user',
'getter callback' => 'entity_metadata_system_get_file_properties',
'schema field' => 'uid',
);
return $info;
}
......@@ -18,12 +18,14 @@ function entity_metadata_taxonomy_entity_property_info() {
'label' => t("Term ID"),
'description' => t("The unique ID of the taxonomy term."),
'type' => 'integer',
'schema field' => 'tid',
);
$properties['name'] = array(
'label' => t("Name"),
'description' => t("The name of the taxonomy term."),
'setter callback' => 'entity_property_verbatim_set',
'required' => TRUE,
'schema field' => 'name',
);
$properties['description'] = array(
'label' => t("Description"),
......@@ -32,12 +34,14 @@ function entity_metadata_taxonomy_entity_property_info() {
'raw getter callback' => 'entity_property_verbatim_get',
'getter callback' => 'entity_metadata_taxonomy_term_get_properties',
'setter callback' => 'entity_property_verbatim_set',
'schema field' => 'description',
);
$properties['weight'] = array(
'label' => t("Weight"),
'type' => 'integer',
'description' => t('The weight of the term, which is used for ordering terms during display.'),
'setter callback' => 'entity_property_verbatim_set',
'schema field' => 'weight',
);
$properties['node_count'] = array(
'label' => t("Node count"),
......@@ -58,6 +62,7 @@ function entity_metadata_taxonomy_entity_property_info() {
'setter callback' => 'entity_metadata_taxonomy_term_setter',
'type' => 'taxonomy_vocabulary',
'required' => TRUE,
'schema field' => 'vid',
);
$properties['parent'] = array(
'label' => t("Parent terms"),
......@@ -75,12 +80,14 @@ function entity_metadata_taxonomy_entity_property_info() {
'label' => t("Vocabulary ID"),
'description' => t("The unique ID of the taxonomy vocabulary."),
'type' => 'integer',
'schema field' => 'vid',
);
$properties['name'] = array(
'label' => t("Name"),
'description' => t("The name of the taxonomy vocabulary."),
'setter callback' => 'entity_property_verbatim_set',
'required' => TRUE,
'schema field' => 'name',
);
$properties['machine_name'] = array(
'label' => t("Machine name"),
......@@ -88,12 +95,14 @@ function entity_metadata_taxonomy_entity_property_info() {
'description' => t("The machine name of the taxonomy vocabulary."),
'setter callback' => 'entity_property_verbatim_set',
'required' => TRUE,
'schema field' => 'machine_name',
);
$properties['description'] = array(
'label' => t("Description"),
'description' => t("The optional description of the taxonomy vocabulary."),
'setter callback' => 'entity_property_verbatim_set',
'sanitize' => 'filter_xss',
'schema field' => 'description',
);
$properties['term_count'] = array(
'label' => t("Term count"),
......
......@@ -18,6 +18,7 @@ function entity_metadata_user_entity_property_info() {
'label' => t("User ID"),
'type' => 'integer',
'description' => t("The unique ID of the user account."),
'schema field' => 'uid',
);
$properties['name'] = array(
'label' => t("Name"),
......@@ -27,6 +28,7 @@ function entity_metadata_user_entity_property_info() {
'sanitize' => 'filter_xss',
'required' => TRUE,
'access callback' => 'entity_metadata_user_properties_access',
'schema field' => 'name',
);
$properties['mail'] = array(
'label' => t("Email"),
......@@ -35,6 +37,7 @@ function entity_metadata_user_entity_property_info() {
'validation callback' => 'valid_email_address',
'required' => TRUE,
'access callback' => 'entity_metadata_user_properties_access',
'schema field' => 'mail',
);
$properties['url'] = array(
'label' => t("URL"),
......@@ -53,11 +56,13 @@ function entity_metadata_user_entity_property_info() {
'description' => t("The date the user last logged in to the site."),
'getter callback' => 'entity_metadata_user_get_properties',
'type' => 'date',
'schema field' => 'login',
);
$properties['created'] = array(
'label' => t("Created"),
'description' => t("The date the user account was created."),
'type' => 'date',
'schema field' => 'created',
);
$properties['roles'] = array(
'label' => t("User roles"),
......
......@@ -37,8 +37,8 @@ function entity_views_data() {
* based upon the schema information of its base table and the provided entity
* property information.
* For that it is possible to map a property name to its schema/views field
* name by adding a 'views field' key with the name of the field as value to the
* property info.
* name by adding a 'schema field' key with the name of the field as value to
* the property info.
*/
class EntityDefaultViewsController {
......@@ -86,9 +86,11 @@ class EntityDefaultViewsController {
$data = array();
foreach ($properties['properties'] as $name => $property_info) {
$views_field_name = isset($property_info['views field']) ? $property_info['views field'] : $name;
// For backward compatibility, also read from 'views field'.
$views_field_name = isset($property_info['schema field']) ? $property_info['schema field'] : (isset($property_info['views field']) ? $property_info['views field'] : $name);
if (isset($schema['fields'][$views_field_name])) {
if ($views_info = $this->map_from_schema_info($name, $schema['fields'][$views_field_name], $property_info)) {
if ($views_info = $this->map_from_schema_info($views_field_name, $schema['fields'][$views_field_name], $property_info)) {
$data[$name] = $views_info + array(
'title' => $property_info['label'],
'help' => $property_info['description'],
......@@ -103,9 +105,8 @@ class EntityDefaultViewsController {
* Comes up with views information based on the given schema and property
* info.
*/
protected function map_from_schema_info($name, $schema_field_info, $property_info) {
protected function map_from_schema_info($views_field_name, $schema_field_info, $property_info) {
$type = isset($property_info['type']) ? $property_info['type'] : 'text';
$views_field_name = isset($property_info['views field']) ? $property_info['views field'] : $name;
// Add in relationships to related entities.
if (($info = entity_get_info($type)) && !empty($info['base table'])) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment