You are here

class AssetFileEntityHelper in Media: Acquia DAM 8

Class AssetFileEntityHelper.

Abstracts out primarily file entity and system file related functionality.

Hierarchy

Expanded class hierarchy of AssetFileEntityHelper

4 files declare their use of AssetFileEntityHelper
AssetFileEntityHelperTest.php in tests/src/Unit/AssetFileEntityHelperTest.php
AssetMediaFactoryTest.php in tests/src/Unit/AssetMediaFactoryTest.php
MediaEntityHelper.php in src/MediaEntityHelper.php
MediaEntityHelperTest.php in tests/src/Unit/MediaEntityHelperTest.php
1 string reference to 'AssetFileEntityHelper'
media_acquiadam.services.yml in ./media_acquiadam.services.yml
media_acquiadam.services.yml
1 service uses AssetFileEntityHelper
media_acquiadam.asset_file.helper in ./media_acquiadam.services.yml
Drupal\media_acquiadam\Service\AssetFileEntityHelper

File

src/Service/AssetFileEntityHelper.php, line 23

Namespace

Drupal\media_acquiadam\Service
View source
class AssetFileEntityHelper implements ContainerInjectionInterface {

  /**
   * Entity Type Manager service.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Entity Field Manager service.
   *
   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
   */
  protected $entityFieldManager;

  /**
   * Drupal config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * Media: Acquia DAM config.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  protected $config;

  /**
   * Drupal filesystem service.
   *
   * @var \Drupal\Core\File\FileSystemInterface
   */
  protected $fileSystem;

  /**
   * Drupal token service.
   *
   * @var \Drupal\Core\Utility\Token
   */
  protected $token;

  /**
   * Media: Acquia DAM asset image helper service.
   *
   * @var \Drupal\media_acquiadam\Service\AssetImageHelper
   */
  protected $assetImageHelper;

  /**
   * Media: Acquia DAM client.
   *
   * @var \Drupal\media_acquiadam\Acquiadam
   */
  protected $acquiaDamClient;

  /**
   * Media: Acquia DAM factory for wrapping media entities.
   *
   * @var \Drupal\media_acquiadam\Service\AssetMediaFactory
   */
  protected $assetMediaFactory;

  /**
   * Media: Acquia DAM logger channel.
   *
   * @var \Drupal\Core\Logger\LoggerChannelInterface
   */
  protected $loggerChannel;

