Browse Source

Add URI extractor service

merge-requests/2/head
Chi 4 years ago
parent
commit
8ab073bf37
  1. 1
      README.md
  2. 50
      src/TwigTweakExtension.php
  3. 84
      src/UriExtractor.php
  4. 7
      src/UrlExtractor.php
  5. 8
      tests/src/Functional/TwigTweakTest.php
  6. 91
      tests/src/Kernel/AbstractExtractorTest.php
  7. 61
      tests/src/Kernel/UriExtractorTest.php
  8. 85
      tests/src/Kernel/UrlExtractorTest.php
  9. 1
      tests/twig_tweak_test/templates/twig-tweak-test.html.twig
  10. 4
      twig_tweak.services.yml

1
README.md

@ -116,7 +116,6 @@ drush ev "print_r(array_keys(\Drupal::service('plugin.manager.block')->getDefini
{{ drupal_image('public://ocean.jpg', 'wide', responsive=true) }}
```
### Drupal Token
```twig
{{ drupal_token('site:name') }}

50
src/TwigTweakExtension.php

@ -7,21 +7,15 @@ use Drupal\Component\Utility\Unicode;
use Drupal\Component\Uuid\Uuid;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
use Drupal\Core\Field\FieldItemInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\Core\Link;
use Drupal\Core\Render\Element;
use Drupal\Core\Render\Markup;
use Drupal\Core\Site\Settings;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\Core\Url;
use Drupal\file\Entity\File;
use Drupal\file\FileInterface;
use Drupal\image\Entity\ImageStyle;
use Drupal\media\MediaInterface;
use Drupal\media\Plugin\media\Source\OEmbedInterface;
use Twig\Environment;
use Twig\Extension\AbstractExtension;
use Twig\Markup as TwigMarkup;
@ -581,18 +575,7 @@ class TwigTweakExtension extends AbstractExtension {
* A URI that may be used to access the file.
*/
public static function fileUriFilter($input): ?string {
if ($input instanceof EntityReferenceFieldItemListInterface) {
$referenced_entities = $input->referencedEntities();
if (isset($referenced_entities[0])) {
return self::getUriFromEntity($referenced_entities[0]);
}
}
elseif ($input instanceof EntityReferenceItem) {
return self::getUriFromEntity($input->entity);
}
elseif ($input instanceof EntityInterface) {
return self::getUriFromEntity($input);
}
return \Drupal::service('twig_tweak.uri_extractor')->extractUri($input);
}
/**
@ -600,12 +583,14 @@ class TwigTweakExtension extends AbstractExtension {
*
* @param string|object $input
* Can be either file URI or an object that contains the URI.
* @param bool $relative
* (optional) Whether the URL should be root-relative, defaults to true.
*
* @return string|null
* A URL that may be used to access the file.
*/
public static function fileUrlFilter($input): ?string {
return \Drupal::service('twig_tweak.url_extractor')->extractUrl($input);
public static function fileUrlFilter($input, bool $relative = TRUE): ?string {
return \Drupal::service('twig_tweak.url_extractor')->extractUrl($input, $relative);
}
/**
@ -630,29 +615,4 @@ class TwigTweakExtension extends AbstractExtension {
return $output;
}
/**
* Extracts file URI from content entity.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* Entity object that contains information about the file.
*
* @return string|null
* A URI that may be used to access the file.
*/
private static function getUriFromEntity(EntityInterface $entity): ?string {
if ($entity instanceof MediaInterface) {
$source = $entity->getSource();
$value = $source->getSourceFieldValue($entity);
if ($source instanceof OEmbedInterface) {
return $value;
}
elseif ($file = File::load($value)) {
return $file->getFileUri();
}
}
elseif ($entity instanceof FileInterface) {
return $entity->getFileUri();
}
}
}

84
src/UriExtractor.php

@ -0,0 +1,84 @@
<?php
namespace Drupal\twig_tweak;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\file\FileInterface;
use Drupal\media\MediaInterface;
use Drupal\media\Plugin\media\Source\OEmbedInterface;
/**
* URI extractor service.
*/
class UriExtractor {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Constructs a UrlExtractor object.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->entityTypeManager = $entity_type_manager;
}
/**
* Returns a URI to the file.
*
* @param object|null $input
* An object that contains the URI.
*
* @return string|null
* A URI that may be used to access the file.
*/
public function extractUri(?object $input): ?string {
if ($input instanceof ContentEntityInterface) {
return self::getUriFromEntity($input);
}
elseif ($input instanceof EntityReferenceFieldItemListInterface) {
if ($item = $input->first()) {
return $this->getUriFromEntity($item->entity);
}
}
elseif ($input instanceof EntityReferenceItem) {
return self::getUriFromEntity($input->entity);
}
return NULL;
}
/**
* Extracts file URI from content entity.
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* Entity object that contains information about the file.
*
* @return string|null
* A URI that may be used to access the file.
*/
private function getUriFromEntity(ContentEntityInterface $entity): ?string {
if ($entity instanceof MediaInterface) {
$source = $entity->getSource();
$value = $source->getSourceFieldValue($entity);
if ($source instanceof OEmbedInterface) {
return $value;
}
/** @var \Drupal\file\FileInterface $file */
$file = $this->entityTypeManager->getStorage('file')->load($value);
if ($file) {
return $file->getFileUri();
}
}
elseif ($entity instanceof FileInterface) {
return $entity->getFileUri();
}
return NULL;
}
}

