diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f40f858b2bb31a92c57f93218d005d6fe11bbf8d --- /dev/null +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TaxonomyTermReferenceItemTest.php @@ -0,0 +1,114 @@ +<?php + +/** + * @file + * Contains \Drupal\taxonomy\Tests\TaxonomyTermReferenceItemTest. + */ + +namespace Drupal\taxonomy\Tests; + +use Drupal\simpletest\WebTestBase; +use Drupal\taxonomy\Type\TaxonomyTermReferenceItem; +use Drupal\Core\Entity\Field\FieldItemInterface; +use Drupal\Core\Entity\Field\FieldInterface; + +/** + * Tests the new entity API for the taxonomy term reference field type. + */ +class TaxonomyTermReferenceItemTest extends WebTestBase { + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = array('field', 'field_sql_storage', 'taxonomy', 'entity_test', 'options'); + + public static function getInfo() { + return array( + 'name' => 'Taxonomy reference API', + 'description' => 'Tests using entity fields of the taxonomy term reference field type.', + 'group' => 'Taxonomy', + ); + } + + public function setUp() { + parent::setUp(); + $vocabulary = entity_create('taxonomy_vocabulary', array( + 'name' => $this->randomName(), + 'machine_name' => drupal_strtolower($this->randomName()), + 'langcode' => LANGUAGE_NOT_SPECIFIED, + )); + $vocabulary->save(); + $field = array( + 'field_name' => 'field_test_taxonomy', + 'type' => 'taxonomy_term_reference', + 'cardinality' => FIELD_CARDINALITY_UNLIMITED, + 'settings' => array( + 'allowed_values' => array( + array( + 'vocabulary' => $vocabulary->machine_name, + 'parent' => 0, + ), + ), + ), + ); + field_create_field($field); + $instance = array( + 'entity_type' => 'entity_test', + 'field_name' => 'field_test_taxonomy', + 'bundle' => 'entity_test', + 'widget' => array( + 'type' => 'options_select', + ), + ); + field_create_instance($instance); + $this->term = entity_create('taxonomy_term', array( + 'name' => $this->randomName(), + 'vid' => $vocabulary->vid, + 'langcode' => LANGUAGE_NOT_SPECIFIED, + )); + $this->term->save(); + } + + /** + * Tests using entity fields of the taxonomy term reference field type. + */ + public function testTaxonomyTermReferenceItem() { + $tid = $this->term->id(); + // Just being able to create the entity like this verifies a lot of code. + $entity = entity_create('entity_test', array()); + $entity->field_test_taxonomy->tid = $this->term->tid; + $entity->name->value = $this->randomName(); + $entity->save(); + + $entity = entity_load('entity_test', $entity->id()); + $this->assertTrue($entity->field_test_taxonomy instanceof FieldInterface, 'Field implements interface.'); + $this->assertTrue($entity->field_test_taxonomy[0] instanceof FieldItemInterface, 'Field item implements interface.'); + $this->assertEqual($entity->field_test_taxonomy->tid, $this->term->tid); + $this->assertEqual($entity->field_test_taxonomy->entity->name, $this->term->name); + $this->assertEqual($entity->field_test_taxonomy->entity->id(), $tid); + $this->assertEqual($entity->field_test_taxonomy->entity->uuid(), $this->term->uuid()); + + // Change the name of the term via the reference. + $new_name = $this->randomName(); + $entity->field_test_taxonomy->entity->name = $new_name; + $entity->field_test_taxonomy->entity->save(); + // Verify it is the correct name. + $term = entity_load('taxonomy_term', $tid); + $this->assertEqual($term->name, $new_name); + + // Make sure the computed term reflects updates to the term id. + $term2 = entity_create('taxonomy_term', array( + 'name' => $this->randomName(), + 'vid' => $this->term->vid, + 'langcode' => LANGUAGE_NOT_SPECIFIED, + )); + $term2->save(); + + $entity->field_test_taxonomy->tid = $term2->tid; + $this->assertEqual($entity->field_test_taxonomy->entity->id(), $term2->tid); + $this->assertEqual($entity->field_test_taxonomy->entity->name, $term2->name); + } + +} diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Type/TaxonomyTermReferenceItem.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Type/TaxonomyTermReferenceItem.php new file mode 100644 index 0000000000000000000000000000000000000000..8eabe7d6db626ecc61711e83d9d3aa371ca7d854 --- /dev/null +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Type/TaxonomyTermReferenceItem.php @@ -0,0 +1,78 @@ +<?php + +/** + * @file + * Contains \Drupal\taxonomy\Type\TaxonomyTermReferenceItem. + */ + +namespace Drupal\taxonomy\Type; + +use Drupal\Core\Entity\Field\FieldItemBase; + +/** + * Defines the 'taxonomy_term_reference' entity field item. + */ +class TaxonomyTermReferenceItem extends FieldItemBase { + + /** + * Property definitions of the contained properties. + * + * @see self::getPropertyDefinitions() + * + * @var array + */ + static $propertyDefinitions; + + /** + * Implements \Drupal\Core\TypedData\ComplexDataInterface::getPropertyDefinitions(). + */ + public function getPropertyDefinitions() { + if (!isset(self::$propertyDefinitions)) { + self::$propertyDefinitions['tid'] = array( + 'type' => 'integer', + 'label' => t('Referenced taxonomy term id.'), + ); + self::$propertyDefinitions['entity'] = array( + 'type' => 'entity', + 'constraints' => array( + 'entity type' => 'taxonomy_term', + ), + 'label' => t('Term'), + 'description' => t('The referenced taxonomy term'), + // The entity object is computed out of the tid. + 'computed' => TRUE, + 'read-only' => FALSE, + 'settings' => array('id source' => 'tid'), + ); + } + return self::$propertyDefinitions; + } + + /** + * Overrides \Drupal\Core\Entity\Field\FieldItemBase::setValue(). + */ + public function setValue($values) { + // Treat the values as property value of the entity field, if no array + // is given. + if (!is_array($values)) { + $values = array('entity' => $values); + } + + // Entity is computed out of the ID, so we only need to update the ID. Only + // set the entity field if no ID is given. + if (isset($values['tid'])) { + $this->properties['tid']->setValue($values['tid']); + } + elseif (isset($values['entity'])) { + $this->properties['entity']->setValue($values['entity']); + } + else { + $this->properties['entity']->setValue(NULL); + } + unset($values['entity'], $values['tid']); + if ($values) { + throw new \InvalidArgumentException('Property ' . key($values) . ' is unknown.'); + } + } + +} diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index d8ea5b79c40fbc7a1a49faff26ab5f6ba362478b..0158e7ee446e9b5a74764df782a9b0b3d37ced91 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -1015,6 +1015,7 @@ function taxonomy_field_info() { 'description' => t('This field stores a reference to a taxonomy term.'), 'default_widget' => 'options_select', 'default_formatter' => 'taxonomy_term_reference_link', + 'field item class' => 'Drupal\taxonomy\Type\TaxonomyTermReferenceItem', 'settings' => array( 'allowed_values' => array( array(