  /**
   * AssetFileEntityHelper constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   Entity Type Manager service.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entityFieldManager
   *   Entity Field Manager service.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
   *   Drupal config factory.
   * @param \Drupal\Core\File\FileSystemInterface $fileSystem
   *   Drupal filesystem service.
   * @param \Drupal\Core\Utility\Token $token
   *   Drupal token service.
   * @param \Drupal\media_acquiadam\Service\AssetImageHelper $assetImageHelper
   *   Media: Acquia DAM asset image helper service.
   * @param \Drupal\media_acquiadam\AcquiadamInterface $acquiaDamClient
   *   Media: Acquia DAM client.
   * @param \Drupal\media_acquiadam\Service\AssetMediaFactory $assetMediaFactory
   *   Media: Acquia DAM Asset Media Factory service.
   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $loggerChannelFactory
   *   The Drupal LoggerChannelFactory service.
   */
  public function __construct(EntityTypeManagerInterface $entityTypeManager, EntityFieldManagerInterface $entityFieldManager, ConfigFactoryInterface $configFactory, FileSystemInterface $fileSystem, Token $token, AssetImageHelper $assetImageHelper, AcquiadamInterface $acquiaDamClient, AssetMediaFactory $assetMediaFactory, LoggerChannelFactoryInterface $loggerChannelFactory) {
    $this->entityTypeManager = $entityTypeManager;
    $this->entityFieldManager = $entityFieldManager;
    $this->configFactory = $configFactory;
    $this->config = $configFactory
      ->get('media_acquiadam.settings');
    $this->fileSystem = $fileSystem;
    $this->token = $token;
    $this->assetImageHelper = $assetImageHelper;
    $this->acquiaDamClient = $acquiaDamClient;
    $this->assetMediaFactory = $assetMediaFactory;
    $this->loggerChannel = $loggerChannelFactory
      ->get('media_acquiadam');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('entity_type.manager'), $container
      ->get('entity_field.manager'), $container
      ->get('config.factory'), $container
      ->get('file_system'), $container
      ->get('token'), $container
      ->get('media_acquiadam.asset_image.helper'), $container
      ->get('media_acquiadam.acquiadam'), $container
      ->get('media_acquiadam.asset_media.factory'), $container
      ->get('logger.factory'));
  }

  /**
   * Get a destination uri from the given entity and field combo.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity to check the field configuration on.
   * @param string $fileField
   *   The name of the file field.
   *
   * @return string
   *   The uri to use. Defaults to public://acquiadam_assets
   */
  public function getDestinationFromEntity(EntityInterface $entity, $fileField) {
    $scheme = $this->configFactory
      ->get('system.file')
      ->get('default_scheme');
    $file_directory = 'acquiadam_assets';

    // Load the field definitions for this bundle.
    $field_definitions = $this->entityFieldManager
      ->getFieldDefinitions($entity
      ->getEntityTypeId(), $entity
      ->bundle());
    if (!empty($field_definitions[$fileField])) {
      $definition = $field_definitions[$fileField]
        ->getItemDefinition();
      $scheme = $definition
        ->getSetting('uri_scheme');
      $file_directory = $definition
        ->getSetting('file_directory');
    }

    // Replace the token for file directory.
    if (!empty($file_directory)) {
      $file_directory = $this->token
        ->replace($file_directory);
    }
    return sprintf('%s://%s', $scheme, $file_directory);
  }

  /**
   * Creates a new file for an asset.
   *
   * @param \cweagans\webdam\Entity\Asset $asset
   *   The asset to save a new file for.
   * @param string $destinationFolder
   *   The path to save the asset into.
   *
   * @return bool|\Drupal\file\FileInterface
   *   The created file or FALSE on failure.
   */
  public function createNewFile(Asset $asset, $destinationFolder) {

    // Ensure we can write to our destination directory.
    if (!$this->fileSystem
      ->prepareDirectory($destinationFolder, FileSystemInterface::CREATE_DIRECTORY)) {
      $this->loggerChannel
        ->warning('Unable to save file for asset ID @asset_id on directory @destination_folder.', [
        '@asset_id' => $asset->id,
        '@destination_folder' => $destinationFolder,
      ]);
      return FALSE;
    }
    $destination_path = sprintf('%s/%s', $destinationFolder, $asset->filename);
    $file_contents = $this
      ->fetchRemoteAssetData($asset, $destinationFolder, $destination_path);
    $existing = $this->assetMediaFactory
      ->getFileEntity($asset->id);
    $file = $existing instanceof FileInterface ? $this
      ->replaceExistingFile($existing, $file_contents, $destination_path) : $this
      ->drupalFileSaveData($file_contents, $destination_path);
    if ($file instanceof FileInterface) {
      return $file;
    }
    $this->loggerChannel
      ->warning('Unable to save file for asset ID @asset_id.', [
      '@asset_id' => $asset->id,
    ]);
    return FALSE;
  }

  /**
   * Fetches binary asset data from a remote source.
   *
   * @param \cweagans\webdam\Entity\Asset $asset
   *   The asset to fetch data for.
   * @param string $destination_folder
   *   The destination folder to save the asset to.
   * @param string $destination_path
   *   An optional variable that will contain the final path in case it was
   *   adjusted.
   *
   * @return false|string
   *   The remote asset contents or FALSE on failure.
   */
  protected function fetchRemoteAssetData(Asset $asset, $destination_folder, &$destination_path = NULL) {

    // If the module was configured to enforce an image size limit then we need
    // to grab the nearest matching pre-created size.
    $mimetype = $this->assetImageHelper
      ->getMimeTypeFromFileType($asset->filetype);
    $size_limit = $this->config
      ->get('size_limit');
    $is_image = 'image' == $mimetype['discrete'];
    $use_tn = !empty($size_limit) && -1 != $size_limit && $is_image;
    if ($use_tn) {
      $largest_tn = $this->assetImageHelper
        ->getThumbnailUrlBySize($asset, $size_limit);
      if (empty($largest_tn)) {
        $this->loggerChannel
          ->warning('Unable to save file for asset ID @asset_id. Largest thumbnail not found.', [
          '@asset_id' => $asset->id,
        ]);
        return FALSE;
      }
      $file_contents = $this
        ->phpFileGetContents($largest_tn);

      // The DAM can return a different filetype from the original asset type,
      // so we need to handle that scenario by updating the target filename.
      $destination_path = $this
        ->getNewDestinationByUri($destination_folder, $largest_tn, $asset->name);
    }
    else {
      $file_contents = $this->acquiaDamClient
        ->downloadAsset($asset->id);
    }
    return $file_contents;
  }

  /**
   * Wrapper for file_get_contents().
   *
   * This method exists so the functionality can be overridden in unit tests.
   *
   * @param string $uri
   *   The URI of the file to get the contents of.
   *
   * @return false|string
   *   The file data or FALSE on failure.
   */
  protected function phpFileGetContents($uri) {
    return file_get_contents($uri);
  }

  /**
   * Gets a new filename for an asset based on the URL returned by the DAM.
   *
   * @param string $destination
   *   The destination folder the asset is being saved to.
   * @param string $uri
   *   The URI that was returned by the DAM API for the asset.
   * @param string $original_name
   *   The original asset filename.
   *
   * @return string
   *   The updated destination path with the new filename.
   */
  protected function getNewDestinationByUri($destination, $uri, $original_name) {
    $path = parse_url($uri, PHP_URL_PATH);
    $path = basename($path);
    $ext = pathinfo($path, PATHINFO_EXTENSION);
    $base_file_name = pathinfo($original_name, PATHINFO_FILENAME);
    return sprintf('%s/%s.%s', $destination, $base_file_name, $ext);
  }

  /**
   * Replaces the binary contents of the given file entity.
   *
   * @param \Drupal\file\FileInterface $file
   *   The file entity to replace the binary contents of.
   * @param mixed $data
   *   The contents to save.
   * @param string $destination
   *   The destination uri to save to.
   *
   * @return \Drupal\file\FileInterface
   *   The file entity that was updated.
   */
  protected function replaceExistingFile(FileInterface $file, $data, $destination) {
    $uri = $this->fileSystem
      ->saveData($data, $destination, FileSystemInterface::EXISTS_REPLACE);
    $file
      ->setFileUri($uri);
    $file
      ->setFilename($this->fileSystem
      ->basename($destination));
    $file
      ->save();
    return $file;
  }

  /**
   * Saves a file to the specified destination and creates a database entry.
   *
   * This method exists so the functionality can be overridden in unit tests.
   *
   * @param string $data
   *   A string containing the contents of the file.
   * @param string|null $destination
   *   (optional) A string containing the destination URI. This must be a stream
   *   wrapper URI. If no value or NULL is provided, a randomized name will be
   *   generated and the file will be saved using Drupal's default files scheme,
   *   usually "public://".
   *
   * @return \Drupal\file\FileInterface|false
   *   A file entity, or FALSE on error.
   */
  protected function drupalFileSaveData($data, $destination = NULL) {
    return file_save_data($data, $destination, FileSystemInterface::EXISTS_REPLACE);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
AssetFileEntityHelper::$acquiaDamClient protected property Media: Acquia DAM client.
AssetFileEntityHelper::$assetImageHelper protected property Media: Acquia DAM asset image helper service.
AssetFileEntityHelper::$assetMediaFactory protected property Media: Acquia DAM factory for wrapping media entities.
AssetFileEntityHelper::$config protected property Media: Acquia DAM config.
AssetFileEntityHelper::$configFactory protected property Drupal config factory.
AssetFileEntityHelper::$entityFieldManager protected property Entity Field Manager service.
AssetFileEntityHelper::$entityTypeManager protected property Entity Type Manager service.
AssetFileEntityHelper::$fileSystem protected property Drupal filesystem service.
AssetFileEntityHelper::$loggerChannel protected property Media: Acquia DAM logger channel.
AssetFileEntityHelper::$token protected property Drupal token service.
AssetFileEntityHelper::create public static function Instantiates a new instance of this class. Overrides ContainerInjectionInterface::create
AssetFileEntityHelper::createNewFile public function Creates a new file for an asset.
AssetFileEntityHelper::drupalFileSaveData protected function Saves a file to the specified destination and creates a database entry.
AssetFileEntityHelper::fetchRemoteAssetData protected function Fetches binary asset data from a remote source.
AssetFileEntityHelper::getDestinationFromEntity public function Get a destination uri from the given entity and field combo.
AssetFileEntityHelper::getNewDestinationByUri protected function Gets a new filename for an asset based on the URL returned by the DAM.
AssetFileEntityHelper::phpFileGetContents protected function Wrapper for file_get_contents().
AssetFileEntityHelper::replaceExistingFile protected function Replaces the binary contents of the given file entity.
AssetFileEntityHelper::__construct public function AssetFileEntityHelper constructor.