diff --git a/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php b/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php index 5b538c8..af2ef3b 100644 --- a/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php +++ b/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php @@ -9,6 +9,7 @@ use PDO; +use Drupal\Core\Entity\Query\QueryInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\DatabaseStorageController; use Drupal\Core\Entity\EntityStorageException; @@ -37,6 +38,13 @@ class DatabaseStorageControllerNG extends DatabaseStorageController { protected $bundleKey; /** + * The table that stores properties, if the entity has multilingual support. + * + * @var string + */ + protected $dataTable; + + /** * Overrides DatabaseStorageController::__construct(). */ public function __construct($entityType) { @@ -44,6 +52,11 @@ public function __construct($entityType) { $this->bundleKey = !empty($this->entityInfo['entity_keys']['bundle']) ? $this->entityInfo['entity_keys']['bundle'] : FALSE; $this->entityClass = $this->entityInfo['class']; + // Check if the entity type has a dedicated table for properties. + if (!empty($this->entityInfo['data_table'])) { + $this->dataTable = $this->entityInfo['data_table']; + } + // Work-a-round to let load() get stdClass storage records without having to // override it. We map storage records to entities in // DatabaseStorageControllerNG:: mapFromStorageRecords(). @@ -95,6 +108,34 @@ public function create(array $values) { } /** + * Builds an entity query. + * + * @param \Drupal\Core\Entity\Query\QueryInterface $entity_query + * EntityQuery instance. + * @param array $values + * An associative array of properties of the entity, where the keys are the + * property names and the values are the values those properties must have. + */ + protected function buildPropertyQuery(QueryInterface $entity_query, array $values) { + if ($this->dataTable) { + // @todo We should not be using a condition to specify whether conditions + // apply to the default language. See http://drupal.org/node/1866330. + // Default to the original entity language if not explicitly specified + // otherwise. + if (!array_key_exists('default_langcode', $values)) { + $values['default_langcode'] = 1; + } + // If the 'default_langcode' flag is explicitly not set, we do not care + // whether the queried values are in the original entity language or not. + elseif ($values['default_langcode'] === NULL) { + unset($values['default_langcode']); + } + } + + parent::buildPropertyQuery($entity_query, $values); + } + + /** * Overrides DatabaseStorageController::attachLoad(). * * Added mapping from storage records to entities. @@ -146,7 +187,7 @@ protected function attachLoad(&$queried_entities, $load_revision = FALSE) { * An array of entity objects implementing the EntityInterface. */ protected function mapFromStorageRecords(array $records, $load_revision = FALSE) { - + $entities = array(); foreach ($records as $id => $record) { $values = array(); foreach ($record as $name => $value) { @@ -155,9 +196,53 @@ protected function mapFromStorageRecords(array $records, $load_revision = FALSE) } $bundle = $this->bundleKey ? $record->{$this->bundleKey} : FALSE; // Turn the record into an entity class. - $records[$id] = new $this->entityClass($values, $this->entityType, $bundle); + $entities[$id] = new $this->entityClass($values, $this->entityType, $bundle); + } + $this->attachPropertyData($entities, $load_revision); + return $entities; + } + + /** + * Attaches property data in all languages for translatable properties. + * + * @param array &$entities + * Associative array of entities, keyed on the entity ID. + * @param boolean $load_revision + * (optional) TRUE if the revision should be loaded, defaults to FALSE. + */ + protected function attachPropertyData(array &$entities, $load_revision = FALSE) { + if ($this->dataTable) { + $query = db_select($this->dataTable, 'data', array('fetch' => PDO::FETCH_ASSOC)) + ->fields('data') + ->condition($this->idKey, array_keys($entities)) + ->orderBy('data.' . $this->idKey); + if ($load_revision) { + // Get revision ID's. + $revision_ids = array(); + foreach ($entities as $id => $entity) { + $revision_ids[] = $entity->get($this->revisionKey)->value; + } + $query->condition($this->revisionKey, $revision_ids); + } + $data = $query->execute(); + + // Fetch the field definitions to check which field is translatable. + $field_definition = $this->getFieldDefinitions(array()); + + foreach ($data as $values) { + $id = $values[$this->idKey]; + // Field values in default language are stored with LANGUAGE_DEFAULT as + // key. + $langcode = empty($values['default_langcode']) ? $values['langcode'] : LANGUAGE_DEFAULT; + + foreach ($this->entityInfo['schema_fields_sql']['data_table'] as $name) { + // Set translatable properties only. + if (!empty($field_definition[$name]['translatable'])) { + $entities[$id]->getTranslation($langcode)->{$name}->value = $values[$name]; + } + } + } } - return $records; } /** @@ -191,6 +276,9 @@ public function save(EntityInterface $entity) { if ($this->revisionKey) { $record->{$this->revisionKey} = $this->saveRevision($entity); } + if ($this->dataTable) { + $this->storePropertyData($entity); + } $this->resetCache(array($entity->id())); $this->postSave($entity, TRUE); $this->invokeHook('update', $entity); @@ -201,10 +289,14 @@ public function save(EntityInterface $entity) { $entity->{$this->idKey}->value = $record->{$this->idKey}; $record->{$this->revisionKey} = $this->saveRevision($entity); } + $entity->{$this->idKey}->value = $record->{$this->idKey}; + if ($this->dataTable) { + $this->storePropertyData($entity); + } + // Reset general caches, but keep caches specific to certain entities. $this->resetCache(array()); - $entity->{$this->idKey}->value = $record->{$this->idKey}; $entity->enforceIsNew(FALSE); $this->postSave($entity, FALSE); $this->invokeHook('insert', $entity); @@ -263,6 +355,31 @@ protected function saveRevision(EntityInterface $entity) { } /** + * Stores the entity property language-aware data. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity object. + */ + protected function storePropertyData(EntityInterface $entity) { + // Delete and insert to handle removed values. + db_delete($this->dataTable) + ->condition($this->idKey, $entity->id()) + ->execute(); + + $query = db_insert($this->dataTable); + + foreach ($entity->getTranslationLanguages() as $langcode => $language) { + $record = $this->mapToDataStorageRecord($entity, $langcode); + $values = (array) $record; + $query + ->fields(array_keys($values)) + ->values($values); + } + + $query->execute(); + } + + /** * Overrides DatabaseStorageController::invokeHook(). * * Invokes field API attachers with a BC entity. @@ -286,6 +403,12 @@ protected function invokeHook($hook, EntityInterface $entity) { /** * Maps from an entity object to the storage record of the base table. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity object. + * + * @return \stdClass + * The record to store. */ protected function mapToStorageRecord(EntityInterface $entity) { $record = new \stdClass(); @@ -297,6 +420,12 @@ protected function mapToStorageRecord(EntityInterface $entity) { /** * Maps from an entity object to the storage record of the revision table. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity object. + * + * @return \stdClass + * The record to store. */ protected function mapToRevisionStorageRecord(EntityInterface $entity) { $record = new \stdClass(); @@ -305,4 +434,81 @@ protected function mapToRevisionStorageRecord(EntityInterface $entity) { } return $record; } + + /** + * Maps from an entity object to the storage record of the data table. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity object. + * @param $langcode + * The language code of the translation to get. + * + * @return \stdClass + * The record to store. + */ + protected function mapToDataStorageRecord(EntityInterface $entity, $langcode) { + $default_langcode = $entity->language()->langcode; + // Don't use strict mode, this way there's no need to do checks here, as + // non-translatable properties are replicated for each language. + $translation = $entity->getTranslation($langcode, FALSE); + + $record = new \stdClass(); + foreach ($this->entityInfo['schema_fields_sql']['data_table'] as $name) { + $record->$name = $translation->$name->value; + } + $record->langcode = $langcode; + $record->default_langcode = intval($default_langcode == $langcode); + + return $record; + } + + /** + * Overwrites \Drupal\Core\Entity\DatabaseStorageController::delete(). + */ + public function delete(array $entities) { + if (!$entities) { + // If no IDs or invalid IDs were passed, do nothing. + return; + } + $transaction = db_transaction(); + + try { + $this->preDelete($entities); + foreach ($entities as $id => $entity) { + $this->invokeHook('predelete', $entity); + } + $ids = array_keys($entities); + + db_delete($this->entityInfo['base_table']) + ->condition($this->idKey, $ids) + ->execute(); + + if ($this->revisionKey) { + db_delete($this->revisionTable) + ->condition($this->idKey, $ids) + ->execute(); + } + + if ($this->dataTable) { + db_delete($this->dataTable) + ->condition($this->idKey, $ids) + ->execute(); + } + + // Reset the cache as soon as the changes have been applied. + $this->resetCache($ids); + + $this->postDelete($entities); + foreach ($entities as $id => $entity) { + $this->invokeHook('delete', $entity); + } + // Ignore slave server temporarily. + db_ignore_slave(); + } + catch (Exception $e) { + $transaction->rollback(); + watchdog_exception($this->entityType, $e); + throw new EntityStorageException($e->getMessage, $e->getCode, $e); + } + } } diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php index caf46a2..affdd80 100644 --- a/core/lib/Drupal/Core/Entity/EntityManager.php +++ b/core/lib/Drupal/Core/Entity/EntityManager.php @@ -294,6 +294,9 @@ public function processDefinition(&$definition, $plugin_id) { // Drupal\Core\Entity\DatabaseStorageControllerInterface::buildQuery(). if (isset($definition['base_table'])) { $definition['schema_fields_sql']['base_table'] = drupal_schema_fields_sql($definition['base_table']); + if (isset($definition['data_table'])) { + $definition['schema_fields_sql']['data_table'] = drupal_schema_fields_sql($definition['data_table']); + } if (isset($definition['revision_table'])) { $definition['schema_fields_sql']['revision_table'] = drupal_schema_fields_sql($definition['revision_table']); } diff --git a/core/lib/Drupal/Core/Entity/EntityNG.php b/core/lib/Drupal/Core/Entity/EntityNG.php index 7df5b1e..b798bcf 100644 --- a/core/lib/Drupal/Core/Entity/EntityNG.php +++ b/core/lib/Drupal/Core/Entity/EntityNG.php @@ -102,7 +102,7 @@ protected function init() { } /** - * Magic __wakeup() implemenation. + * Magic __wakeup() implementation. */ public function __wakeup() { $this->init(); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiTest.php index 7cf3403..4c428cc 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiTest.php @@ -32,43 +32,58 @@ public static function getInfo() { /** * Tests basic CRUD functionality of the Entity API. */ - function testCRUD() { + public function testCRUD() { $user1 = $this->drupalCreateUser(); + // All entity variations have to have the same results. + foreach (entity_test_entity_types() as $entity_type) { + $this->assertCRUD($entity_type, $user1); + } + } + + /** + * Executes a test set for a defined entity type and user. + * + * @param string $entity_type + * The entity type to run the tests with. + * @param \Drupal\user\Plugin\Core\Entity\User $user1 + * The user to run the tests with. + */ + protected function assertCRUD($entity_type, \Drupal\user\Plugin\Core\Entity\User $user1) { // Create some test entities. - $entity = entity_create('entity_test', array('name' => 'test', 'user_id' => $user1->uid)); + $entity = entity_create($entity_type, array('name' => 'test', 'user_id' => $user1->uid)); $entity->save(); - $entity = entity_create('entity_test', array('name' => 'test2', 'user_id' => $user1->uid)); + $entity = entity_create($entity_type, array('name' => 'test2', 'user_id' => $user1->uid)); $entity->save(); - $entity = entity_create('entity_test', array('name' => 'test', 'user_id' => NULL)); + $entity = entity_create($entity_type, array('name' => 'test', 'user_id' => NULL)); $entity->save(); - $entities = array_values(entity_load_multiple_by_properties('entity_test', array('name' => 'test'))); - $this->assertEqual($entities[0]->name->value, 'test', 'Created and loaded entity.'); - $this->assertEqual($entities[1]->name->value, 'test', 'Created and loaded entity.'); + $entities = array_values(entity_load_multiple_by_properties($entity_type, array('name' => 'test'))); + $this->assertEqual($entities[0]->name->value, 'test', format_string('%entity_type: Created and loaded entity', array('%entity_type' => $entity_type))); + $this->assertEqual($entities[1]->name->value, 'test', format_string('%entity_type: Created and loaded entity', array('%entity_type' => $entity_type))); // Test loading a single entity. - $loaded_entity = entity_test_load($entity->id()); - $this->assertEqual($loaded_entity->id(), $entity->id(), 'Loaded a single entity by id.'); + $loaded_entity = entity_load($entity_type, $entity->id()); + $this->assertEqual($loaded_entity->id(), $entity->id(), format_string('%entity_type: Loaded a single entity by id.', array('%entity_type' => $entity_type))); // Test deleting an entity. - $entities = array_values(entity_load_multiple_by_properties('entity_test', array('name' => 'test2'))); + $entities = array_values(entity_load_multiple_by_properties($entity_type, array('name' => 'test2'))); $entities[0]->delete(); - $entities = array_values(entity_load_multiple_by_properties('entity_test', array('name' => 'test2'))); - $this->assertEqual($entities, array(), 'Entity deleted.'); + $entities = array_values(entity_load_multiple_by_properties($entity_type, array('name' => 'test2'))); + $this->assertEqual($entities, array(), format_string('%entity_type: Entity deleted.', array('%entity_type' => $entity_type))); // Test updating an entity. - $entities = array_values(entity_load_multiple_by_properties('entity_test', array('name' => 'test'))); + $entities = array_values(entity_load_multiple_by_properties($entity_type, array('name' => 'test'))); $entities[0]->name->value = 'test3'; $entities[0]->save(); - $entity = entity_test_load($entities[0]->id()); - $this->assertEqual($entity->name->value, 'test3', 'Entity updated.'); + $entity = entity_load($entity_type, $entities[0]->id()); + $this->assertEqual($entity->name->value, 'test3', format_string('%entity_type: Entity updated.', array('%entity_type' => $entity_type))); // Try deleting multiple test entities by deleting all. - $ids = array_keys(entity_test_load_multiple()); - entity_test_delete_multiple($ids); + $ids = array_keys(entity_load_multiple($entity_type)); + entity_delete_multiple($entity_type, $ids); - $all = entity_test_load_multiple(); - $this->assertTrue(empty($all), 'Deleted all entities.'); + $all = entity_load_multiple($entity_type); + $this->assertTrue(empty($all), format_string('%entity_type: Deleted all entities.', array('%entity_type' => $entity_type))); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php index 56f3873..4590ad9 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php @@ -38,14 +38,14 @@ public static function getInfo() { * * @return \Drupal\Core\Entity\EntityInterface */ - protected function createTestEntity() { + protected function createTestEntity($entity_type) { $this->entity_name = $this->randomName(); $this->entity_user = $this->drupalCreateUser(); $this->entity_field_text = $this->randomName(); // Pass in the value of the name field when creating. With the user // field we test setting a field after creation. - $entity = entity_create('entity_test', array()); + $entity = entity_create($entity_type, array()); $entity->user_id->value = $this->entity_user->uid; $entity->name->value = $this->entity_name; @@ -59,74 +59,87 @@ protected function createTestEntity() { * Tests reading and writing properties and field items. */ public function testReadWrite() { - $entity = $this->createTestEntity(); + // All entity variations have to have the same results. + foreach (entity_test_entity_types() as $entity_type) { + $this->assertReadWrite($entity_type); + } + } + + /** + * Executes the read write test set for a defined entity type. + * + * @param string $entity_type + * The entity type to run the tests with. + */ + protected function assertReadWrite($entity_type) { + $entity = $this->createTestEntity($entity_type); // Access the name field. - $this->assertTrue($entity->name instanceof FieldInterface, 'Field implements interface'); - $this->assertTrue($entity->name[0] instanceof FieldItemInterface, 'Field item implements interface'); + $this->assertTrue($entity->name instanceof FieldInterface, format_string('%entity_type: Field implements interface', array('%entity_type' => $entity_type))); + $this->assertTrue($entity->name[0] instanceof FieldItemInterface, format_string('%entity_type: Field item implements interface', array('%entity_type' => $entity_type))); - $this->assertEqual($this->entity_name, $entity->name->value, 'Name value can be read.'); - $this->assertEqual($this->entity_name, $entity->name[0]->value, 'Name value can be read through list access.'); - $this->assertEqual($entity->name->getValue(), array(0 => array('value' => $this->entity_name)), 'Plain field value returned.'); + $this->assertEqual($this->entity_name, $entity->name->value, format_string('%entity_type: Name value can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($this->entity_name, $entity->name[0]->value, format_string('%entity_type: Name value can be read through list access.', array('%entity_type' => $entity_type))); + $this->assertEqual($entity->name->getValue(), array(0 => array('value' => $this->entity_name)), format_string('%entity_type: Plain field value returned.', array('%entity_type' => $entity_type))); // Change the name. $new_name = $this->randomName(); $entity->name->value = $new_name; - $this->assertEqual($new_name, $entity->name->value, 'Name can be updated and read.'); - $this->assertEqual($entity->name->getValue(), array(0 => array('value' => $new_name)), 'Plain field value reflects the update.'); + $this->assertEqual($new_name, $entity->name->value, format_string('%entity_type: Name can be updated and read.', array('%entity_type' => $entity_type))); + $this->assertEqual($entity->name->getValue(), array(0 => array('value' => $new_name)), format_string('%entity_type: Plain field value reflects the update.', array('%entity_type' => $entity_type))); $new_name = $this->randomName(); $entity->name[0]->value = $new_name; - $this->assertEqual($new_name, $entity->name->value, 'Name can be updated and read through list access.'); + $this->assertEqual($new_name, $entity->name->value, format_string('%entity_type: Name can be updated and read through list access.', array('%entity_type' => $entity_type))); // Access the user field. - $this->assertTrue($entity->user_id instanceof FieldInterface, 'Field implements interface'); - $this->assertTrue($entity->user_id[0] instanceof FieldItemInterface, 'Field item implements interface'); + $this->assertTrue($entity->user_id instanceof FieldInterface, format_string('%entity_type: Field implements interface', array('%entity_type' => $entity_type))); + $this->assertTrue($entity->user_id[0] instanceof FieldItemInterface, format_string('%entity_type: Field item implements interface', array('%entity_type' => $entity_type))); - $this->assertEqual($this->entity_user->uid, $entity->user_id->value, 'User id can be read.'); - $this->assertEqual($this->entity_user->name, $entity->user_id->entity->name, 'User name can be read.'); + $this->assertEqual($this->entity_user->uid, $entity->user_id->value, format_string('%entity_type: User id can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($this->entity_user->name, $entity->user_id->entity->name, format_string('%entity_type: User name can be read.', array('%entity_type' => $entity_type))); // Change the assigned user by entity. $new_user = $this->drupalCreateUser(); $entity->user_id->entity = $new_user; - $this->assertEqual($new_user->uid, $entity->user_id->value, 'Updated user id can be read.'); - $this->assertEqual($new_user->name, $entity->user_id->entity->name, 'Updated user name value can be read.'); + $this->assertEqual($new_user->uid, $entity->user_id->value, format_string('%entity_type: Updated user id can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($new_user->name, $entity->user_id->entity->name, format_string('%entity_type: Updated user name value can be read.', array('%entity_type' => $entity_type))); // Change the assigned user by id. $new_user = $this->drupalCreateUser(); $entity->user_id->value = $new_user->uid; - $this->assertEqual($new_user->uid, $entity->user_id->value, 'Updated user id can be read.'); - $this->assertEqual($new_user->name, $entity->user_id->entity->name, 'Updated user name value can be read.'); + $this->assertEqual($new_user->uid, $entity->user_id->value, format_string('%entity_type: Updated user id can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($new_user->name, $entity->user_id->entity->name, format_string('%entity_type: Updated user name value can be read.', array('%entity_type' => $entity_type))); // Try unsetting a field. $entity->name->value = NULL; $entity->user_id->value = NULL; - $this->assertNull($entity->name->value, 'Name field is not set.'); - $this->assertNull($entity->user_id->value, 'User ID field is not set.'); - $this->assertNull($entity->user_id->entity, 'User entity field is not set.'); + $this->assertNull($entity->name->value, format_string('%entity_type: Name field is not set.', array('%entity_type' => $entity_type))); + $this->assertNull($entity->user_id->value, format_string('%entity_type: User ID field is not set.', array('%entity_type' => $entity_type))); + $this->assertNull($entity->user_id->entity, format_string('%entity_type: User entity field is not set.', array('%entity_type' => $entity_type))); // Test using isset(), empty() and unset(). $entity->name->value = 'test unset'; unset($entity->name->value); - $this->assertFalse(isset($entity->name->value), 'Name is not set.'); - $this->assertFalse(isset($entity->name[0]->value), 'Name is not set.'); - $this->assertTrue(empty($entity->name->value), 'Name is empty.'); - $this->assertTrue(empty($entity->name[0]->value), 'Name is empty.'); + $this->assertFalse(isset($entity->name->value), format_string('%entity_type: Name is not set.', array('%entity_type' => $entity_type))); + $this->assertFalse(isset($entity->name[0]->value), format_string('%entity_type: Name is not set.', array('%entity_type' => $entity_type))); + $this->assertTrue(empty($entity->name->value), format_string('%entity_type: Name is empty.', array('%entity_type' => $entity_type))); + $this->assertTrue(empty($entity->name[0]->value), format_string('%entity_type: Name is empty.', array('%entity_type' => $entity_type))); $entity->name->value = 'a value'; - $this->assertTrue(isset($entity->name->value), 'Name is set.'); - $this->assertTrue(isset($entity->name[0]->value), 'Name is set.'); - $this->assertFalse(empty($entity->name->value), 'Name is not empty.'); - $this->assertFalse(empty($entity->name[0]->value), 'Name is not empty.'); - $this->assertTrue(isset($entity->name[0]), 'Name string item is set.'); - $this->assertFalse(isset($entity->name[1]), 'Second name string item is not set as it does not exist'); - $this->assertTrue(isset($entity->name), 'Name field is set.'); - $this->assertFalse(isset($entity->nameInvalid), 'Not existing field is not set.'); + $this->assertTrue(isset($entity->name->value), format_string('%entity_type: Name is set.', array('%entity_type' => $entity_type))); + $this->assertTrue(isset($entity->name[0]->value), format_string('%entity_type: Name is set.', array('%entity_type' => $entity_type))); + $this->assertFalse(empty($entity->name->value), format_string('%entity_type: Name is not empty.', array('%entity_type' => $entity_type))); + $this->assertFalse(empty($entity->name[0]->value), format_string('%entity_type: Name is not empty.', array('%entity_type' => $entity_type))); + $this->assertTrue(isset($entity->name[0]), format_string('%entity_type: Name string item is set.', array('%entity_type' => $entity_type))); + $this->assertFalse(isset($entity->name[1]), format_string('%entity_type: Second name string item is not set as it does not exist', array('%entity_type' => $entity_type))); + $this->assertTrue(isset($entity->name), format_string('%entity_type: Name field is set.', array('%entity_type' => $entity_type))); + $this->assertFalse(isset($entity->nameInvalid), format_string('%entity_type: Not existing field is not set.', array('%entity_type' => $entity_type))); unset($entity->name[0]); - $this->assertFalse(isset($entity->name[0]), 'Name field item is not set.'); - $this->assertFalse(isset($entity->name[0]->value), 'Name is not set.'); - $this->assertFalse(isset($entity->name->value), 'Name is not set.'); + $this->assertFalse(isset($entity->name[0]), format_string('%entity_type: Name field item is not set.', array('%entity_type' => $entity_type))); + $this->assertFalse(isset($entity->name[0]->value), format_string('%entity_type: Name is not set.', array('%entity_type' => $entity_type))); + $this->assertFalse(isset($entity->name->value), format_string('%entity_type: Name is not set.', array('%entity_type' => $entity_type))); $entity->name = array(); $this->assertTrue(isset($entity->name), 'Name field is set.'); @@ -135,33 +148,33 @@ public function testReadWrite() { $this->assertFalse(isset($entity->name->value), 'Name value is not set.'); $entity->name->value = 'a value'; - $this->assertTrue(isset($entity->name->value), 'Name is set.'); + $this->assertTrue(isset($entity->name->value), format_string('%entity_type: Name is set.', array('%entity_type' => $entity_type))); unset($entity->name); - $this->assertFalse(isset($entity->name), 'Name field is not set.'); - $this->assertFalse(isset($entity->name[0]), 'Name field item is not set.'); - $this->assertFalse(isset($entity->name[0]->value), 'Name is not set.'); - $this->assertFalse(isset($entity->name->value), 'Name is not set.'); + $this->assertFalse(isset($entity->name), format_string('%entity_type: Name field is not set.', array('%entity_type' => $entity_type))); + $this->assertFalse(isset($entity->name[0]), format_string('%entity_type: Name field item is not set.', array('%entity_type' => $entity_type))); + $this->assertFalse(isset($entity->name[0]->value), format_string('%entity_type: Name is not set.', array('%entity_type' => $entity_type))); + $this->assertFalse(isset($entity->name->value), format_string('%entity_type: Name is not set.', array('%entity_type' => $entity_type))); // Access the language field. - $this->assertEqual(LANGUAGE_NOT_SPECIFIED, $entity->langcode->value, 'Language code can be read.'); - $this->assertEqual(language_load(LANGUAGE_NOT_SPECIFIED), $entity->langcode->language, 'Language object can be read.'); + $this->assertEqual(LANGUAGE_NOT_SPECIFIED, $entity->langcode->value, format_string('%entity_type: Language code can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual(language_load(LANGUAGE_NOT_SPECIFIED), $entity->langcode->language, format_string('%entity_type: Language object can be read.', array('%entity_type' => $entity_type))); // Change the language by code. $entity->langcode->value = language_default()->langcode; - $this->assertEqual(language_default()->langcode, $entity->langcode->value, 'Language code can be read.'); - $this->assertEqual(language_default(), $entity->langcode->language, 'Language object can be read.'); + $this->assertEqual(language_default()->langcode, $entity->langcode->value, format_string('%entity_type: Language code can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual(language_default(), $entity->langcode->language, format_string('%entity_type: Language object can be read.', array('%entity_type' => $entity_type))); // Revert language by code then try setting it by language object. $entity->langcode->value = LANGUAGE_NOT_SPECIFIED; $entity->langcode->language = language_default(); - $this->assertEqual(language_default()->langcode, $entity->langcode->value, 'Language code can be read.'); - $this->assertEqual(language_default(), $entity->langcode->language, 'Language object can be read.'); + $this->assertEqual(language_default()->langcode, $entity->langcode->value, format_string('%entity_type: Language code can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual(language_default(), $entity->langcode->language, format_string('%entity_type: Language object can be read.', array('%entity_type' => $entity_type))); // Access the text field and test updating. - $this->assertEqual($entity->field_test_text->value, $this->entity_field_text, 'Text field can be read.'); + $this->assertEqual($entity->field_test_text->value, $this->entity_field_text, format_string('%entity_type: Text field can be read.', array('%entity_type' => $entity_type))); $new_text = $this->randomName(); $entity->field_test_text->value = $new_text; - $this->assertEqual($entity->field_test_text->value, $new_text, 'Updated text field can be read.'); + $this->assertEqual($entity->field_test_text->value, $new_text, format_string('%entity_type: Updated text field can be read.', array('%entity_type' => $entity_type))); // Test creating the entity by passing in plain values. $this->entity_name = $this->randomName(); @@ -171,153 +184,179 @@ public function testReadWrite() { $this->entity_field_text = $this->randomName(); $text_item[0]['value'] = $this->entity_field_text; - $entity = entity_create('entity_test', array( + $entity = entity_create($entity_type, array( 'name' => $name_item, 'user_id' => $user_item, 'field_test_text' => $text_item, )); - $this->assertEqual($this->entity_name, $entity->name->value, 'Name value can be read.'); - $this->assertEqual($this->entity_user->uid, $entity->user_id->value, 'User id can be read.'); - $this->assertEqual($this->entity_user->name, $entity->user_id->entity->name, 'User name can be read.'); - $this->assertEqual($this->entity_field_text, $entity->field_test_text->value, 'Text field can be read.'); + $this->assertEqual($this->entity_name, $entity->name->value, format_string('%entity_type: Name value can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($this->entity_user->uid, $entity->user_id->value, format_string('%entity_type: User id can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($this->entity_user->name, $entity->user_id->entity->name, format_string('%entity_type: User name can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($this->entity_field_text, $entity->field_test_text->value, format_string('%entity_type: Text field can be read.', array('%entity_type' => $entity_type))); // Test copying field values. - $entity2 = $this->createTestEntity(); + $entity2 = $this->createTestEntity($entity_type); $entity2->name = $entity->name; $entity2->user_id = $entity->user_id; $entity2->field_test_text = $entity->field_test_text; - $this->assertTrue($entity->name !== $entity2->name, 'Copying properties results in a different field object.'); - $this->assertEqual($entity->name->value, $entity2->name->value, 'Name field copied.'); - $this->assertEqual($entity->user_id->value, $entity2->user_id->value, 'User id field copied.'); - $this->assertEqual($entity->field_test_text->value, $entity2->field_test_text->value, 'Text field copied.'); + $this->assertTrue($entity->name !== $entity2->name, format_string('%entity_type: Copying properties results in a different field object.', array('%entity_type' => $entity_type))); + $this->assertEqual($entity->name->value, $entity2->name->value, format_string('%entity_type: Name field copied.', array('%entity_type' => $entity_type))); + $this->assertEqual($entity->user_id->value, $entity2->user_id->value, format_string('%entity_type: User id field copied.', array('%entity_type' => $entity_type))); + $this->assertEqual($entity->field_test_text->value, $entity2->field_test_text->value, format_string('%entity_type: Text field copied.', array('%entity_type' => $entity_type))); // Tests adding a value to a field item list. $entity->name[] = 'Another name'; - $this->assertEqual($entity->name[1]->value == 'Another name', 'List item added via [].'); + $this->assertEqual($entity->name[1]->value == 'Another name', format_string('%entity_type: List item added via [].', array('%entity_type' => $entity_type))); $entity->name[2]->value = 'Third name'; - $this->assertEqual($entity->name[2]->value == 'Third name', 'List item added by a accessing not yet created item.'); + $this->assertEqual($entity->name[2]->value == 'Third name', format_string('%entity_type: List item added by a accessing not yet created item.', array('%entity_type' => $entity_type))); // Test removing and empty-ing list items. - $this->assertEqual(count($entity->name), 3, 'List has 3 items.'); + $this->assertEqual(count($entity->name), 3, format_string('%entity_type: List has 3 items.', array('%entity_type' => $entity_type))); unset($entity->name[1]); - $this->assertEqual(count($entity->name), 2, 'Second list item has been removed.'); + $this->assertEqual(count($entity->name), 2, format_string('%entity_type: Second list item has been removed.', array('%entity_type' => $entity_type))); $entity->name[2] = NULL; - $this->assertEqual(count($entity->name), 2, 'Assigning NULL does not reduce array count.'); - $this->assertTrue($entity->name[2]->isEmpty(), 'Assigning NULL empties the item.'); + $this->assertEqual(count($entity->name), 2, format_string('%entity_type: Assigning NULL does not reduce array count.', array('%entity_type' => $entity_type))); + $this->assertTrue($entity->name[2]->isEmpty(), format_string('%entity_type: Assigning NULL empties the item.', array('%entity_type' => $entity_type))); // Test using isEmpty(). unset($entity->name[2]); - $this->assertFalse($entity->name[0]->isEmpty(), 'Name item is not empty.'); + $this->assertFalse($entity->name[0]->isEmpty(), format_string('%entity_type: Name item is not empty.', array('%entity_type' => $entity_type))); $entity->name->value = NULL; - $this->assertTrue($entity->name[0]->isEmpty(), 'Name item is empty.'); - $this->assertTrue($entity->name->isEmpty(), 'Name field is empty.'); - $this->assertEqual(count($entity->name), 1, 'Empty item is considered when counting.'); - $this->assertEqual(count(iterator_to_array($entity->name->getIterator())), count($entity->name), 'Count matches iterator count.'); - $this->assertTrue($entity->name->getValue() === array(0 => NULL), 'Name field value contains a NULL value.'); + $this->assertTrue($entity->name[0]->isEmpty(), format_string('%entity_type: Name item is empty.', array('%entity_type' => $entity_type))); + $this->assertTrue($entity->name->isEmpty(), format_string('%entity_type: Name field is empty.', array('%entity_type' => $entity_type))); + $this->assertEqual(count($entity->name), 1, format_string('%entity_type: Empty item is considered when counting.', array('%entity_type' => $entity_type))); + $this->assertEqual(count(iterator_to_array($entity->name->getIterator())), count($entity->name), format_string('%entity_type: Count matches iterator count.', array('%entity_type' => $entity_type))); + $this->assertTrue($entity->name->getValue() === array(0 => NULL), format_string('%entity_type: Name field value contains a NULL value.', array('%entity_type' => $entity_type))); // Test removing all list items by assigning an empty array. $entity->name = array(); - $this->assertIdentical(count($entity->name), 0, 'Name field contains no items.'); - $this->assertIdentical($entity->name->getValue(), array(), 'Name field value is an empty array.'); + $this->assertIdentical(count($entity->name), 0, format_string('%entity_type: Name field contains no items.', array('%entity_type' => $entity_type))); + $this->assertIdentical($entity->name->getValue(), array(), format_string('%entity_type: Name field value is an empty array.', array('%entity_type' => $entity_type))); $entity->name->value = 'foo'; - $this->assertTrue($entity->name->value, 'foo', 'Name field set.'); + $this->assertEqual($entity->name->value, 'foo', format_string('%entity_type: Name field set.', array('%entity_type' => $entity_type))); // Test removing all list items by setting it to NULL. $entity->name = NULL; - $this->assertIdentical(count($entity->name), 0, 'Name field contains no items.'); - $this->assertNull($entity->name->getValue(), 'Name field value is NULL.'); + $this->assertIdentical(count($entity->name), 0, format_string('%entity_type: Name field contains no items.', array('%entity_type' => $entity_type))); + $this->assertNull($entity->name->getValue(), format_string('%entity_type: Name field value is an empty array.', array('%entity_type' => $entity_type))); // Test get and set field values. $entity->name = 'foo'; - $this->assertEqual($entity->name[0]->getPropertyValues(), array('value' => 'foo'), 'Field value has been retrieved via getPropertyValue()'); + $this->assertEqual($entity->name[0]->getPropertyValues(), array('value' => 'foo'), format_string('%entity_type: Field value has been retrieved via getPropertyValue()', array('%entity_type' => $entity_type))); $entity->name[0]->setPropertyValues(array('value' => 'bar')); - $this->assertEqual($entity->name->value, 'bar', 'Field value has been set via setPropertyValue()'); + $this->assertEqual($entity->name->value, 'bar', format_string('%entity_type: Field value has been set via setPropertyValue()', array('%entity_type' => $entity_type))); $values = $entity->getPropertyValues(); - $this->assertEqual($values['name'], array(0 => array('value' => 'bar')), 'Field value has been retrieved via getPropertyValue() from an entity.'); + $this->assertEqual($values['name'], array(0 => array('value' => 'bar')), format_string('%entity_type: Field value has been retrieved via getPropertyValue() from an entity.', array('%entity_type' => $entity_type))); $entity->setPropertyValues(array('name' => 'foo')); - $this->assertEqual($entity->name->value, 'foo', 'Field value has been set via setPropertyValue() on an entity.'); + $this->assertEqual($entity->name->value, 'foo', format_string('%entity_type: Field value has been set via setPropertyValue() on an entity.', array('%entity_type' => $entity_type))); // Make sure the user id can be set to zero. $user_item[0]['value'] = 0; - $entity = entity_create('entity_test', array( + $entity = entity_create($entity_type, array( 'name' => $name_item, 'user_id' => $user_item, 'field_test_text' => $text_item, )); - $this->assertNotNull($entity->user_id->value, 'User id is not NULL'); - $this->assertIdentical($entity->user_id->value, 0, 'User id has been set to 0'); + $this->assertNotNull($entity->user_id->value, format_string('%entity_type: User id is not NULL', array('%entity_type' => $entity_type))); + $this->assertIdentical($entity->user_id->value, 0, format_string('%entity_type: User id has been set to 0', array('%entity_type' => $entity_type))); // Test setting the ID with the value only. - $entity = entity_create('entity_test', array( + $entity = entity_create($entity_type, array( 'name' => $name_item, 'user_id' => 0, 'field_test_text' => $text_item, )); - $this->assertNotNull($entity->user_id->value, 'User id is not NULL'); - $this->assertIdentical($entity->user_id->value, 0, 'User id has been set to 0'); + $this->assertNotNull($entity->user_id->value, format_string('%entity_type: User id is not NULL', array('%entity_type' => $entity_type))); + $this->assertIdentical($entity->user_id->value, 0, format_string('%entity_type: User id has been set to 0', array('%entity_type' => $entity_type))); } /** * Tries to save and load an entity again. */ public function testSave() { - $entity = $this->createTestEntity(); + // All entity variations have to have the same results. + foreach (entity_test_entity_types() as $entity_type) { + $this->assertSave($entity_type); + } + } + + /** + * Executes the save tests for the given entity type. + * + * @param string $entity_type + * The entity type to run the tests with. + */ + protected function assertSave($entity_type) { + $entity = $this->createTestEntity($entity_type); $entity->save(); - $this->assertTrue((bool) $entity->id(), 'Entity has received an id.'); + $this->assertTrue((bool) $entity->id(), format_string('%entity_type: Entity has received an id.', array('%entity_type' => $entity_type))); - $entity = entity_load('entity_test', $entity->id()); - $this->assertTrue((bool) $entity->id(), 'Entity loaded.'); + $entity = entity_load($entity_type, $entity->id()); + $this->assertTrue((bool) $entity->id(), format_string('%entity_type: Entity loaded.', array('%entity_type' => $entity_type))); // Access the name field. - $this->assertEqual(1, $entity->id->value, 'ID value can be read.'); - $this->assertTrue(is_string($entity->uuid->value), 'UUID value can be read.'); - $this->assertEqual(LANGUAGE_NOT_SPECIFIED, $entity->langcode->value, 'Language code can be read.'); - $this->assertEqual(language_load(LANGUAGE_NOT_SPECIFIED), $entity->langcode->language, 'Language object can be read.'); - $this->assertEqual($this->entity_user->uid, $entity->user_id->value, 'User id can be read.'); - $this->assertEqual($this->entity_user->name, $entity->user_id->entity->name, 'User name can be read.'); - $this->assertEqual($this->entity_field_text, $entity->field_test_text->value, 'Text field can be read.'); + $this->assertEqual(1, $entity->id->value, format_string('%entity_type: ID value can be read.', array('%entity_type' => $entity_type))); + $this->assertTrue(is_string($entity->uuid->value), format_string('%entity_type: UUID value can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual(LANGUAGE_NOT_SPECIFIED, $entity->langcode->value, format_string('%entity_type: Language code can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual(language_load(LANGUAGE_NOT_SPECIFIED), $entity->langcode->language, format_string('%entity_type: Language object can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($this->entity_user->uid, $entity->user_id->value, format_string('%entity_type: User id can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($this->entity_user->name, $entity->user_id->entity->name, format_string('%entity_type: User name can be read.', array('%entity_type' => $entity_type))); + $this->assertEqual($this->entity_field_text, $entity->field_test_text->value, format_string('%entity_type: Text field can be read.', array('%entity_type' => $entity_type))); } /** * Tests introspection and getting metadata upfront. */ public function testIntrospection() { + // All entity variations have to have the same results. + foreach (entity_test_entity_types() as $entity_type) { + $this->assertIntrospection($entity_type); + } + } + + /** + * Executes the introspection tests for the given entity type. + * + * @param string $entity_type + * The entity type to run the tests with. + */ + protected function assertIntrospection($entity_type) { // Test getting metadata upfront, i.e. without having an entity object. $definition = array( 'type' => 'entity', 'constraints' => array( - 'entity type' => 'entity_test', + 'entity type' => $entity_type, ), 'label' => t('Test entity'), ); $wrapped_entity = typed_data()->create($definition); $definitions = $wrapped_entity->getPropertyDefinitions($definition); - $this->assertEqual($definitions['name']['type'], 'string_field', 'Name field found.'); - $this->assertEqual($definitions['user_id']['type'], 'entityreference_field', 'User field found.'); - $this->assertEqual($definitions['field_test_text']['type'], 'text_field', 'Test-text-field field found.'); + $this->assertEqual($definitions['name']['type'], 'string_field', $entity_type .': Name field found.'); + $this->assertEqual($definitions['user_id']['type'], 'entityreference_field', $entity_type .': User field found.'); + $this->assertEqual($definitions['field_test_text']['type'], 'text_field', $entity_type .': Test-text-field field found.'); // Test introspecting an entity object. // @todo: Add bundles and test bundles as well. - $entity = entity_create('entity_test', array()); + $entity = entity_create($entity_type, array()); $definitions = $entity->getPropertyDefinitions(); - $this->assertEqual($definitions['name']['type'], 'string_field', 'Name field found.'); - $this->assertEqual($definitions['user_id']['type'], 'entityreference_field', 'User field found.'); - $this->assertEqual($definitions['field_test_text']['type'], 'text_field', 'Test-text-field field found.'); + $this->assertEqual($definitions['name']['type'], 'string_field', $entity_type .': Name field found.'); + $this->assertEqual($definitions['user_id']['type'], 'entityreference_field', $entity_type .': User field found.'); + $this->assertEqual($definitions['field_test_text']['type'], 'text_field', $entity_type .': Test-text-field field found.'); $name_properties = $entity->name->getPropertyDefinitions(); - $this->assertEqual($name_properties['value']['type'], 'string', 'String value property of the name found.'); + $this->assertEqual($name_properties['value']['type'], 'string', $entity_type .': String value property of the name found.'); $userref_properties = $entity->user_id->getPropertyDefinitions(); - $this->assertEqual($userref_properties['value']['type'], 'integer', 'Entity id property of the user found.'); - $this->assertEqual($userref_properties['entity']['type'], 'entity', 'Entity reference property of the user found.'); + $this->assertEqual($userref_properties['value']['type'], 'integer', $entity_type .': Entity id property of the user found.'); + $this->assertEqual($userref_properties['entity']['type'], 'entity', $entity_type .': Entity reference property of the user found.'); $textfield_properties = $entity->field_test_text->getPropertyDefinitions(); - $this->assertEqual($textfield_properties['value']['type'], 'string', 'String value property of the test-text field found.'); - $this->assertEqual($textfield_properties['format']['type'], 'string', 'String format field of the test-text field found.'); - $this->assertEqual($textfield_properties['processed']['type'], 'string', 'String processed property of the test-text field found.'); + $this->assertEqual($textfield_properties['value']['type'], 'string', $entity_type .': String value property of the test-text field found.'); + $this->assertEqual($textfield_properties['format']['type'], 'string', $entity_type .': String format field of the test-text field found.'); + $this->assertEqual($textfield_properties['processed']['type'], 'string', $entity_type .': String processed property of the test-text field found.'); // @todo: Once the user entity has definitions, continue testing getting // them from the $userref_values['entity'] property. @@ -351,26 +390,39 @@ public function testIntrospection() { * Tests iterating over properties. */ public function testIterator() { - $entity = $this->createTestEntity(); + // All entity variations have to have the same results. + foreach (entity_test_entity_types() as $entity_type) { + $this->assertIterator($entity_type); + } + } + + /** + * Executes the iterator tests for the given entity type. + * + * @param string $entity_type + * The entity type to run the tests with. + */ + protected function assertIterator($entity_type) { + $entity = $this->createTestEntity($entity_type); foreach ($entity as $name => $field) { - $this->assertTrue($field instanceof FieldInterface, "Field $name implements interface."); + $this->assertTrue($field instanceof FieldInterface, $entity_type . ": Field $name implements interface."); foreach ($field as $delta => $item) { - $this->assertTrue($field[0] instanceof FieldItemInterface, "Item $delta of field $name implements interface."); + $this->assertTrue($field[0] instanceof FieldItemInterface, $entity_type . ": Item $delta of field $name implements interface."); foreach ($item as $value_name => $value_property) { - $this->assertTrue($value_property instanceof TypedDataInterface, "Value $value_name of item $delta of field $name implements interface."); + $this->assertTrue($value_property instanceof TypedDataInterface, $entity_type . ": Value $value_name of item $delta of field $name implements interface."); $value = $value_property->getValue(); - $this->assertTrue(!isset($value) || is_scalar($value) || $value instanceof EntityInterface, "Value $value_name of item $delta of field $name is a primitive or an entity."); + $this->assertTrue(!isset($value) || is_scalar($value) || $value instanceof EntityInterface, $entity_type . ": Value $value_name of item $delta of field $name is a primitive or an entity."); } } } $properties = $entity->getProperties(); - $this->assertEqual(array_keys($properties), array_keys($entity->getPropertyDefinitions()), 'All properties returned.'); - $this->assertEqual($properties, iterator_to_array($entity->getIterator()), 'Entity iterator iterates over all properties.'); + $this->assertEqual(array_keys($properties), array_keys($entity->getPropertyDefinitions()), format_string('%entity_type: All properties returned.', array('%entity_type' => $entity_type))); + $this->assertEqual($properties, iterator_to_array($entity->getIterator()), format_string('%entity_type: Entity iterator iterates over all properties.', array('%entity_type' => $entity_type))); } /** @@ -378,12 +430,25 @@ public function testIterator() { * list interfaces. */ public function testDataStructureInterfaces() { - $entity = $this->createTestEntity(); + // All entity variations have to have the same results. + foreach (entity_test_entity_types() as $entity_type) { + $this->assertDataStructureInterfaces($entity_type); + } + } + + /** + * Executes the data structure interfaces tests for the given entity type. + * + * @param string $entity_type + * The entity type to run the tests with. + */ + protected function assertDataStructureInterfaces($entity_type) { + $entity = $this->createTestEntity($entity_type); $entity->save(); $entity_definition = array( 'type' => 'entity', 'constraints' => array( - 'entity type' => 'entity_test', + 'entity type' => $entity_type, ), 'label' => t('Test entity'), ); @@ -404,7 +469,7 @@ public function testDataStructureInterfaces() { // Field format. NULL, ); - $this->assertEqual($strings, $target_strings, 'All contained strings found.'); + $this->assertEqual($strings, $target_strings, format_string('%entity_type: All contained strings found.', array('%entity_type' => $entity_type))); } /** @@ -436,21 +501,34 @@ public function getContainedStrings(TypedDataInterface $wrapper, $depth, array & * Tests getting processed property values via a computed property. */ public function testComputedProperties() { + // All entity variations have to have the same results. + foreach (entity_test_entity_types() as $entity_type) { + $this->assertComputedProperties($entity_type); + } + } + + /** + * Executes the computed properties tests for the given entity type. + * + * @param string $entity_type + * The entity type to run the tests with. + */ + protected function assertComputedProperties($entity_type) { // Make the test text field processed. - $instance = field_info_instance('entity_test', 'field_test_text', 'entity_test'); + $instance = field_info_instance($entity_type, 'field_test_text', $entity_type); $instance['settings']['text_processing'] = 1; field_update_instance($instance); - $entity = $this->createTestEntity(); + $entity = $this->createTestEntity($entity_type); $entity->field_test_text->value = "The text text to filter."; $entity->field_test_text->format = filter_default_format(); $target = "

The <strong>text</strong> text to filter.

\n"; - $this->assertEqual($entity->field_test_text->processed, $target, 'Text is processed with the default filter.'); + $this->assertEqual($entity->field_test_text->processed, $target, format_string('%entity_type: Text is processed with the default filter.', array('%entity_type' => $entity_type))); // Save and load entity and make sure it still works. $entity->save(); - $entity = entity_load('entity_test', $entity->id()); - $this->assertEqual($entity->field_test_text->processed, $target, 'Text is processed with the default filter.'); + $entity = entity_load($entity_type, $entity->id()); + $this->assertEqual($entity->field_test_text->processed, $target, format_string('%entity_type: Text is processed with the default filter.', array('%entity_type' => $entity_type))); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFormTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFormTest.php index 278e151..a978107 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFormTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFormTest.php @@ -39,6 +39,19 @@ function setUp() { * Tests basic form CRUD functionality. */ function testFormCRUD() { + // All entity variations have to have the same results. + foreach (entity_test_entity_types() as $entity_type) { + $this->assertFormCRUD($entity_type); + } + } + + /** + * Executes the form CRUD tests for the given entity type. + * + * @param string $entity_type + * The entity type to run the tests with. + */ + protected function assertFormCRUD($entity_type) { $langcode = LANGUAGE_NOT_SPECIFIED; $name1 = $this->randomName(8); $name2 = $this->randomName(10); @@ -49,28 +62,27 @@ function testFormCRUD() { "field_test_text[$langcode][0][value]" => $this->randomName(16), ); - $this->drupalPost('entity-test/add', $edit, t('Save')); - $entity = $this->loadEntityByName($name1); - $this->assertTrue($entity, 'Entity found in the database.'); + $this->drupalPost($entity_type . '/add', $edit, t('Save')); + $entity = $this->loadEntityByName($entity_type, $name1); + $this->assertTrue($entity, format_string('%entity_type: Entity found in the database.', array('%entity_type' => $entity_type))); $edit['name'] = $name2; - $this->drupalPost('entity-test/manage/' . $entity->id() . '/edit', $edit, t('Save')); - $entity = $this->loadEntityByName($name1); - $this->assertFalse($entity, 'The entity has been modified.'); - $entity = $this->loadEntityByName($name2); - $this->assertTrue($entity, 'Modified entity found in the database.'); - $this->assertNotEqual($entity->name->value, $name1, 'The entity name has been modified.'); + $this->drupalPost($entity_type . '/manage/' . $entity->id() . '/edit', $edit, t('Save')); + $entity = $this->loadEntityByName($entity_type, $name1); + $this->assertFalse($entity, format_string('%entity_type: The entity has been modified.', array('%entity_type' => $entity_type))); + $entity = $this->loadEntityByName($entity_type, $name2); + $this->assertTrue($entity, format_string('%entity_type: Modified entity found in the database.', array('%entity_type' => $entity_type))); + $this->assertNotEqual($entity->name->value, $name1, format_string('%entity_type: The entity name has been modified.', array('%entity_type' => $entity_type))); - $this->drupalPost('entity-test/manage/' . $entity->id() . '/edit', array(), t('Delete')); - $entity = $this->loadEntityByName($name2); - $this->assertFalse($entity, 'Entity not found in the database.'); + $this->drupalPost($entity_type . '/manage/' . $entity->id() . '/edit', array(), t('Delete')); + $entity = $this->loadEntityByName($entity_type, $name2); + $this->assertFalse($entity, format_string('%entity_type: Entity not found in the database.', array('%entity_type' => $entity_type))); } /** * Loads a test entity by name always resetting the storage controller cache. */ - protected function loadEntityByName($name) { - $entity_type = 'entity_test'; + protected function loadEntityByName($entity_type, $name) { // Always load the entity from the database to ensure that changes are // correctly picked up. entity_get_controller($entity_type)->resetCache(); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityRevisionsTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityRevisionsTest.php index 6783494..152527b 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityRevisionsTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityRevisionsTest.php @@ -47,8 +47,22 @@ public function setUp() { */ public function testRevisions() { + // All revisable entity variations have to have the same results. + foreach (entity_test_entity_types(ENTITY_TEST_TYPES_REVISABLE) as $entity_type) { + $this->assertRevisions($entity_type); + } + } + + /** + * Executes the revision tests for the given entity type. + * + * @param string $entity_type + * The entity type to run the tests with. + */ + protected function assertRevisions($entity_type) { + // Create initial entity. - $entity = entity_create('entity_test', array( + $entity = entity_create($entity_type, array( 'name' => 'foo', 'user_id' => $this->web_user->uid, )); @@ -67,7 +81,7 @@ public function testRevisions() { $legacy_name = $entity->name->value; $legacy_text = $entity->field_test_text->value; - $entity = entity_test_load($entity->id->value); + $entity = entity_load($entity_type, $entity->id->value); $entity->setNewRevision(TRUE); $names[] = $entity->name->value = $this->randomName(32); $texts[] = $entity->field_test_text->value = $this->randomName(32); @@ -75,25 +89,25 @@ public function testRevisions() { $revision_ids[] = $entity->revision_id->value; // Check that the fields and properties contain new content. - $this->assertTrue($entity->revision_id->value > $legacy_revision_id, 'Revision ID changed.'); - $this->assertNotEqual($entity->name->value, $legacy_name, 'Name changed.'); - $this->assertNotEqual($entity->field_test_text->value, $legacy_text, 'Text changed.'); + $this->assertTrue($entity->revision_id->value > $legacy_revision_id, format_string('%entity_type: Revision ID changed.', array('%entity_type' => $entity_type))); + $this->assertNotEqual($entity->name->value, $legacy_name, format_string('%entity_type: Name changed.', array('%entity_type' => $entity_type))); + $this->assertNotEqual($entity->field_test_text->value, $legacy_text, format_string('%entity_type: Text changed.', array('%entity_type' => $entity_type))); } for ($i = 0; $i < $revision_count; $i++) { // Load specific revision. - $entity_revision = entity_revision_load('entity_test', $revision_ids[$i]); + $entity_revision = entity_revision_load($entity_type, $revision_ids[$i]); // Check if properties and fields contain the revision specific content. - $this->assertEqual($entity_revision->revision_id->value, $revision_ids[$i], 'Revision ID matches.'); - $this->assertEqual($entity_revision->name->value, $names[$i], 'Name matches.'); - $this->assertEqual($entity_revision->field_test_text->value, $texts[$i], 'Text matches.'); + $this->assertEqual($entity_revision->revision_id->value, $revision_ids[$i], format_string('%entity_type: Revision ID matches.', array('%entity_type' => $entity_type))); + $this->assertEqual($entity_revision->name->value, $names[$i], format_string('%entity_type: Name matches.', array('%entity_type' => $entity_type))); + $this->assertEqual($entity_revision->field_test_text->value, $texts[$i], format_string('%entity_type: Text matches.', array('%entity_type' => $entity_type))); } // Confirm the correct revision text appears in the edit form. - $entity = entity_load('entity_test', $entity->id->value); - $this->drupalGet('entity-test/manage/' . $entity->id->value); - $this->assertFieldById('edit-name', $entity->name->value, 'Name matches in UI.'); - $this->assertFieldById('edit-field-test-text-und-0-value', $entity->field_test_text->value, 'Text matches in UI.'); + $entity = entity_load($entity_type, $entity->id->value); + $this->drupalGet($entity_type . '/manage/' . $entity->id->value); + $this->assertFieldById('edit-name', $entity->name->value, format_string('%entity_type: Name matches in UI.', array('%entity_type' => $entity_type))); + $this->assertFieldById('edit-field-test-text-und-0-value', $entity->field_test_text->value, format_string('%entity_type: Text matches in UI.', array('%entity_type' => $entity_type))); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php index 370622d..b658cd9 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php @@ -50,13 +50,16 @@ function setUp() { field_create_field($field); $this->field = field_read_field($this->field_name); - $instance = array( - 'field_name' => $this->field_name, - 'entity_type' => 'entity_test', - 'bundle' => 'entity_test', - ); - field_create_instance($instance); - $this->instance = field_read_instance('entity_test', $this->field_name, 'entity_test'); + // Create instance in all entity variations. + foreach (entity_test_entity_types() as $entity_type) { + $instance = array( + 'field_name' => $this->field_name, + 'entity_type' => $entity_type, + 'bundle' => $entity_type, + ); + field_create_instance($instance); + $this->instance[$entity_type] = field_read_instance($entity_type, $this->field_name, $entity_type); + } // Create test languages. $this->langcodes = array(); @@ -73,45 +76,58 @@ function setUp() { /** * Tests language related methods of the Entity class. */ - function testEntityLanguageMethods() { - $entity = entity_create('entity_test', array( + public function testEntityLanguageMethods() { + // All entity variations have to have the same results. + foreach (entity_test_entity_types() as $entity_type) { + $this->assertEntityLanguageMethods($entity_type); + } + } + + /** + * Executes the entity language method tests for the given entity type. + * + * @param string $entity_type + * The entity type to run the tests with. + */ + protected function assertEntityLanguageMethods($entity_type) { + $entity = entity_create($entity_type, array( 'name' => 'test', 'user_id' => $GLOBALS['user']->uid, )); - $this->assertEqual($entity->language()->langcode, LANGUAGE_NOT_SPECIFIED, 'Entity language not specified.'); - $this->assertFalse($entity->getTranslationLanguages(FALSE), 'No translations are available'); + $this->assertEqual($entity->language()->langcode, LANGUAGE_NOT_SPECIFIED, format_string('%entity_type: Entity language not specified.', array('%entity_type' => $entity_type))); + $this->assertFalse($entity->getTranslationLanguages(FALSE), format_string('%entity_type: No translations are available', array('%entity_type' => $entity_type))); // Set the value in default language. $entity->set($this->field_name, array(0 => array('value' => 'default value'))); // Get the value. - $this->assertEqual($entity->getTranslation(LANGUAGE_DEFAULT)->get($this->field_name)->value, 'default value', 'Untranslated value retrieved.'); + $this->assertEqual($entity->getTranslation(LANGUAGE_DEFAULT)->get($this->field_name)->value, 'default value', format_string('%entity_type: Untranslated value retrieved.', array('%entity_type' => $entity_type))); // Set the value in a certain language. As the entity is not // language-specific it should use the default language and so ignore the // specified language. $entity->getTranslation($this->langcodes[1])->set($this->field_name, array(0 => array('value' => 'default value2'))); - $this->assertEqual($entity->get($this->field_name)->value, 'default value2', 'Untranslated value updated.'); - $this->assertFalse($entity->getTranslationLanguages(FALSE), 'No translations are available'); + $this->assertEqual($entity->get($this->field_name)->value, 'default value2', format_string('%entity_type: Untranslated value updated.', array('%entity_type' => $entity_type))); + $this->assertFalse($entity->getTranslationLanguages(FALSE), format_string('%entity_type: No translations are available', array('%entity_type' => $entity_type))); // Test getting a field value using a specific language for a not // language-specific entity. - $this->assertEqual($entity->getTranslation($this->langcodes[1])->get($this->field_name)->value, 'default value2', 'Untranslated value retrieved.'); + $this->assertEqual($entity->getTranslation($this->langcodes[1])->get($this->field_name)->value, 'default value2', format_string('%entity_type: Untranslated value retrieved.', array('%entity_type' => $entity_type))); // Now, make the entity language-specific by assigning a language and test // translating it. $entity->langcode->value = $this->langcodes[0]; $entity->{$this->field_name} = array(); - $this->assertEqual($entity->language(), language_load($this->langcodes[0]), 'Entity language retrieved.'); - $this->assertFalse($entity->getTranslationLanguages(FALSE), 'No translations are available'); + $this->assertEqual($entity->language(), language_load($this->langcodes[0]), format_string('%entity_type: Entity language retrieved.', array('%entity_type' => $entity_type))); + $this->assertFalse($entity->getTranslationLanguages(FALSE), format_string('%entity_type: No translations are available', array('%entity_type' => $entity_type))); // Set the value in default language. $entity->set($this->field_name, array(0 => array('value' => 'default value'))); // Get the value. - $this->assertEqual($entity->get($this->field_name)->value, 'default value', 'Untranslated value retrieved.'); + $this->assertEqual($entity->get($this->field_name)->value, 'default value', format_string('%entity_type: Untranslated value retrieved.', array('%entity_type' => $entity_type))); // Set a translation. $entity->getTranslation($this->langcodes[1])->set($this->field_name, array(0 => array('value' => 'translation 1'))); - $this->assertEqual($entity->getTranslation($this->langcodes[1])->{$this->field_name}->value, 'translation 1', 'Translated value set.'); + $this->assertEqual($entity->getTranslation($this->langcodes[1])->{$this->field_name}->value, 'translation 1', format_string('%entity_type: Translated value set.', array('%entity_type' => $entity_type))); // Make sure the untranslated value stays. $this->assertEqual($entity->get($this->field_name)->value, 'default value', 'Untranslated value stays.'); @@ -120,7 +136,7 @@ function testEntityLanguageMethods() { $this->assertEqual($entity->getTranslationLanguages(FALSE), $translations, 'Translations retrieved.'); // Try to get a not available translation. - $this->assertNull($entity->getTranslation($this->langcodes[2])->get($this->field_name)->value, 'A translation that is not available is NULL.'); + $this->assertNull($entity->getTranslation($this->langcodes[2])->get($this->field_name)->value, format_string('%entity_type: A translation that is not available is NULL.', array('%entity_type' => $entity_type))); // Try to get a value using an invalid language code. try { @@ -135,79 +151,92 @@ function testEntityLanguageMethods() { try { $field_name = 'field_test_text'; $value = $entity->getTranslation($this->langcodes[1])->get($field_name); - $this->fail('Getting an untranslatable value from a translation in strict mode throws an exception.'); + $this->fail(format_string('%entity_type: Getting an untranslatable value from a translation in strict mode throws an exception.', array('%entity_type' => $entity_type))); } catch (InvalidArgumentException $e) { - $this->pass('Getting an untranslatable value from a translation in strict mode throws an exception.'); + $this->pass(format_string('%entity_type: Getting an untranslatable value from a translation in strict mode throws an exception.', array('%entity_type' => $entity_type))); } // Try to get an untranslatable value from a translation in non-strict // mode. $entity->set($field_name, array(0 => array('value' => 'default value'))); $value = $entity->getTranslation($this->langcodes[1], FALSE)->get($field_name)->value; - $this->assertEqual($value, 'default value', 'Untranslated value retrieved from translation in non-strict mode.'); + $this->assertEqual($value, 'default value', format_string('%entity_type: Untranslated value retrieved from translation in non-strict mode.', array('%entity_type' => $entity_type))); // Try to set a value using an invalid language code. try { $entity->getTranslation('invalid')->set($this->field_name, NULL); - $this->fail("Setting a translation for an invalid language throws an exception."); + $this->fail(format_string('%entity_type: Setting a translation for an invalid language throws an exception.', array('%entity_type' => $entity_type))); } catch (InvalidArgumentException $e) { - $this->pass("Setting a translation for an invalid language throws an exception."); + $this->pass(format_string('%entity_type: Setting a translation for an invalid language throws an exception.', array('%entity_type' => $entity_type))); } // Try to set an untranslatable value into a translation in strict mode. try { $entity->getTranslation($this->langcodes[1])->set($field_name, NULL); - $this->fail("Setting an untranslatable value into a translation in strict mode throws an exception."); + $this->fail(format_string('%entity_type: Setting an untranslatable value into a translation in strict mode throws an exception.', array('%entity_type' => $entity_type))); } catch (InvalidArgumentException $e) { - $this->pass("Setting an untranslatable value into a translation in strict mode throws an exception."); + $this->pass(format_string('%entity_type: Setting an untranslatable value into a translation in strict mode throws an exception.', array('%entity_type' => $entity_type))); } // Set the value in default language. $entity->getTranslation($this->langcodes[1], FALSE)->set($field_name, array(0 => array('value' => 'default value2'))); // Get the value. - $this->assertEqual($entity->get($field_name)->value, 'default value2', 'Untranslated value set into a translation in non-strict mode.'); + $this->assertEqual($entity->get($field_name)->value, 'default value2', format_string('%entity_type: Untranslated value set into a translation in non-strict mode.', array('%entity_type' => $entity_type))); } /** * Tests multilingual properties. */ - function testMultilingualProperties() { + public function testMultilingualProperties() { + // Test all entity variations with data table support. + foreach (entity_test_entity_types(ENTITY_TEST_TYPES_MULTILINGUAL) as $entity_type) { + $this->assertMultilingualProperties($entity_type); + } + } + + /** + * Executes the multilingual property tests for the given entity type. + * + * @param string $entity_type + * The entity type to run the tests with. + */ + protected function assertMultilingualProperties($entity_type) { $name = $this->randomName(); $uid = mt_rand(0, 127); $langcode = $this->langcodes[0]; // Create a language neutral entity and check that properties are stored // as language neutral. - $entity = entity_create('entity_test', array('name' => $name, 'user_id' => $uid)); + $entity = entity_create($entity_type, array('name' => $name, 'user_id' => $uid)); $entity->save(); - $entity = entity_test_load($entity->id()); - $this->assertEqual($entity->language()->langcode, LANGUAGE_NOT_SPECIFIED, 'Entity created as language neutral.'); - $this->assertEqual($name, $entity->getTranslation(LANGUAGE_DEFAULT)->get('name')->value, 'The entity name has been correctly stored as language neutral.'); - $this->assertEqual($uid, $entity->getTranslation(LANGUAGE_DEFAULT)->get('user_id')->value, 'The entity author has been correctly stored as language neutral.'); + $entity = entity_load($entity_type, $entity->id()); + $this->assertEqual($entity->language()->langcode, LANGUAGE_NOT_SPECIFIED, format_string('%entity_type: Entity created as language neutral.', array('%entity_type' => $entity_type))); + $this->assertEqual($name, $entity->getTranslation(LANGUAGE_DEFAULT)->get('name')->value, format_string('%entity_type: The entity name has been correctly stored as language neutral.', array('%entity_type' => $entity_type))); + $this->assertEqual($uid, $entity->getTranslation(LANGUAGE_DEFAULT)->get('user_id')->value, format_string('%entity_type: The entity author has been correctly stored as language neutral.', array('%entity_type' => $entity_type))); // As fields, translatable properties should ignore the given langcode and // use neutral language if the entity is not translatable. - $this->assertEqual($name, $entity->getTranslation($langcode)->get('name')->value, 'The entity name defaults to neutral language.'); - $this->assertEqual($uid, $entity->getTranslation($langcode)->get('user_id')->value, 'The entity author defaults to neutral language.'); - $this->assertEqual($name, $entity->get('name')->value, 'The entity name can be retrieved without specifying a language.'); - $this->assertEqual($uid, $entity->get('user_id')->value, 'The entity author can be retrieved without specifying a language.'); + $this->assertEqual($name, $entity->getTranslation($langcode)->get('name')->value, format_string('%entity_type: The entity name defaults to neutral language.', array('%entity_type' => $entity_type))); + $this->assertEqual($uid, $entity->getTranslation($langcode)->get('user_id')->value, format_string('%entity_type: The entity author defaults to neutral language.', array('%entity_type' => $entity_type))); + $this->assertEqual($name, $entity->get('name')->value, format_string('%entity_type: The entity name can be retrieved without specifying a language.', array('%entity_type' => $entity_type))); + $this->assertEqual($uid, $entity->get('user_id')->value, format_string('%entity_type: The entity author can be retrieved without specifying a language.', array('%entity_type' => $entity_type))); // Create a language-aware entity and check that properties are stored // as language-aware. - $entity = entity_create('entity_test', array('name' => $name, 'user_id' => $uid, 'langcode' => $langcode)); + $entity = entity_create($entity_type, array('name' => $name, 'user_id' => $uid, 'langcode' => $langcode)); $entity->save(); - $entity = entity_test_load($entity->id()); - $this->assertEqual($entity->language()->langcode, $langcode, 'Entity created as language specific.'); - $this->assertEqual($name, $entity->getTranslation($langcode)->get('name')->value, 'The entity name has been correctly stored as a language-aware property.'); - $this->assertEqual($uid, $entity->getTranslation($langcode)->get('user_id')->value, 'The entity author has been correctly stored as a language-aware property.'); + $entity = entity_load($entity_type, $entity->id()); + $this->assertEqual($entity->language()->langcode, $langcode, format_string('%entity_type: Entity created as language specific.', array('%entity_type' => $entity_type))); + $this->assertEqual($name, $entity->getTranslation($langcode)->get('name')->value, format_string('%entity_type: The entity name has been correctly stored as a language-aware property.', array('%entity_type' => $entity_type))); + $this->assertEqual($uid, $entity->getTranslation($langcode)->get('user_id')->value, format_string('%entity_type: The entity author has been correctly stored as a language-aware property.', array('%entity_type' => $entity_type))); // Translatable properties on a translatable entity should use default // language if LANGUAGE_NOT_SPECIFIED is passed. - $this->assertEqual($name, $entity->getTranslation(LANGUAGE_NOT_SPECIFIED)->get('name')->value, 'The entity name defaults to the default language.'); - $this->assertEqual($uid, $entity->getTranslation(LANGUAGE_NOT_SPECIFIED)->get('user_id')->value, 'The entity author defaults to the default language.'); - $this->assertEqual($name, $entity->get('name')->value, 'The entity name can be retrieved without specifying a language.'); - $this->assertEqual($uid, $entity->get('user_id')->value, 'The entity author can be retrieved without specifying a language.'); + $this->assertEqual($name, $entity->getTranslation(LANGUAGE_NOT_SPECIFIED)->get('name')->value, format_string('%entity_type: The entity name defaults to the default language.', array('%entity_type' => $entity_type))); + $this->assertEqual($uid, $entity->getTranslation(LANGUAGE_NOT_SPECIFIED)->get('user_id')->value, format_string('%entity_type: The entity author defaults to the default language.', array('%entity_type' => $entity_type))); + $this->assertEqual($name, $entity->get('name')->value, format_string('%entity_type: The entity name can be retrieved without specifying a language.', array('%entity_type' => $entity_type))); + $this->assertEqual($uid, $entity->get('user_id')->value, format_string('%entity_type: The entity author can be retrieved without specifying a language.', array('%entity_type' => $entity_type))); // Create property translations. $properties = array(); @@ -230,11 +259,14 @@ function testMultilingualProperties() { $entity->save(); // Check that property translation were correctly stored. - $entity = entity_test_load($entity->id()); + $entity = entity_load($entity_type, $entity->id()); foreach ($this->langcodes as $langcode) { - $args = array('%langcode' => $langcode); - $this->assertEqual($properties[$langcode]['name'][0], $entity->getTranslation($langcode)->get('name')->value, format_string('The entity name has been correctly stored for language %langcode.', $args)); - $this->assertEqual($properties[$langcode]['user_id'][0], $entity->getTranslation($langcode)->get('user_id')->value, format_string('The entity author has been correctly stored for language %langcode.', $args)); + $args = array( + '%entity_type' => $entity_type, + '%langcode' => $langcode, + ); + $this->assertEqual($properties[$langcode]['name'][0], $entity->getTranslation($langcode)->get('name')->value, format_string('%entity_type: The entity name has been correctly stored for language %langcode.', $args)); + $this->assertEqual($properties[$langcode]['user_id'][0], $entity->getTranslation($langcode)->get('user_id')->value, format_string('%entity_type: The entity author has been correctly stored for language %langcode.', $args)); } // Test query conditions (cache is reset at each call). @@ -242,34 +274,34 @@ function testMultilingualProperties() { // Create an additional entity with only the uid set. The uid for the // original language is the same of one used for a translation. $langcode = $this->langcodes[1]; - entity_create('entity_test', array( + entity_create($entity_type, array( 'user_id' => $properties[$langcode]['user_id'], 'name' => 'some name', ))->save(); - $entities = entity_test_load_multiple(); - $this->assertEqual(count($entities), 3, 'Three entities were created.'); - $entities = entity_test_load_multiple(array($translated_id)); - $this->assertEqual(count($entities), 1, 'One entity correctly loaded by id.'); - $entities = entity_load_multiple_by_properties('entity_test', array('name' => $name)); - $this->assertEqual(count($entities), 2, 'Two entities correctly loaded by name.'); + $entities = entity_load_multiple($entity_type); + $this->assertEqual(count($entities), 3, format_string('%entity_type: Three entities were created.', array('%entity_type' => $entity_type))); + $entities = entity_load_multiple($entity_type, array($translated_id)); + $this->assertEqual(count($entities), 1, format_string('%entity_type: One entity correctly loaded by id.', array('%entity_type' => $entity_type))); + $entities = entity_load_multiple_by_properties($entity_type, array('name' => $name)); + $this->assertEqual(count($entities), 2, format_string('%entity_type: Two entities correctly loaded by name.', array('%entity_type' => $entity_type))); // @todo The default language condition should go away in favor of an // explicit parameter. - $entities = entity_load_multiple_by_properties('entity_test', array('name' => $properties[$langcode]['name'][0], 'default_langcode' => 0)); - $this->assertEqual(count($entities), 1, 'One entity correctly loaded by name translation.'); - $entities = entity_load_multiple_by_properties('entity_test', array('langcode' => $default_langcode, 'name' => $name)); - $this->assertEqual(count($entities), 1, 'One entity correctly loaded by name and language.'); - - $entities = entity_load_multiple_by_properties('entity_test', array('langcode' => $langcode, 'name' => $properties[$langcode]['name'][0])); - $this->assertEqual(count($entities), 0, 'No entity loaded by name translation specifying the translation language.'); - $entities = entity_load_multiple_by_properties('entity_test', array('langcode' => $langcode, 'name' => $properties[$langcode]['name'][0], 'default_langcode' => 0)); - $this->assertEqual(count($entities), 1, 'One entity loaded by name translation and language specifying to look for translations.'); - $entities = entity_load_multiple_by_properties('entity_test', array('user_id' => $properties[$langcode]['user_id'][0], 'default_langcode' => NULL)); - $this->assertEqual(count($entities), 2, 'Two entities loaded by uid without caring about property translatability.'); + $entities = entity_load_multiple_by_properties($entity_type, array('name' => $properties[$langcode]['name'][0], 'default_langcode' => 0)); + $this->assertEqual(count($entities), 1, format_string('%entity_type: One entity correctly loaded by name translation.', array('%entity_type' => $entity_type))); + $entities = entity_load_multiple_by_properties($entity_type, array('langcode' => $default_langcode, 'name' => $name)); + $this->assertEqual(count($entities), 1, format_string('%entity_type: One entity correctly loaded by name and language.', array('%entity_type' => $entity_type))); + + $entities = entity_load_multiple_by_properties($entity_type, array('langcode' => $langcode, 'name' => $properties[$langcode]['name'][0])); + $this->assertEqual(count($entities), 0, format_string('%entity_type: No entity loaded by name translation specifying the translation language.', array('%entity_type' => $entity_type))); + $entities = entity_load_multiple_by_properties($entity_type, array('langcode' => $langcode, 'name' => $properties[$langcode]['name'][0], 'default_langcode' => 0)); + $this->assertEqual(count($entities), 1, format_string('%entity_type: One entity loaded by name translation and language specifying to look for translations.', array('%entity_type' => $entity_type))); + $entities = entity_load_multiple_by_properties($entity_type, array('user_id' => $properties[$langcode]['user_id'][0], 'default_langcode' => NULL)); + $this->assertEqual(count($entities), 2, format_string('%entity_type: Two entities loaded by uid without caring about property translatability.', array('%entity_type' => $entity_type))); // Test property conditions and orders with multiple languages in the same // query. - $query = entity_query('entity_test'); + $query = entity_query($entity_type); $group = $query->andConditionGroup() ->condition('user_id', $properties[$default_langcode]['user_id'], '=', $default_langcode) ->condition('name', $properties[$default_langcode]['name'], '=', $default_langcode); @@ -277,14 +309,14 @@ function testMultilingualProperties() { ->condition($group) ->condition('name', $properties[$langcode]['name'], '=', $langcode) ->execute(); - $this->assertEqual(count($result), 1, 'One entity loaded by name and uid using different language meta conditions.'); + $this->assertEqual(count($result), 1, format_string('%entity_type: One entity loaded by name and uid using different language meta conditions.', array('%entity_type' => $entity_type))); // Test mixed property and field conditions. - $entity = entity_load('entity_test', reset($result), TRUE); + $entity = entity_load($entity_type, reset($result), TRUE); $field_value = $this->randomString(); $entity->getTranslation($langcode)->set($this->field_name, array(array('value' => $field_value))); $entity->save(); - $query = entity_query('entity_test'); + $query = entity_query($entity_type); $default_langcode_group = $query->andConditionGroup() ->condition('user_id', $properties[$default_langcode]['user_id'], '=', $default_langcode) ->condition('name', $properties[$default_langcode]['name'], '=', $default_langcode); @@ -296,7 +328,7 @@ function testMultilingualProperties() { ->condition($default_langcode_group) ->condition($langcode_group) ->execute(); - $this->assertEqual(count($result), 1, 'One entity loaded by name, uid and field value using different language meta conditions.'); + $this->assertEqual(count($result), 1, format_string('%entity_type: One entity loaded by name, uid and field value using different language meta conditions.', array('%entity_type' => $entity_type))); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUUIDTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUUIDTest.php index cb2f7f3..15220cb 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUUIDTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUUIDTest.php @@ -34,10 +34,23 @@ public static function getInfo() { * Tests UUID generation in entity CRUD operations. */ function testCRUD() { + // All entity variations have to have the same results. + foreach (entity_test_entity_types() as $entity_type) { + $this->assertCRUD($entity_type); + } + } + + /** + * Executes the UUID CRUD tests for the given entity type. + * + * @param string $entity_type + * The entity type to run the tests with. + */ + protected function assertCRUD($entity_type) { // Verify that no UUID is auto-generated when passing one for creation. $uuid_service = new Uuid(); $uuid = $uuid_service->generate(); - $custom_entity = entity_create('entity_test', array( + $custom_entity = entity_create($entity_type, array( 'name' => $this->randomName(), 'uuid' => $uuid, )); @@ -46,7 +59,7 @@ function testCRUD() { $custom_entity->save(); // Verify that a new UUID is generated upon creating an entity. - $entity = entity_create('entity_test', array('name' => $this->randomName())); + $entity = entity_create($entity_type, array('name' => $this->randomName())); $uuid = $entity->uuid(); $this->assertTrue($uuid); @@ -58,11 +71,11 @@ function testCRUD() { $this->assertIdentical($entity->uuid(), $uuid); // Verify that the UUID is retained upon loading. - $entity_loaded = entity_test_load($entity->id(), TRUE); + $entity_loaded = entity_load($entity_type, $entity->id(), TRUE); $this->assertIdentical($entity_loaded->uuid(), $uuid); // Verify that entity_load_by_uuid() loads the same entity. - $entity_loaded_by_uuid = entity_load_by_uuid('entity_test', $uuid, TRUE); + $entity_loaded_by_uuid = entity_load_by_uuid($entity_type, $uuid, TRUE); $this->assertIdentical($entity_loaded_by_uuid->uuid(), $uuid); $this->assertEqual($entity_loaded_by_uuid->id(), $entity_loaded->id()); diff --git a/core/modules/system/lib/Drupal/system/Tests/Serialization/EntitySerializationTest.php b/core/modules/system/lib/Drupal/system/Tests/Serialization/EntitySerializationTest.php index f34cd9d..ea3c960 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Serialization/EntitySerializationTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Serialization/EntitySerializationTest.php @@ -59,7 +59,7 @@ protected function setUp() { 'format' => 'full_html', ), ); - $this->entity = entity_create('entity_test', $this->values); + $this->entity = entity_create('entity_test_mulrev', $this->values); $this->entity->save(); } @@ -105,7 +105,7 @@ public function testNormalize() { foreach (array_keys($expected) as $fieldName) { $this->assertEqual($expected[$fieldName], $normalized[$fieldName], "ComplexDataNormalizer produces expected array for $fieldName."); } - $this->assertEqual(array_keys($expected), array_keys($normalized), 'No unexpected data is added to the normalized array.'); + $this->assertEqual(array_diff_key($normalized, $expected), array(), 'No unexpected data is added to the normalized array.'); } /** diff --git a/core/modules/system/tests/modules/entity_test/entity_test.install b/core/modules/system/tests/modules/entity_test/entity_test.install index 617986a..dacd1f5 100644 --- a/core/modules/system/tests/modules/entity_test/entity_test.install +++ b/core/modules/system/tests/modules/entity_test/entity_test.install @@ -18,23 +18,32 @@ function entity_test_install() { ); field_create_field($field); - $instance = array( - 'entity_type' => 'entity_test', - 'field_name' => 'field_test_text', - 'bundle' => 'entity_test', - 'label' => 'Test text-field', - 'widget' => array( - 'type' => 'text_textfield', - 'weight' => 0, - ), + $entity_types = array( + 'entity_test', + 'entity_test_rev', + 'entity_test_mul', + 'entity_test_mulrev', ); - field_create_instance($instance); + foreach ($entity_types as $entity_type) { + $instance = array( + 'entity_type' => $entity_type, + 'field_name' => 'field_test_text', + 'bundle' => $entity_type, + 'label' => 'Test text-field', + 'widget' => array( + 'type' => 'text_textfield', + 'weight' => 0, + ), + ); + field_create_instance($instance); + } } /** * Implements hook_schema(). */ function entity_test_schema() { + // Schema for simple entity. $schema['entity_test'] = array( 'description' => 'Stores entity_test items.', 'fields' => array( @@ -43,8 +52,215 @@ function entity_test_schema() { 'not null' => TRUE, 'description' => 'Primary Key: Unique entity-test item ID.', ), + 'uuid' => array( + 'description' => 'Unique Key: Universally unique identifier for this entity.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => FALSE, + ), + 'langcode' => array( + 'description' => 'The {language}.langcode of the original variant of this test entity.', + 'type' => 'varchar', + 'length' => 12, + 'not null' => TRUE, + 'default' => '', + ), + 'name' => array( + 'description' => 'The name of the test entity.', + 'type' => 'varchar', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + ), + 'user_id' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + 'default' => NULL, + 'description' => 'The {users}.uid of the associated user.', + ), + ), + 'primary key' => array('id'), + 'unique keys' => array( + 'uuid' => array('uuid'), + ), + ); + + // Schema for entity with revisions. + $schema['entity_test_rev'] = array( + 'description' => 'Stores entity_test_rev items.', + 'fields' => array( + 'id' => array( + 'type' => 'serial', + 'not null' => TRUE, + 'description' => 'Primary Key: Unique entity-test item ID.', + ), + 'revision_id' => array( + 'description' => 'The current {entity_test_rev_property_revision}.revision_id version identifier.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'uuid' => array( + 'description' => 'Unique Key: Universally unique identifier for this entity.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => FALSE, + ), + 'langcode' => array( + 'description' => 'The {language}.langcode of the original variant of this test entity.', + 'type' => 'varchar', + 'length' => 12, + 'not null' => TRUE, + 'default' => '', + ), + 'name' => array( + 'description' => 'The name of the test entity.', + 'type' => 'varchar', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + ), + ), + 'primary key' => array('id'), + 'unique keys' => array( + 'uuid' => array('uuid'), + ), + ); + $schema['entity_test_rev_revision'] = array( + 'description' => 'Stores entity_test_rev item property revisions.', + 'fields' => array( + 'id' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The {entity_test_rev}.id of the test entity.', + ), + 'revision_id' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The primary identifier for this version.', + ), + 'langcode' => array( + 'description' => 'The {language}.langcode of this variant of this test entity.', + 'type' => 'varchar', + 'length' => 12, + 'not null' => TRUE, + 'default' => '', + ), + 'name' => array( + 'description' => 'The name of the test entity.', + 'type' => 'varchar', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + ), + 'user_id' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + 'default' => NULL, + 'description' => 'The {users}.uid of the associated user.', + ), + ), + 'indexes' => array( + 'user_id' => array('user_id'), + ), + 'foreign keys' => array( + 'user_id' => array('users' => 'uid'), + 'id' => array('entity_test_rev' => 'id'), + ), + 'primary key' => array('revision_id', 'id', 'langcode'), + ); + + // Schema for entity with data table. + $schema['entity_test_mul'] = array( + 'description' => 'Stores entity_test_mul items.', + 'fields' => array( + 'id' => array( + 'type' => 'serial', + 'not null' => TRUE, + 'description' => 'Primary Key: Unique entity-test item ID.', + ), + 'uuid' => array( + 'description' => 'Unique Key: Universally unique identifier for this entity.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => FALSE, + ), + 'langcode' => array( + 'description' => 'The {language}.langcode of the original variant of this test entity.', + 'type' => 'varchar', + 'length' => 12, + 'not null' => TRUE, + 'default' => '', + ), + ), + 'primary key' => array('id'), + 'unique keys' => array( + 'uuid' => array('uuid'), + ), + ); + $schema['entity_test_mul_property_data'] = array( + 'description' => 'Stores entity_test_mul item properties.', + 'fields' => array( + 'id' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'The {entity_test_mul}.id of the test entity.', + ), + 'langcode' => array( + 'description' => 'The {language}.langcode of this variant of this test entity.', + 'type' => 'varchar', + 'length' => 12, + 'not null' => TRUE, + 'default' => '', + ), + 'default_langcode' => array( + 'description' => 'Boolean indicating whether the current variant is in the original entity language.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 1, + ), + 'name' => array( + 'description' => 'The name of the test entity.', + 'type' => 'varchar', + 'length' => 32, + 'not null' => TRUE, + 'default' => '', + ), + 'user_id' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + 'default' => NULL, + 'description' => 'The {users}.uid of the associated user.', + ), + ), + 'indexes' => array( + 'user_id' => array('user_id'), + ), + 'foreign keys' => array( + 'user_id' => array('users' => 'uid'), + 'id' => array('entity_test_mul' => 'id'), + ), + 'primary key' => array('id', 'langcode'), + ); + + // Schema for entity with data table and revisions. + $schema['entity_test_mulrev'] = array( + 'description' => 'Stores entity_test_mulrev items.', + 'fields' => array( + 'id' => array( + 'type' => 'serial', + 'not null' => TRUE, + 'description' => 'Primary Key: Unique entity-test item ID.', + ), 'revision_id' => array( - 'description' => 'The current {entity_test_property_revision}.revision_id version identifier.', + 'description' => 'The current {entity_test_mulrev_property_revision}.revision_id version identifier.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, @@ -69,17 +285,17 @@ function entity_test_schema() { 'uuid' => array('uuid'), ), ); - $schema['entity_test_property_data'] = array( - 'description' => 'Stores entity_test item properties.', + $schema['entity_test_mulrev_property_data'] = array( + 'description' => 'Stores entity_test_mulrev item properties.', 'fields' => array( 'id' => array( 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, - 'description' => 'The {entity_test}.id of the test entity.', + 'description' => 'The {entity_test_mulrev}.id of the test entity.', ), 'revision_id' => array( - 'description' => 'The current {entity_test_property_revision}.revision_id version identifier.', + 'description' => 'The current {entity_test_mulrev_property_revision}.revision_id version identifier.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, @@ -110,7 +326,7 @@ function entity_test_schema() { 'unsigned' => TRUE, 'not null' => FALSE, 'default' => NULL, - 'description' => "The {users}.uid of the associated user.", + 'description' => 'The {users}.uid of the associated user.', ), ), 'indexes' => array( @@ -118,18 +334,18 @@ function entity_test_schema() { ), 'foreign keys' => array( 'user_id' => array('users' => 'uid'), - 'id' => array('entity_test' => 'id'), + 'id' => array('entity_test_mulrev' => 'id'), ), 'primary key' => array('id', 'langcode'), ); - $schema['entity_test_property_revision'] = array( - 'description' => 'Stores entity_test item property revisions.', + $schema['entity_test_mulrev_property_revision'] = array( + 'description' => 'Stores entity_test_mulrev item property revisions.', 'fields' => array( 'id' => array( 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, - 'description' => 'The {entity_test}.id of the test entity.', + 'description' => 'The {entity_test_mulrev}.id of the test entity.', ), 'revision_id' => array( 'type' => 'serial', @@ -162,7 +378,7 @@ function entity_test_schema() { 'unsigned' => TRUE, 'not null' => FALSE, 'default' => NULL, - 'description' => "The {users}.uid of the associated user.", + 'description' => 'The {users}.uid of the associated user.', ), ), 'indexes' => array( @@ -170,9 +386,10 @@ function entity_test_schema() { ), 'foreign keys' => array( 'user_id' => array('users' => 'uid'), - 'id' => array('entity_test' => 'id'), + 'id' => array('entity_test_mulrev' => 'id'), ), 'primary key' => array('revision_id', 'id', 'langcode'), ); + return $schema; } diff --git a/core/modules/system/tests/modules/entity_test/entity_test.module b/core/modules/system/tests/modules/entity_test/entity_test.module index f2b5b38..a84f302 100644 --- a/core/modules/system/tests/modules/entity_test/entity_test.module +++ b/core/modules/system/tests/modules/entity_test/entity_test.module @@ -2,11 +2,54 @@ /** * @file - * Test module for the entity API providing an entity type for testing. + * Test module for the entity API providing several entity types for testing. */ -use Drupal\entity_test\Plugin\Core\Entity\EntityTest; +use Drupal\Core\Entity\EntityInterface; +/** + * Filter that limits test entity list to revisable ones. + */ +const ENTITY_TEST_TYPES_REVISABLE = 1; + +/** + * Filter that limits test entity list to multilingual ones. + */ +const ENTITY_TEST_TYPES_MULTILINGUAL = 2; + +/** + * Returns a list of test entity types. + * + * The returned entity types are one for each available entity storage type: + * - The plain entity_test type supports neither revisions nor multilingual + * properties. + * - The entity_test_mul type supports multilingual properties. + * - The entity_test_rev type supports revisions. + * - The entity_test_mulrev type supports both revisions and multilingual + * properties. + * + * @param int $filter + * Either ENTITY_TEST_TYPES_REVISABLE to only return revisable entity types or + * ENTITY_TEST_TYPES_MULTILINGUAL to only return multilingual ones. Defaults + * to NULL, which returns all. + * + * @return array + * List with entity_types. + */ +function entity_test_entity_types($filter = NULL) { + $types = array(); + if ($filter == NULL) { + $types[] = 'entity_test'; + } + if ($filter != ENTITY_TEST_TYPES_REVISABLE) { + $types[] = 'entity_test_mul'; + } + if ($filter != ENTITY_TEST_TYPES_MULTILINGUAL) { + $types[] = 'entity_test_rev'; + } + $types[] = 'entity_test_mulrev'; + return drupal_map_assoc($types); +} /** * Implements hook_entity_info_alter(). @@ -14,7 +57,9 @@ function entity_test_entity_info_alter(&$info) { // Optionally specify a translation handler for testing translations. if (state()->get('entity_test.translation')) { - $info['entity_test']['translation']['entity_test'] = TRUE; + foreach(entity_test_entity_types() as $entity_type) { + $info[$entity_type]['translation'][$entity_type] = TRUE; + } } } @@ -69,55 +114,71 @@ function entity_test_permission() { function entity_test_menu() { $items = array(); - $items['entity-test/add'] = array( - 'title' => 'Add an entity_test', - 'page callback' => 'entity_test_add', - 'access arguments' => array('administer entity_test content'), - 'type' => MENU_NORMAL_ITEM, - ); - - $items['entity-test/manage/%entity_test'] = array( - 'title' => 'Edit test entity', - 'page callback' => 'entity_test_edit', - 'page arguments' => array(2), - 'access arguments' => array('administer entity_test content'), - 'type' => MENU_NORMAL_ITEM, - ); - - $items['entity-test/manage/%entity_test/edit'] = array( - 'title' => 'Edit', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); + foreach(entity_test_entity_types() as $entity_type) { + $items[$entity_type . '/add'] = array( + 'title' => 'Add an @type', + 'title arguments' => array('@type' => $entity_type), + 'page callback' => 'entity_test_add', + 'page arguments' => array($entity_type), + 'access arguments' => array('administer entity_test content'), + 'type' => MENU_NORMAL_ITEM, + ); + + $items[$entity_type . '/manage/%' . $entity_type] = array( + 'title' => 'Edit @type', + 'title arguments' => array('@type' => $entity_type), + 'page callback' => 'entity_test_edit', + 'page arguments' => array(2), + 'access arguments' => array('administer entity_test content'), + 'type' => MENU_NORMAL_ITEM, + ); + + $items[$entity_type . '/manage/%' . $entity_type . '/edit'] = array( + 'title' => 'Edit', + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); + } return $items; } /** + * Implements hook_form_BASE_FORM_ID_alter(). + */ +function entity_test_form_node_form_alter(&$form, &$form_state, $form_id) { + $langcode = $form_state['controller']->getFormLangcode($form_state); + variable_set('entity_form_langcode', $langcode); +} + +/** * Menu callback: displays the 'Add new entity_test' form. * + * @param string $entity_type + * Name of the entity type for which a create form should be displayed. + * * @return array * The processed form for a new entity_test. * * @see entity_test_menu() */ -function entity_test_add() { - drupal_set_title(t('Create an entity_test')); - $entity = entity_create('entity_test', array()); +function entity_test_add($entity_type) { + drupal_set_title(t('Create an @type', array('@type' => $entity_type))); + $entity = entity_create($entity_type, array()); return entity_get_form($entity); } /** * Menu callback: displays the 'Edit existing entity_test' form. * - * @param array $entity + * @param \Drupal\Core\Entity\EntityInterface $entity * The entity to be edited. * * @return array - * The processed form for the edited entity_test. + * The processed form for the edited entity. * * @see entity_test_menu() */ -function entity_test_edit(EntityTest $entity) { +function entity_test_edit(EntityInterface $entity) { drupal_set_title($entity->label(), PASS_THROUGH); return entity_get_form($entity); } @@ -130,7 +191,7 @@ function entity_test_edit(EntityTest $entity) { * @param bool $reset * A boolean indicating that the internal cache should be reset. * - * @return Drupal\entity_test\Plugin\Core\Entity\EntityTest + * @return \Drupal\entity_test\Plugin\Core\Entity\EntityTest * The loaded entity object, or FALSE if the entity cannot be loaded. */ function entity_test_load($id, $reset = FALSE) { @@ -138,34 +199,46 @@ function entity_test_load($id, $reset = FALSE) { } /** - * Loads multiple test entities based on certain conditions. + * Loads a test entity. * - * @param array $ids - * (optional) An array of entity IDs. If omitted, all entities are loaded. + * @param int $id + * A test entity ID. * @param bool $reset * A boolean indicating that the internal cache should be reset. * - * @return array - * An array of test entity objects, indexed by ID. + * @return \Drupal\entity_test\Plugin\Core\Entity\EntityTestRev + * The loaded entity object, or FALSE if the entity cannot be loaded. */ -function entity_test_load_multiple(array $ids = NULL, $reset = FALSE) { - return entity_load_multiple('entity_test', $ids, $reset); +function entity_test_rev_load($id, $reset = FALSE) { + return entity_load('entity_test_rev', $id, $reset); } /** - * Deletes multiple test entities. + * Loads a test entity. + * + * @param int $id + * A test entity ID. + * @param bool $reset + * A boolean indicating that the internal cache should be reset. * - * @param $ids - * An array of test entity IDs. + * @return \Drupal\entity_test\Plugin\Core\Entity\EntityTestMul + * The loaded entity object, or FALSE if the entity cannot be loaded. */ -function entity_test_delete_multiple(array $ids) { - entity_delete_multiple('entity_test', $ids); +function entity_test_mul_load($id, $reset = FALSE) { + return entity_load('entity_test_mul', $id, $reset); } /** - * Implements hook_form_BASE_FORM_ID_alter(). + * Loads a test entity. + * + * @param int $id + * A test entity ID. + * @param bool $reset + * A boolean indicating that the internal cache should be reset. + * + * @return \Drupal\entity_test\Plugin\Core\Entity\EntityTestMulRev + * The loaded entity object, or FALSE if the entity cannot be loaded. */ -function entity_test_form_node_form_alter(&$form, &$form_state, $form_id) { - $langcode = $form_state['controller']->getFormLangcode($form_state); - variable_set('entity_form_langcode', $langcode); +function entity_test_mulrev_load($id, $reset = FALSE) { + return entity_load('entity_test_mulrev', $id, $reset); } diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestFormController.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestFormController.php index a65f06f..e1892a0 100644 --- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestFormController.php +++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestFormController.php @@ -61,11 +61,16 @@ public function save(array $form, array &$form_state) { $is_new = $entity->isNew(); $entity->save(); - $message = $is_new ? t('entity_test @id has been created.', array('@id' => $entity->id())) : t('entity_test @id has been updated.', array('@id' => $entity->id())); + if ($is_new) { + $message = t('%entity_type @id has been created.', array('@id' => $entity->id(), '%entity_type' => $entity->entityType())); + } + else { + $message = t('%entity_type @id has been updated.', array('@id' => $entity->id(), '%entity_type' => $entity->entityType())); + } drupal_set_message($message); if ($entity->id()) { - $form_state['redirect'] = 'entity-test/manage/' . $entity->id() . '/edit'; + $form_state['redirect'] = $entity->entityType() . '/manage/' . $entity->id() . '/edit'; } else { // Error on save. @@ -80,7 +85,7 @@ public function save(array $form, array &$form_state) { public function delete(array $form, array &$form_state) { $entity = $this->getEntity($form_state); $entity->delete(); - drupal_set_message(t('entity_test @id has been deleted.', array('@id' => $entity->id()))); + drupal_set_message(t('%entity_type @id has been deleted.', array('@id' => $entity->id(), '%entity_type' => $entity->entityType()))); $form_state['redirect'] = ''; } } diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestMulRevStorageController.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestMulRevStorageController.php new file mode 100644 index 0000000..f940ed0 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestMulRevStorageController.php @@ -0,0 +1,39 @@ + t('ID'), + 'description' => t('The version id of the test entity.'), + 'type' => 'integer_field', + 'read-only' => TRUE, + ); + $fields['default_langcode'] = array( + 'label' => t('Default language'), + 'description' => t('Flag to inditcate whether this is the default language.'), + 'type' => 'boolean_field', + ); + return $fields; + } +} diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestMulStorageController.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestMulStorageController.php new file mode 100644 index 0000000..28a90ee --- /dev/null +++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestMulStorageController.php @@ -0,0 +1,33 @@ + t('Default language'), + 'description' => t('Flag to inditcate whether this is the default language.'), + 'type' => 'boolean_field', + ); + return $fields; + } +} diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestRevStorageController.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestRevStorageController.php new file mode 100644 index 0000000..0fec01e --- /dev/null +++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestRevStorageController.php @@ -0,0 +1,33 @@ + t('ID'), + 'description' => t('The version id of the test entity.'), + 'type' => 'integer_field', + 'read-only' => TRUE, + ); + return $fields; + } +} diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestStorageController.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestStorageController.php index d24ade8..0908700 100644 --- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestStorageController.php +++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/EntityTestStorageController.php @@ -7,9 +7,6 @@ namespace Drupal\entity_test; -use PDO; -use Drupal\Core\Entity\Query\QueryInterface; -use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\DatabaseStorageControllerNG; /** @@ -21,123 +18,6 @@ class EntityTestStorageController extends DatabaseStorageControllerNG { /** - * Overrides Drupal\Core\Entity\DatabaseStorageController::buildPropertyQuery(). - */ - protected function buildPropertyQuery(QueryInterface $entity_query, array $values) { - // @todo We should not be using a condition to specify whether conditions - // apply to the default language or not. We need to move this to a - // separate parameter during the following API refactoring. - // Default to the original entity language if not explicitly specified - // otherwise. - if (!array_key_exists('default_langcode', $values)) { - $values['default_langcode'] = 1; - } - // If the 'default_langcode' flag is esplicitly not set, we do not care - // whether the queried values are in the original entity language or not. - elseif ($values['default_langcode'] === NULL) { - unset($values['default_langcode']); - } - - parent::buildPropertyQuery($entity_query, $values); - } - - /** - * Maps from storage records to entity objects. - * - * @return array - * An array of entity objects implementing the EntityInterface. - */ - protected function mapFromStorageRecords(array $records, $load_revision = FALSE) { - $property_values = $this->getPropertyValues($records, $load_revision); - - foreach ($records as $id => $record) { - $values = isset($property_values[$id]) ? $property_values[$id] : array(); - - foreach ($record as $name => $value) { - $values[$name][LANGUAGE_DEFAULT][0]['value'] = $value; - } - $entity = new $this->entityClass($values, $this->entityType); - $records[$id] = $entity; - } - return $records; - } - - /** - * Attaches property data in all languages for translatable properties. - */ - protected function getPropertyValues($records, $load_revision = FALSE) { - $query = db_select('entity_test_property_data', 'data', array('fetch' => PDO::FETCH_ASSOC)) - ->fields('data') - ->condition('id', array_keys($records)) - ->orderBy('data.id'); - if ($load_revision) { - // Get revision id's. - $revision_ids = array(); - foreach ($records as $record) { - $revision_ids[] = $record->revision_id; - } - $query->condition('revision_id', $revision_ids); - } - $data = $query->execute(); - $property_values = array(); - - foreach ($data as $values) { - $id = $values['id']; - // Field values in default language are stored with - // LANGUAGE_DEFAULT as key. - $langcode = empty($values['default_langcode']) ? $values['langcode'] : LANGUAGE_DEFAULT; - - $property_values[$id]['name'][$langcode][0]['value'] = $values['name']; - $property_values[$id]['user_id'][$langcode][0]['value'] = $values['user_id']; - } - return $property_values; - } - - /** - * Overrides Drupal\Core\Entity\DatabaseStorageController::postSave(). - * - * Stores values of translatable properties. - */ - protected function postSave(EntityInterface $entity, $update) { - $default_langcode = $entity->language()->langcode; - - // Delete and insert to handle removed values. - db_delete('entity_test_property_data') - ->condition('id', $entity->id()) - ->execute(); - - $query = db_insert('entity_test_property_data'); - - foreach ($entity->getTranslationLanguages() as $langcode => $language) { - $translation = $entity->getTranslation($langcode); - - $values = array( - 'id' => $entity->id(), - 'revision_id' => $entity->getRevisionId(), - 'langcode' => $langcode, - 'default_langcode' => intval($default_langcode == $langcode), - 'name' => $translation->name->value, - 'user_id' => $translation->user_id->value, - ); - - $query - ->fields(array_keys($values)) - ->values($values); - } - - $query->execute(); - } - - /** - * Overrides Drupal\Core\Entity\DatabaseStorageController::postDelete(). - */ - protected function postDelete($entities) { - db_delete('entity_test_property_data') - ->condition('id', array_keys($entities)) - ->execute(); - } - - /** * Implements \Drupal\Core\Entity\DataBaseStorageControllerNG::baseFieldDefinitions(). */ public function baseFieldDefinitions() { @@ -147,12 +27,6 @@ public function baseFieldDefinitions() { 'type' => 'integer_field', 'read-only' => TRUE, ); - $fields['revision_id'] = array( - 'label' => t('ID'), - 'description' => t('The version id of the test entity.'), - 'type' => 'integer_field', - 'read-only' => TRUE, - ); $fields['uuid'] = array( 'label' => t('UUID'), 'description' => t('The UUID of the test entity.'), @@ -163,11 +37,6 @@ public function baseFieldDefinitions() { 'description' => t('The language code of the test entity.'), 'type' => 'language_field', ); - $fields['default_langcode'] = array( - 'label' => t('Default language'), - 'description' => t('Flag to inditcate whether this is the default language.'), - 'type' => 'boolean_field', - ); $fields['name'] = array( 'label' => t('Name'), 'description' => t('The name of the test entity.'), diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Plugin/Core/Entity/EntityTest.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Plugin/Core/Entity/EntityTest.php index 22ac2ec..1c8979e 100644 --- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Plugin/Core/Entity/EntityTest.php +++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Plugin/Core/Entity/EntityTest.php @@ -25,13 +25,10 @@ * }, * translation_controller_class = "Drupal\translation_entity\EntityTranslationControllerNG", * base_table = "entity_test", - * data_table = "entity_test_property_data", - * revision_table = "entity_test_property_revision", * fieldable = TRUE, * entity_keys = { * "id" = "id", * "uuid" = "uuid", - * "revision" = "revision_id" * }, * menu_base_path = "entity-test/manage/%entity_test" * ) @@ -53,13 +50,6 @@ class EntityTest extends EntityNG { public $uuid; /** - * The entity revision id. - * - * @var \Drupal\Core\Entity\Field\FieldInterface - */ - public $revision_id; - - /** * The name of the test entity. * * @var \Drupal\Core\Entity\Field\FieldInterface @@ -81,7 +71,6 @@ protected function init() { // We unset all defined properties, so magic getters apply. unset($this->id); unset($this->uuid); - unset($this->revision_id); unset($this->name); unset($this->user_id); } @@ -92,11 +81,4 @@ protected function init() { public function label($langcode = LANGUAGE_DEFAULT) { return $this->getTranslation($langcode)->name->value; } - - /** - * Implements Drupal\Core\Entity\EntityInterface::getRevisionId(). - */ - public function getRevisionId() { - return $this->get('revision_id')->value; - } } diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Plugin/Core/Entity/EntityTestMul.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Plugin/Core/Entity/EntityTestMul.php new file mode 100644 index 0000000..b5afe21 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Plugin/Core/Entity/EntityTestMul.php @@ -0,0 +1,39 @@ +revision_id); + } + + /** + * Implements Drupal\Core\Entity\EntityInterface::getRevisionId(). + */ + public function getRevisionId() { + return $this->get('revision_id')->value; + } +} diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTestTranslationUITest.php b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTestTranslationUITest.php index f66fcc3..2fbb509 100644 --- a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTestTranslationUITest.php +++ b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTestTranslationUITest.php @@ -31,7 +31,8 @@ public static function getInfo() { * Overrides \Drupal\simpletest\WebTestBase::setUp(). */ function setUp() { - $this->entityType = 'entity_test'; + // Use the entity_test_mul as this has multilingual property support. + $this->entityType = 'entity_test_mul'; parent::setUp(); } diff --git a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationUITest.php b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationUITest.php index 6ad80a3..42be87c 100644 --- a/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationUITest.php +++ b/core/modules/translation_entity/lib/Drupal/translation_entity/Tests/EntityTranslationUITest.php @@ -220,8 +220,10 @@ function testTranslationUI() { $this->drupalPost($path, array(), t('Delete translation')); $this->drupalPost(NULL, array(), t('Delete')); $entity = entity_load($this->entityType, $entity->id(), TRUE); - $translations = $entity->getTranslationLanguages(); - $this->assertTrue(count($translations) == 2 && empty($translations[$enabled_langcode]), 'Translation successfully deleted.'); + if ($this->assertTrue(is_object($entity), 'Entity found')) { + $translations = $entity->getTranslationLanguages(); + $this->assertTrue(count($translations) == 2 && empty($translations[$enabled_langcode]), 'Translation successfully deleted.'); + } } /**