- Patch #938462 by bojanz: Fix EntityFieldQuery fatal error in certain cases and document bundle limitations.

merge-requests/26/head
Dries Buytaert 2010-11-05 19:57:28 +00:00
parent 4a110ab715
commit 4a5e9447c0
3 changed files with 57 additions and 10 deletions

View File

@ -549,6 +549,10 @@ class EntityFieldQuery {
*
* 'bundle', 'revision_id' and 'entity_id' have no such restrictions.
*
* Note: The "comment" and "taxonomy_term" entity types don't support bundle
* conditions. For "taxonomy_term", propertyCondition('vid') can be used
* instead.
*
* @param $name
* 'entity_type', 'bundle', 'revision_id' or 'entity_id'.
* @param $value
@ -680,6 +684,9 @@ class EntityFieldQuery {
* If called multiple times, the query will order by each specified column in
* the order this method is called.
*
* Note: The "comment" and "taxonomy_term" entity types don't support ordering
* by bundle. For "taxonomy_term", propertyOrderBy('vid') can be used instead.
*
* @param $name
* 'entity_type', 'bundle', 'revision_id' or 'entity_id'.
* @param $direction
@ -965,6 +972,7 @@ class EntityFieldQuery {
throw new EntityFieldQueryException(t('Entity %entity has no base table.', array('%entity' => $entity_type)));
}
$base_table = $entity_info['base table'];
$base_table_schema = drupal_get_schema($base_table);
$select_query = db_select($base_table);
$select_query->addExpression(':entity_type', 'entity_type', array(':entity_type' => $entity_type));
// Process the property conditions.
@ -997,8 +1005,11 @@ class EntityFieldQuery {
// Handle bundles.
if (!empty($entity_info['entity keys']['bundle'])) {
$sql_field = $entity_info['entity keys']['bundle'];
$select_query->addField($base_table, $sql_field, 'bundle');
$having = FALSE;
if (!empty($base_table_schema['fields'][$sql_field])) {
$select_query->addField($base_table, $sql_field, 'bundle');
}
}
else {
$sql_field = 'bundle';
@ -1057,7 +1068,8 @@ class EntityFieldQuery {
}
$return = array();
foreach ($select_query->execute() as $partial_entity) {
$entity = entity_create_stub_entity($partial_entity->entity_type, array($partial_entity->entity_id, $partial_entity->revision_id, $partial_entity->bundle));
$bundle = isset($partial_entity->bundle) ? $partial_entity->bundle : NULL;
$entity = entity_create_stub_entity($partial_entity->entity_type, array($partial_entity->entity_id, $partial_entity->revision_id, $bundle));
$return[$partial_entity->entity_type][$partial_entity->$id_key] = $entity;
$this->ordered_results[] = $partial_entity;
}

View File

@ -62,13 +62,16 @@ function field_test_entity_info() {
'bundles' => array('bundle1' => array('label' => 'Bundle1'), 'bundle2' => array('label' => 'Bundle2')),
'view modes' => $test_entity_modes,
),
// In this case, the bundle key is not stored in the database.
'test_entity_bundle' => array(
'name' => t('Test Entity with a specified bundle.'),
'base table' => 'test_entity_bundle',
'fieldable' => TRUE,
'controller class' => 'TestEntityBundleController',
'field cache' => FALSE,
'entity keys' => array(
'id' => 'ftid',
'bundle' => 'fttype',
),
'bundles' => array('test_entity_2' => array('label' => 'Test entity 2')),
'view modes' => $test_entity_modes,
@ -409,3 +412,21 @@ function field_test_entity_form_submit_builder($form, &$form_state) {
entity_form_submit_build_entity('test_entity', $entity, $form, $form_state);
return $entity;
}
/**
* Controller class for the test_entity_bundle entity type.
*
* This extends the DrupalDefaultEntityController class, adding required
* special handling for bundles (since they are not stored in the database).
*/
class TestEntityBundleController extends DrupalDefaultEntityController {
protected function attachLoad(&$entities, $revision_id = FALSE) {
// Add bundle information.
foreach ($entities as $key => $entity) {
$entity->fttype = 'test_entity_bundle';
$entities[$key] = $entity;
}
parent::attachLoad($entities, $revision_id);
}
}

View File

@ -113,7 +113,7 @@ class EntityFieldQueryTestCase extends DrupalWebTestCase {
$entity = new stdClass();
$entity->ftid = 5;
$entity->fttype = 'bundle2';
$entity->fttype = 'test_entity_bundle';
$entity->{$this->field_names[1]}[LANGUAGE_NONE][0]['shape'] = 'square';
$entity->{$this->field_names[1]}[LANGUAGE_NONE][0]['color'] = 'red';
$entity->{$this->field_names[1]}[LANGUAGE_NONE][1]['shape'] = 'circle';
@ -164,6 +164,14 @@ class EntityFieldQueryTestCase extends DrupalWebTestCase {
* Tests EntityFieldQuery.
*/
function testEntityFieldQuery() {
$query = new EntityFieldQuery();
$query
->entityCondition('entity_type', 'test_entity_bundle')
->entityCondition('entity_id', '5');
$this->assertEntityFieldQuery($query, array(
array('test_entity_bundle', 5),
), t('Test query on an entity type with a generated bundle.'));
// Test entity_type condition.
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'test_entity_bundle_key');
@ -974,6 +982,7 @@ class EntityFieldQueryTestCase extends DrupalWebTestCase {
for ($i = 6; $i < 10; $i++) {
$entity = new stdClass();
$entity->ftid = $i;
$entity->fttype = 'test_entity_bundle';
$entity->{$this->field_names[0]}[LANGUAGE_NONE][0]['value'] = $i - 5;
drupal_write_record('test_entity_bundle', $entity);
field_attach_insert('test_entity_bundle', $entity);
@ -1112,15 +1121,20 @@ class EntityFieldQueryTestCase extends DrupalWebTestCase {
*/
function assertEntityFieldQuery($query, $intended_results, $message, $ordered = FALSE) {
$results = array();
foreach ($query->execute() as $entity_type => $entity_ids) {
foreach ($entity_ids as $entity_id => $stub_entity) {
$results[] = array($entity_type, $entity_id);
try {
foreach ($query->execute() as $entity_type => $entity_ids) {
foreach ($entity_ids as $entity_id => $stub_entity) {
$results[] = array($entity_type, $entity_id);
}
}
if (!isset($ordered) || !$ordered) {
sort($results);
sort($intended_results);
}
$this->assertEqual($results, $intended_results, $message);
}
if (!isset($ordered) || !$ordered) {
sort($results);
sort($intended_results);
catch (Exception $e) {
$this->fail('Exception thrown: '. $e->getMessage());
}
$this->assertEqual($results, $intended_results, $message);
}
}