diff --git a/core/modules/image/image.field.inc b/core/modules/image/image.field.inc index 11152ae6ebb3..495ca04f8b26 100644 --- a/core/modules/image/image.field.inc +++ b/core/modules/image/image.field.inc @@ -48,6 +48,7 @@ function image_field_info() { ), 'default_widget' => 'image_image', 'default_formatter' => 'image', + 'field item class' => '\Drupal\image\Type\ImageItem', ), ); } diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php new file mode 100644 index 000000000000..7f863cfdea5f --- /dev/null +++ b/core/modules/image/lib/Drupal/image/Tests/ImageItemTest.php @@ -0,0 +1,116 @@ + 'Image field item API', + 'description' => 'Tests using entity fields of the image field type.', + 'group' => 'Image', + ); + } + + public function setUp() { + parent::setUp(); + + $this->installSchema('file', array('file_managed', 'file_usage')); + + $field = array( + 'field_name' => 'image_test', + 'type' => 'image', + 'cardinality' => FIELD_CARDINALITY_UNLIMITED, + ); + field_create_field($field); + $instance = array( + 'entity_type' => 'entity_test', + 'field_name' => 'image_test', + 'bundle' => 'entity_test', + 'widget' => array( + 'type' => 'image_image', + ), + ); + field_create_instance($instance); + file_unmanaged_copy(DRUPAL_ROOT . '/core/misc/druplicon.png', 'public://example.jpg'); + $this->image = entity_create('file', array( + 'uri' => 'public://example.jpg', + )); + $this->image->save(); + } + + /** + * Tests using entity fields of the image field type. + */ + public function testImageItem() { + // Create a test entity with the image field set. + $entity = entity_create('entity_test', array()); + $entity->image_test->fid = $this->image->id(); + $entity->image_test->alt = $alt = $this->randomName(); + $entity->image_test->title = $title = $this->randomName(); + $entity->name->value = $this->randomName(); + $entity->save(); + + $entity = entity_load('entity_test', $entity->id()); + $this->assertTrue($entity->image_test instanceof FieldInterface, 'Field implements interface.'); + $this->assertTrue($entity->image_test[0] instanceof FieldItemInterface, 'Field item implements interface.'); + $this->assertEqual($entity->image_test->fid, $this->image->id()); + $this->assertEqual($entity->image_test->alt, $alt); + $this->assertEqual($entity->image_test->title, $title); + $info = image_get_info('public://example.jpg'); + $this->assertEqual($entity->image_test->width, $info['width']); + $this->assertEqual($entity->image_test->height, $info['height']); + $this->assertEqual($entity->image_test->entity->id(), $this->image->id()); + $this->assertEqual($entity->image_test->entity->uuid(), $this->image->uuid()); + + // Make sure the computed entity reflects updates to the referenced file. + file_unmanaged_copy(DRUPAL_ROOT . '/core/misc/feed.png', 'public://example-2.jpg'); + $image2 = entity_create('file', array( + 'uri' => 'public://example-2.jpg', + )); + $image2->save(); + + $entity->image_test->fid = $image2->id(); + $entity->image_test->alt = $new_alt = $this->randomName(); + // The width and height is only updated when width is not set. + $entity->image_test->width = NULL; + $entity->save(); + $this->assertEqual($entity->image_test->entity->id(), $image2->id()); + $this->assertEqual($entity->image_test->entity->uri, $image2->uri); + $info = image_get_info('public://example-2.jpg'); + $this->assertEqual($entity->image_test->width, $info['width']); + $this->assertEqual($entity->image_test->height, $info['height']); + $this->assertEqual($entity->image_test->alt, $new_alt); + + // Check that the image item can be set to the referenced file directly. + $entity->image_test = $this->image; + $this->assertEqual($entity->image_test->fid, $this->image->id()); + } + +} diff --git a/core/modules/image/lib/Drupal/image/Type/ImageItem.php b/core/modules/image/lib/Drupal/image/Type/ImageItem.php new file mode 100644 index 000000000000..72bf09c6afcf --- /dev/null +++ b/core/modules/image/lib/Drupal/image/Type/ImageItem.php @@ -0,0 +1,105 @@ + 'integer', + 'label' => t('Referenced file id.'), + ); + static::$propertyDefinitions['alt'] = array( + 'type' => 'boolean', + 'label' => t("Alternative image text, for the image's 'alt' attribute."), + ); + static::$propertyDefinitions['title'] = array( + 'type' => 'string', + 'label' => t("Image title text, for the image's 'title' attribute."), + ); + static::$propertyDefinitions['width'] = array( + 'type' => 'integer', + 'label' => t('The width of the image in pixels.'), + ); + static::$propertyDefinitions['height'] = array( + 'type' => 'integer', + 'label' => t('The height of the image in pixels.'), + ); + static::$propertyDefinitions['entity'] = array( + 'type' => 'entity', + 'constraints' => array( + 'EntityType' => 'file', + ), + 'label' => t('Image'), + 'description' => t('The referenced file'), + // The entity object is computed out of the fid. + 'computed' => TRUE, + 'read-only' => FALSE, + 'settings' => array('id source' => 'fid'), + ); + } + return static::$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); + } + + foreach (array('alt', 'title', 'width', 'height') as $property) { + if (isset($values[$property])) { + $this->properties[$property]->setValue($values[$property]); + unset($values[$property]); + } + } + + // 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['fid'])) { + $this->properties['fid']->setValue($values['fid']); + } + elseif (isset($values['entity'])) { + $this->properties['entity']->setValue($values['entity']); + } + else { + $this->properties['entity']->setValue(NULL); + } + + unset($values['fid'], $values['entity']); + // @todo These properties are sometimes set due to being present in form + // values. Needs to be cleaned up somewhere. + unset($values['display'], $values['description'], $values['upload_button'], $values['remove_button'], $values['upload']); + if ($values) { + throw new \InvalidArgumentException('Property ' . key($values) . ' is unknown.'); + } + } + +} 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 dacd1f5e18a1..d0da0509447d 100644 --- a/core/modules/system/tests/modules/entity_test/entity_test.install +++ b/core/modules/system/tests/modules/entity_test/entity_test.install @@ -229,8 +229,7 @@ function entity_test_schema() { 'description' => 'The name of the test entity.', 'type' => 'varchar', 'length' => 32, - 'not null' => TRUE, - 'default' => '', + 'not null' => FALSE, ), 'user_id' => array( 'type' => 'int',