You are here

public static function MimeMailFormatHelper::mimeMailFile in Mime Mail 8

Builds a manifest containing metadata about files attached to an email.

Calling this function with either a $url argument or a $content argument will generate metadata for the file described by that argument and will accumulate that metadata internally in a static array. Subsequent calls with one of these arguments will add additional metadata to this internal array.

Calling this function with no arguments will return everything stored in the internal static array by all previous calls (this is the 'manifest'), then will clear the contents of the internal static array.

The manifest is an associative array indexed by the Content-ID, which is a unique identifier calculated internally using a hash of the attachment name and the server's host name. The required (always present) keys of this manifest array are:

  • name: The file name of the attachment.
  • file: The absolute URL of the file or the contents of the file.
  • Content-ID: The unique identifier of the file.
  • Content-Disposition: How the file is attached - either 'inline' or 'attachment'.
  • Content-Type: MIME type of the file.

Parameters

string $url: (optional) The URI or the absolute URL of the file.

string $content: (optional) The actual file content. This is required if $url is not set.

string $name: (optional) The file name.

string $type: (optional) The MIME type of the file.

string $disposition: (optional) The content disposition. One of 'inline' or 'attachment'. Defaults to 'inline'.

Return value

mixed Returned value is one of:

  • The Content-ID, if this function is called with either a $url or a $content argument.
  • An array of accumulated metadata indexed by Content-ID if this function is called with no arguments. The structure of this metadata (the 'manifest') is described above.
  • URL if the $url is not a local file and $content is not set.
2 calls to MimeMailFormatHelper::mimeMailFile()
MimeMailFormatHelper::mimeMailExtractFiles in src/Utility/MimeMailFormatHelper.php
Extracts links to local images from HTML documents.
MimeMailFormatHelper::mimeMailHtmlBody in src/Utility/MimeMailFormatHelper.php
Generates a multipart message body with a plaintext alternative.

File

src/Utility/MimeMailFormatHelper.php, line 343

Class

MimeMailFormatHelper
Utility methods for formatting MIME-encoded email messages.

Namespace

Drupal\mimemail\Utility

Code

public static function mimeMailFile($url = NULL, $content = NULL, $name = '', $type = '', $disposition = 'inline') {

  // A cumulative manifest of metadata about the files that are attached
  // to an email message.
  static $files = [];

  /** @var \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface $mime_type_guesser */
  $mime_type_guesser = \Drupal::service('file.mime_type.guesser');

  /** @var \Drupal\Core\File\FileSystemInterface $file_system */
  $file_system = \Drupal::service('file_system');

  /** @var \Drupal\Core\Config\ImmutableConfig file_config */
  $file_config = \Drupal::config('system.file');

  /** @var \Symfony\Component\HttpFoundation\Request $current_request */
  $current_request = \Drupal::requestStack()
    ->getCurrentRequest();

  /** @var \Drupal\Core\Session\AccountProxyInterface $current_user */
  $current_user = \Drupal::currentUser();

  /** @var \Drupal\Core\Config\ImmutableConfig $mimemail_config */
  $mimemail_config = \Drupal::config('mimemail.settings');
  if ($url) {
    $image = preg_match('!\\.(png|gif|jpg|jpeg)$!i', $url);
    $linkonly = \Drupal::config('mimemail.settings')
      ->get('linkonly');

    // The file exists on the server as-is.
    // Allows for non-web-accessible files.
    if (@is_file($url) && $image && !$linkonly) {
      $file = $url;
    }
    else {
      $url = static::mimeMailUrl($url, TRUE);

      // The $url is absolute, we're done here.
      $scheme = StreamWrapperManager::getScheme($url);
      if ($scheme == 'http' || $scheme == 'https' || preg_match('!mailto:!', $url)) {
        return $url;
      }
      else {
        $file = $file_system
          ->realpath($url) ? $file_system
          ->realpath($url) : file_create_url($url);
      }
    }
  }
  elseif ($content) {
    $file = $content;
  }
  if (isset($file) && (@is_file($file) || $content)) {
    $public_path = $file_config
      ->get('default_scheme') . '://';
    $no_access = !$current_user
      ->hasPermission('send arbitrary files');
    $not_in_public_path = mb_strpos($file_system
      ->realpath($file), $file_system
      ->realpath($public_path)) !== 0;
    if (@is_file($file) && $not_in_public_path && $no_access) {
      return $url;
    }
    if (!$name) {
      $name = @is_file($file) ? basename($file) : 'attachment.dat';
    }
    if (!$type) {

      // @todo $name will ALWAYS be TRUE here because of the above if{}.
      $type = $name ? $mime_type_guesser
        ->guess($name) : $mime_type_guesser
        ->guess($file);
    }

    // Generate a unique ID using the HTTP host requested.
    $id = md5($file) . '@' . $current_request
      ->getHttpHost();

    // Prevent attaching the same file more than once. For example, an image
    // that's part of the theme may be referenced many times in the HTML, but
    // should only be attached once.
    if (!isset($files[$id])) {

      // This is a new file that needs to be attached.
      // Store the metadata in our static $files array indexed by $id.
      $files[$id] = [
        'name' => $name,
        'file' => $file,
        'Content-ID' => $id,
        'Content-Disposition' => $disposition,
        'Content-Type' => $type,
      ];
    }

    // Return the content id for this item.
    return 'cid:' . $id;
  }
  elseif ($url) {
    return $url;
  }
  $ret = $files;
  $files = [];
  $ids = [];
  return $ret;
}