Commit 76db64a8 authored by git's avatar git Committed by Berdir

Issue #2611866 by Bambell: Add image style tokens for image fields

parent 0bf90c63
......@@ -3,6 +3,9 @@
namespace Drupal\token\Tests;
use Drupal\node\Entity\NodeType;
use Drupal\node\Entity\Node;
use Drupal\file\Entity\File;
use Drupal\image\Entity\ImageStyle;
/**
* Tests field ui.
......@@ -60,6 +63,28 @@ class TokenFieldUiTest extends TokenTestBase {
'entity_type' => 'node',
'bundle' => 'article',
))->save();
entity_create('field_storage_config', array(
'field_name' => 'field_image_2',
'entity_type' => 'node',
'type' => 'image',
))->save();
entity_create('field_config', array(
'field_name' => 'field_image_2',
'label' => 'Image 2',
'entity_type' => 'node',
'bundle' => 'article',
))->save();
entity_create('field_storage_config', array(
'field_name' => 'multivalued_field_image',
'entity_type' => 'node',
'type' => 'image',
))->save();
entity_create('field_config', array(
'field_name' => 'multivalued_field_image',
'label' => 'Multivalued field image',
'entity_type' => 'node',
'bundle' => 'article',
))->save();
entity_get_form_display('node', 'article', 'default')
->setComponent('field_body', [
......@@ -94,4 +119,162 @@ class TokenFieldUiTest extends TokenTestBase {
$this->drupalGet('node/add/article');
$this->assertText('The site is called Drupal.');
}
/**
* Test that tokens are correctly provided and replaced for the image fields.
*/
public function testImageFieldTokens() {
// Generate 2 different test images.
file_unmanaged_copy(\Drupal::root() . '/core/misc/druplicon.png', 'public://example1.png');
file_unmanaged_copy(\Drupal::root() . '/core/misc/loading.gif', 'public://example2.gif');
// Resize the test images so that they will be scaled down during token
// replacement.
$image1 = \Drupal::service('image.factory')->get('public://example1.png');
$image1->resize(500, 500);
$image1->save();
$image2 = \Drupal::service('image.factory')->get('public://example2.gif');
$image2->resize(500, 500);
$image2->save();
/** @var \Drupal\file\Entity\File $image1 */
$image1 = File::create(['uri' => 'public://example1.png']);
$image1->save();
/** @var \Drupal\file\Entity\File $image2 */
$image2 = File::create(['uri' => 'public://example2.gif']);
$image2->save();
$node = Node::create([
'title' => 'Test node title',
'type' => 'article',
'field_image' => [
[
'target_id' => $image1->id(),
],
],
'field_image_2' => [
[
'target_id' => $image2->id(),
],
],
'multivalued_field_image' => [
['target_id' => $image1->id()],
['target_id' => $image2->id()],
],
]);
$node->save();
// Obtain the file size and dimension of the images that will be scaled
// down during token replacement by applying the styles here.
$style_thumbnail = ImageStyle::load('thumbnail');
$style_thumbnail->createDerivative('public://example1.png', 'public://styles/thumbnail/public/example1-test.png');
$style_thumbnail->createDerivative('public://example2.gif', 'public://styles/thumbnail/public/example2-test.gif');
$image_1_thumbnail = \Drupal::service('image.factory')->get('public://styles/thumbnail/public/example1-test.png');
$image_2_thumbnail = \Drupal::service('image.factory')->get('public://styles/thumbnail/public/example2-test.gif');
$style_medium = ImageStyle::load('medium');
$style_medium->createDerivative('public://example1.png', 'public://styles/medium/public/example1-test.png');
$style_medium->createDerivative('public://example2.gif', 'public://styles/medium/public/example2-test.gif');
$image_1_medium = \Drupal::service('image.factory')->get('public://styles/medium/public/example1-test.png');
$image_2_medium = \Drupal::service('image.factory')->get('public://styles/medium/public/example2-test.gif');
$style_large = ImageStyle::load('large');
$style_large->createDerivative('public://example1.png', 'public://styles/large/public/example1-test.png');
$style_large->createDerivative('public://example2.gif', 'public://styles/large/public/example2-test.gif');
$image_1_large = \Drupal::service('image.factory')->get('public://styles/large/public/example1-test.png');
$image_2_large = \Drupal::service('image.factory')->get('public://styles/large/public/example2-test.gif');
// Delete the image derivatives, to make sure they are re-created.
unlink('public://styles/thumbnail/public/example1-test.png');
unlink('public://styles/medium/public/example1-test.png');
unlink('public://styles/large/public/example1-test.png');
unlink('public://styles/thumbnail/public/example2-test.gif');
unlink('public://styles/medium/public/example2-test.gif');
unlink('public://styles/large/public/example2-test.gif');
$tokens = [
// field_image
'field_image:thumbnail:mimetype' => 'image/png',
'field_image:medium:mimetype' => 'image/png',
'field_image:large:mimetype' => 'image/png',
'field_image:thumbnail:filesize' => $image_1_thumbnail->getFileSize(),
'field_image:medium:filesize' => $image_1_medium->getFileSize(),
'field_image:large:filesize' => $image_1_large->getFileSize(),
'field_image:thumbnail:height' => '100',
'field_image:medium:height' => '220',
'field_image:large:height' => '480',
'field_image:thumbnail:width' => '100',
'field_image:medium:width' => '220',
'field_image:large:width' => '480',
'field_image:thumbnail:uri' => 'public://styles/thumbnail/public/example1.png',
'field_image:medium:uri' => 'public://styles/medium/public/example1.png',
'field_image:large:uri' => 'public://styles/large/public/example1.png',
'field_image:thumbnail:url' => $style_thumbnail->buildUrl('public://example1.png'),
'field_image:medium:url' => $style_medium->buildUrl('public://example1.png'),
'field_image:large:url' => $style_large->buildUrl('public://example1.png'),
'field_image:thumbnail' => $style_thumbnail->buildUrl('public://example1.png'),
'field_image:medium' => $style_medium->buildUrl('public://example1.png'),
'field_image:large' => $style_large->buildUrl('public://example1.png'),
// field_image_2
'field_image_2:thumbnail:mimetype' => 'image/gif',
'field_image_2:medium:mimetype' => 'image/gif',
'field_image_2:large:mimetype' => 'image/gif',
'field_image_2:thumbnail:filesize' => $image_2_thumbnail->getFileSize(),
'field_image_2:medium:filesize' => $image_2_medium->getFileSize(),
'field_image_2:large:filesize' => $image_2_large->getFileSize(),
'field_image_2:thumbnail:height' => '100',
'field_image_2:medium:height' => '220',
'field_image_2:large:height' => '480',
'field_image_2:thumbnail:width' => '100',
'field_image_2:medium:width' => '220',
'field_image_2:large:width' => '480',
'field_image_2:thumbnail:uri' => 'public://styles/thumbnail/public/example2.gif',
'field_image_2:medium:uri' => 'public://styles/medium/public/example2.gif',
'field_image_2:large:uri' => 'public://styles/large/public/example2.gif',
'field_image_2:thumbnail:url' => $style_thumbnail->buildUrl('public://example2.gif'),
'field_image_2:medium:url' => $style_medium->buildUrl('public://example2.gif'),
'field_image_2:large:url' => $style_large->buildUrl('public://example2.gif'),
'field_image_2:thumbnail' => $style_thumbnail->buildUrl('public://example2.gif'),
'field_image_2:medium' => $style_medium->buildUrl('public://example2.gif'),
'field_image_2:large' => $style_large->buildUrl('public://example2.gif'),
// multivalued_field_image:0, test for thumbnail image style only.
'multivalued_field_image:0:thumbnail:mimetype' => 'image/png',
'multivalued_field_image:0:thumbnail:filesize' => $image_1_thumbnail->getFileSize(),
'multivalued_field_image:0:thumbnail:height' => '100',
'multivalued_field_image:0:thumbnail:width' => '100',
'multivalued_field_image:0:thumbnail:uri' => 'public://styles/thumbnail/public/example1.png',
'multivalued_field_image:0:thumbnail:url' => $style_thumbnail->buildUrl('public://example1.png'),
'multivalued_field_image:0:thumbnail' => $style_thumbnail->buildUrl('public://example1.png'),
// multivalued_field_image:1, test for medium image style only.
'multivalued_field_image:1:medium:mimetype' => 'image/gif',
'multivalued_field_image:1:medium:filesize' => $image_2_medium->getFileSize(),
'multivalued_field_image:1:medium:height' => '220',
'multivalued_field_image:1:medium:width' => '220',
'multivalued_field_image:1:medium:uri' => 'public://styles/medium/public/example2.gif',
'multivalued_field_image:1:medium:url' => $style_medium->buildUrl('public://example2.gif'),
'multivalued_field_image:1:medium' => $style_medium->buildUrl('public://example2.gif'),
];
$this->assertTokens('node', ['node' => $node], $tokens);
/** @var \Drupal\token\Token $token_service */
$token_service = \Drupal::service('token');
// Test one of the image style's token info for cardinality 1 image field.
$token_info = $token_service->getTokenInfo('node-field_image', 'thumbnail');
$this->assertEqual('Thumbnail (100×100)', $token_info['name']);
$this->assertEqual('Represents the image in the given image style.', $token_info['description']);
// Test one of the image style's token info for a multivalued image field.
$token_info = $token_service->getTokenInfo('node-multivalued_field_image', 'medium');
$this->assertEqual('Medium (220×220)', $token_info['name']);
$this->assertEqual('Represents the image in the given image style.', $token_info['description']);
// Test few of the image styles' properties token info.
$token_info = $token_service->getTokenInfo('image_with_image_style', 'mimetype');
$this->assertEqual('MIME type', $token_info['name']);
$this->assertEqual('The MIME type (image/png, image/bmp, etc.) of the image.', $token_info['description']);
$token_info = $token_service->getTokenInfo('image_with_image_style', 'filesize');
$this->assertEqual('File size', $token_info['name']);
$this->assertEqual('The file size of the image.', $token_info['description']);
}
}
......@@ -22,6 +22,7 @@ use Symfony\Cmf\Component\Routing\RouteObjectInterface;
use Drupal\Core\TypedData\PrimitiveInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Entity\ContentEntityTypeInterface;
use Drupal\image\Entity\ImageStyle;
/**
* Implements hook_token_info_alter().
......@@ -382,6 +383,42 @@ function token_token_info() {
'dynamic' => TRUE,
);
// Define image_with_image_style token type.
if (\Drupal::moduleHandler()->moduleExists('image')) {
$info['types']['image_with_image_style'] = [
'name' => t('Image with image style'),
'needs-data' => 'image_with_image_style',
'module' => 'token',
'nested' => TRUE,
];
// Provide tokens for the ImageStyle attributes.
$info['tokens']['image_with_image_style']['mimetype'] = [
'name' => t('MIME type'),
'description' => t('The MIME type (image/png, image/bmp, etc.) of the image.'),
];
$info['tokens']['image_with_image_style']['filesize'] = [
'name' => t('File size'),
'description' => t('The file size of the image.'),
];
$info['tokens']['image_with_image_style']['height'] = [
'name' => t('Height'),
'description' => t('The height the image, in pixels.'),
];
$info['tokens']['image_with_image_style']['width'] = [
'name' => t('Width'),
'description' => t('The width of the image, in pixels.'),
];
$info['tokens']['image_with_image_style']['uri'] = [
'name' => t('URI'),
'description' => t('The URI to the image.'),
];
$info['tokens']['image_with_image_style']['url'] = [
'name' => t('URL'),
'description' => t('The URL to the image.'),
];
}
return $info;
}
......@@ -1286,6 +1323,17 @@ function field_token_info_alter(&$info) {
];
}
}
// Provide image_with_image_style tokens for image fields.
if ($field->getType() == 'image') {
$image_styles = image_style_options(FALSE);
foreach ($image_styles as $style => $description) {
$info['tokens'][$field_token_name][$style] = [
'name' => $description,
'description' => t('Represents the image in the given image style.'),
'type' => 'image_with_image_style',
];
}
}
}
}
}
......@@ -1462,6 +1510,51 @@ function field_tokens($type, $tokens, array $data = array(), array $options = ar
$replacements[$original] = $entity->label();
}
}
elseif (($field_item->getFieldDefinition()->getType() == 'image') && ($style = ImageStyle::load($property_name))) {
// Handle [node:field_name:image_style:property] tokens and multivalued
// [node:field_name:delta:image_style:property] tokens. If the token is
// of the form [node:field_name:image_style], provide the URL as a
// replacement.
$property_name = isset($parts[1]) ? $parts[1] : 'url';
$entity = $field_item->entity;
$original_uri = $entity->getFileUri();
// Only generate the image derivative if needed.
if ($property_name === 'width' || $property_name === 'height') {
$dimensions = [
'width' => $field_item->width,
'height' => $field_item->height,
];
$style->transformDimensions($dimensions, $original_uri);
$replacements[$original] = $dimensions[$property_name];
}
elseif ($property_name === 'uri') {
$replacements[$original] = $style->buildUri($original_uri);
}
elseif ($property_name === 'url') {
$replacements[$original] = $style->buildUrl($original_uri);
}
else {
// Generate the image derivative, if it doesn't already exist.
$derivative_uri = $style->buildUri($original_uri);
$derivative_exists = TRUE;
if (!file_exists($derivative_uri)) {
$derivative_exists = $style->createDerivative($original_uri, $derivative_uri);
}
if ($derivative_exists) {
$image = \Drupal::service('image.factory')->get($derivative_uri);
// Provide the replacement.
switch ($property_name) {
case 'mimetype':
$replacements[$original] = $image->getMimeType();
break;
case 'filesize' :
$replacements[$original] = $image->getFileSize();
break;
}
}
}
}
else {
$replacements[$original] = $field_item->$property_name;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment