Drupal 8如何获取图片文件名或URI

3

虽然我想找到最佳方法来实现这个目标,但我目前非常渴望找到任何一种实现方式。我尝试在我的主题文件中的预处理视图函数中获取图像文件名或URI值,但是一直遇到障碍。我最接近的方法是使用$node->field_photo->entity;,并在转储时可以看到我想要获取的“filename”或“uri”值,如下面的截图所示。

enter image description here

以下是我迄今为止尝试过的方法:

#1) 我尝试使用$node->field_photo->entity->getFileUri();
问题:返回错误:在null上调用成员函数getFileUri()

#2) 我尝试了以下方法:

$referenceItem = $node->get('field_photo')->referencedEntities();
$referenceItem[0]->values['filename']

问题:返回 null #3) 我尝试了以下方法:
$referencedEntity = $node
  ->get('field_photo')
  ->first()
  ->get('entity')
  ->getTarget()
  ->getValue();

问题:返回错误:在“->get('entity')”上调用成员函数get()时为空。

#4) 我尝试从"target_id"获取图片,但两个类中都没有找到:

use Drupal\media\Entity\Media;
use Drupal\media_entity\Entity\Media;

问题:找不到任何类。 #5) 我尝试了以下操作:
// $id = some node ID
// $field = field name for entity reference field
$node = Node::load($id);

/** @var \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $referenceItem */
$referenceItem = $node->get($field)->first();

/** @var \Drupal\Core\Entity\Plugin\DataType\EntityReference $entityReference */
$entityReference = $referenceItem->get('entity');

/** @var \Drupal\Core\Entity\Plugin\DataType\EntityAdapter $entityAdapter */
$entityAdapter = $entityReference->getTarget();

/** @var \Drupal\Core\Entity\EntityInterface $referencedEntity */
$referencedEntity = $entityAdapter->getValue();

问题:错误信息为“调用空对象的get()方法,对象名为' ->get('entity')'”

#6) 我也尝试了以下操作:

$node->field_photo->entity->field_media_image->entity->getFileUri();

问题:返回错误调用了一个空对象的getFileUri()函数。

$node->field_photo->entity 返回一个文件对象,但是 $node->field_photo->entity->getFileUri(); 却报告 getFileUri() 在空值上被调用,这真的没有意义。除非在视图中返回的其中一项没有设置图像/文件。在调用 getFuleUri() 函数之前,请尝试检查 $node->field_photo->entity 不为 null。 - undefined
1个回答

0

简短回答

获取Drupal上媒体的图像URI的一种简单而不太规范的方法:

$media = current($node->get('field_media')->referencedEntities());
$uri = $media->field_media_image->entity->getFileUri();

如果你想理解你刚刚复制/粘贴的内容

这取决于你的图像媒体类型的字段名称。

去这个页面检查:/admin/structure/media/manage/image/fields 获取字段名称。

假设字段名称是field_media_image,获取媒体图像文件URI的干净且推荐的方法是:

public function getFileUriFromNode(Node $node) : string {
  // File URI to return (empty string by default).
  $uri = '';
  // Node field media.
  $field_media = $node->get('field_media');
  // Check field not empty.
  if ($field_media->isEmpty() === TRUE) {
    return $uri;
  }
  // Media.
  $media = current($field_media->referencedEntities());
  // File.
  $file = $media->field_media_image->entity;
  // Check file exists.
  if (empty($file) === TRUE) {
    return $uri;
  }
  // File URI.
  $uri = $file->getFileUri();
  return $uri;
}

这涉及编写更多的代码行,但确保您的代码永远不会生成致命错误(错误500),这是一个好的实践。
获取Drupal节点媒体图像样式URI。
再进一步,如果您需要应用图像样式(如调整大小或其他操作),然后获取应用了图像样式的图像URI:
public function getImageStyleUri(Node $node) : string {
  // Image style URI to return (empty string by default).
  $style_uri = '';
  // Same code that above to get media URI first.
  $media_uri = $this->getFileUriFromNode($node);
  // Check media URI.
  if (empty($media_uri) === TRUE) {
    return $style_uri;
  }
  // Load Drupal entity type manager.
  $entityTypeManager = Drupal::entityTypeManager();
  // Load image style by name.
  $style = $entityTypeManager->getStorage('image_style')->load('100x50');
  // Check that image style exists.
   if (empty($style) === TRUE) {
    return $style_uri;
  }
  else {
    $style_uri = $style->buildUrl($uri);
  }
  return $style_uri;
}

避免在PHP 8中发生致命错误

请注意,自PHP版本8.0起,您可以使用空安全运算符:https://php.watch/versions/8.0/null-safe-operator

这个新的运算符在调用一个变量上的方法时,如果该变量不是一个对象,可以使用?->符号而不是->符号来避免致命错误。

像这样:

// Generate a fatal error if one of these is null : media, field_media_image, entity.
$uri = $media->field_media_image->entity->getFileUri();

// Never generate fatal error. Will set $uri with NULL.
$uri = $media?->field_media_image?->entity?->getFileUri();
// The line above does the same that :
if ($media) {
  if ($media->hasField('field_media_image')) {
    if (!$media->get('field_media_image')->isEmpty()) {
      if (method_exists($media->field_media_image->entity, 'getFileUri') {
        return $media->field_media_image->entity->getFileUri();
      }
    }
  }
}

相当实用,因为它节省时间,提高代码可读性,并增加代码执行的可靠性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接