7
src/UrlExtractor.php

@ -11,7 +11,7 @@ use Drupal\media\MediaInterface;
use Drupal\media\Plugin\media\Source\OEmbedInterface;
/**
* UrlExtractor service.
* URL extractor service.
*/
class UrlExtractor {
@ -35,7 +35,7 @@ class UrlExtractor {
* @param string|object $input
* Can be either file URI or an object that contains the URI.
* @param bool $relative
* (optional) Whether the URL should be root-relative, defaults to TRUE.
* (optional) Whether the URL should be root-relative, defaults to true.
*
* @return string|null
* A URL that may be used to access the file.
@ -65,7 +65,7 @@ class UrlExtractor {
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* Entity object that contains information about the file.
* @param bool $relative
* (optional) Whether the URL should be root-relative, defaults to TRUE.
* (optional) Whether the URL should be root-relative, defaults to true.
*
* @return string|null
* A URL that may be used to access the file.
@ -81,6 +81,7 @@ class UrlExtractor {
return $value;
}
else {
/** @var \Drupal\file\FileInterface $file */
$file = $this->entityTypeManager->getStorage('file')->load($value);
if ($file) {
return $file->createFileUrl($relative);

8
tests/src/Functional/TwigTweakTest.php

@ -359,8 +359,12 @@ final class TwigTweakTest extends BrowserTestBase {
$xpath = '//div[@class = "tt-image-style-from-file-uri-from-media-field" and contains(text(), "styles/thumbnail/public/image-1.png")]';
$this->assertXpath($xpath);
// -- File URL from URI.
$xpath = '//div[@class = "tt-file-url-from-uri" and contains(text(), "/files/image-test.png")]';
// -- File URL from URI (relative).
$xpath = '//div[@class = "tt-file-url-from-uri" and contains(text(), "/files/image-test.png") and not(contains(text(), "http://"))]';
$this->assertXpath($xpath);
// -- File URL from URI (absolute).
$xpath = '//div[@class = "tt-file-url-from-uri-absolute" and contains(text(), "/files/image-test.png") and contains(text(), "http://")]';
$this->assertXpath($xpath);
// -- File URL from image field.

91
tests/src/Kernel/AbstractExtractorTest.php

@ -0,0 +1,91 @@
<?php
namespace Drupal\Tests\twig_tweak\Kernel;
use Drupal\file\Entity\File;
use Drupal\KernelTests\KernelTestBase;
use Drupal\media\Entity\Media;
use Drupal\node\Entity\Node;
use Drupal\Tests\TestFileCreationTrait;
/**
* A base class of URL and URI extractor tests.
*/
abstract class AbstractExtractorTest extends KernelTestBase {
use TestFileCreationTrait;
/**
* A node to test.
*
* @var \Drupal\node\NodeInterface
*/
protected $node;
/**
* {@inheritdoc}
*/
public static $modules = [
'twig_tweak',
'twig_tweak_test',
'system',
'views',
'node',
'block',
'image',
'field',
'text',
'media',
'file',
'user',
'filter',
];
/**
* {@inheritdoc}
*/
public function setUp(): void {
parent::setUp();
$this->installConfig(['node', 'twig_tweak_test']);
$this->installSchema('file', 'file_usage');
$this->installEntitySchema('file');
$this->installEntitySchema('media');
$test_files = $this->getTestFiles('image');
//
$image_file = File::create([
'uri' => $test_files[0]->uri,
'uuid' => 'a2cb2b6f-7bf8-4da4-9de5-316e93487518',
'status' => FILE_STATUS_PERMANENT,
]);
$image_file->save();
$media_file = File::create([
'uri' => $test_files[2]->uri,
'uuid' => '5dd794d0-cb75-4130-9296-838aebc1fe74',
'status' => FILE_STATUS_PERMANENT,
]);
$media_file->save();
$media = Media::create([
'bundle' => 'image',
'name' => 'Image 1',
'field_media_image' => ['target_id' => $media_file->id()],
]);
$media->save();
$node_values = [
'title' => 'Alpha',
'type' => 'page',
'field_image' => [
'target_id' => $image_file->id(),
],
'field_media' => [
'target_id' => $media->id(),
],
];
$this->node = Node::create($node_values);
}
}

61
tests/src/Kernel/UriExtractorTest.php

@ -0,0 +1,61 @@
<?php
namespace Drupal\Tests\twig_tweak\Kernel;
/**
* A test for URI extractor service.
*
* @group twig_tweak
*/
final class UriExtractorTest extends AbstractExtractorTest {
/**
* Test callback.
*/
public function testUrlExtractor(): void {
$extractor = $this->container->get('twig_tweak.uri_extractor');
$url = $extractor->extractUri(NULL);
self::assertNull($url);
$url = $extractor->extractUri($this->node);
self::assertNull($url);
$url = $extractor->extractUri($this->node->get('title'));
self::assertNull($url);
$url = $extractor->extractUri($this->node->get('field_image')[0]);
self::assertSame('public://image-test.png', $url);
$url = $extractor->extractUri($this->node->get('field_image')[1]);
self::assertNull($url);
$url = $extractor->extractUri($this->node->get('field_image'));
self::assertSame('public://image-test.png', $url);
$url = $extractor->extractUri($this->node->get('field_image')->entity);
self::assertSame('public://image-test.png', $url);
$this->node->get('field_image')->removeItem(0);
$url = $extractor->extractUri($this->node->get('field_image'));
self::assertNull($url);
$url = $extractor->extractUri($this->node->get('field_media')[0]);
self::assertSame('public://image-test.gif', $url);
$url = $extractor->extractUri($this->node->get('field_media')[1]);
self::assertNull($url);
$url = $extractor->extractUri($this->node->get('field_media'));
self::assertSame('public://image-test.gif', $url);
$url = $extractor->extractUri($this->node->get('field_media')->entity);
self::assertSame('public://image-test.gif', $url);
$this->node->get('field_media')->removeItem(0);
$url = $extractor->extractUri($this->node->get('field_media'));
self::assertNull($url);
}
}

85
tests/src/Kernel/UrlExtractorTest.php

@ -2,93 +2,12 @@
namespace Drupal\Tests\twig_tweak\Kernel;
use Drupal\file\Entity\File;
use Drupal\KernelTests\KernelTestBase;
use Drupal\media\Entity\Media;
use Drupal\node\Entity\Node;
use Drupal\Tests\TestFileCreationTrait;
/**
* A test for UrlExtractor.
* A test for URL Extractor service.
*
* @group twig_tweak
*/
final class UrlExtractorTest extends KernelTestBase {
use TestFileCreationTrait;
/**
* A node to test.
*
* @var \Drupal\node\NodeInterface
*/
private $node;
/**
* {@inheritdoc}
*/
public static $modules = [
'twig_tweak',
'twig_tweak_test',
'system',
'views',
'node',
'block',
'image',
'field',
'text',
'media',
'file',
'user',
'filter',
];
/**
* {@inheritdoc}
*/
public function setUp(): void {
parent::setUp();
$this->installConfig(['node', 'twig_tweak_test']);
$this->installSchema('file', 'file_usage');
$this->installEntitySchema('file');
$this->installEntitySchema('media');
$test_files = $this->getTestFiles('image');
//
$image_file = File::create([
'uri' => $test_files[0]->uri,
'uuid' => 'a2cb2b6f-7bf8-4da4-9de5-316e93487518',
'status' => FILE_STATUS_PERMANENT,
]);
$image_file->save();
$media_file = File::create([
'uri' => $test_files[2]->uri,
'uuid' => '5dd794d0-cb75-4130-9296-838aebc1fe74',
'status' => FILE_STATUS_PERMANENT,
]);
$media_file->save();
$media = Media::create([
'bundle' => 'image',
'name' => 'Image 1',
'field_media_image' => ['target_id' => $media_file->id()],
]);
$media->save();
$node_values = [
'title' => 'Alpha',
'type' => 'page',
'field_image' => [
'target_id' => $image_file->id(),
],
'field_media' => [
'target_id' => $media->id(),
],
];
$this->node = Node::create($node_values);
}
final class UrlExtractorTest extends AbstractExtractorTest {
/**
* Test callback.

1
tests/twig_tweak_test/templates/twig-tweak-test.html.twig

@ -93,6 +93,7 @@
<div class="tt-image-style-from-file-uri-from-media-field">{{ media_uri|image_style('thumbnail') }}</div>
{% endif %}
<div class="tt-file-url-from-uri">{{ 'public://image-test.png'|file_url }}</div>
<div class="tt-file-url-from-uri-absolute">{{ 'public://image-test.png'|file_url(false) }}</div>
<div class="tt-file-url-from-image-field">{{ node.field_image|file_url }}</div>
<div class="tt-file-url-from-image-field-delta">{{ node.field_image[0]|file_url }}</div>
<div class="tt-file-url-from-media-field">{{ node.field_media|file_url }}</div>

4
twig_tweak.services.yml

@ -35,3 +35,7 @@ services:
twig_tweak.url_extractor:
class: Drupal\twig_tweak\UrlExtractor
arguments: ['@entity_type.manager']
twig_tweak.uri_extractor:
class: Drupal\twig_tweak\UriExtractor
arguments: ['@entity_type.manager']

Loading…
Cancel
Save