AcquiaDAMStreamWrapper.inc in Media: Acquia DAM 7
Create an Acquia DAM Stream Wrapper class for the Media/Resource module.
File
includes/AcquiaDAMStreamWrapper.incView source
<?php
/**
* @file
* Create an Acquia DAM Stream Wrapper class for the Media/Resource module.
*/
/**
* Provides a remote stream wrapper for Acquia DAM assets.
*
* Create an instance like this:
* ```php
* $dam = new AcquiaDAMStreamWrapper('acquiadam://[asset_id].[filetype]');
* ```
*/
class AcquiaDAMStreamWrapper extends DrupalRemoteStreamWrapper {
/**
* Fetch the content of the file using drupal_http_request().
*/
protected function getStreamContent() {
if (!isset($this->stream_content)) {
$this->stream_content = NULL;
// Translate our acquiadam:// uri into a remote URL before we make the
// request.
$uri = file_create_url($this->uri);
$request = drupal_http_request($uri);
if (empty($request->error) && !empty($request->data)) {
$this->stream_content = $request->data;
}
elseif (!empty($request->error)) {
watchdog('media_acquiadam', '(@code) Error fetching asset content: @error', [
'@code' => $request->code,
'@error' => $request->error,
], WATCHDOG_NOTICE, l(t('View'), $uri));
}
}
return $this->stream_content;
}
/**
* Support for fstat().
*
* {@inheritDoc}
*/
public function stream_stat() {
$stat = [];
// Skip looking up the size if we already have it stored locally.
// If we don't do this then file listing pages can issue several requests
// and have a delay in loading.
$files = entity_load('file', FALSE, [
'uri' => $this->uri,
]);
$file = !empty($files) ? reset($files) : FALSE;
if (!empty($file->filesize)) {
$stat = [
'size' => $file->filesize,
];
}
else {
// If the asset has an overall large size then we skip trying to get the
// accurate size of the specific URL we're referencing. This comes into
// play when the source image or video might be 15MB but we're trying to
// render a thumbnail.
$asset = $this
->getAssetByUri($this->uri);
// Filesize can be '0.00' which will count as not empty, so we have to
// check the size is greater than 0 as well.
if (!empty($asset['filesize']) && 0 < $asset['filesize']) {
$stat['size'] = $asset['filesize'] * 1024 * 1024;
}
else {
// Translate our acquiadam:// uri into a remote URL before we make the
// request.
$uri = file_create_url($this->uri);
$scheme = file_uri_scheme($uri);
if (empty($scheme)) {
$uri = url($uri, [
'absolute' => TRUE,
]);
}
// We have to use a GET request here instead of HEAD because the
// download links we receive are not valid for a HEAD-type request and
// will return a 403.
$request = drupal_http_request($uri, [
'method' => 'GET',
]);
if (empty($request->error) && isset($request->headers['content-length'])) {
$stat['size'] = $request->headers['content-length'];
}
elseif (!empty($request->error)) {
watchdog('media_acquiadam', '(@code) Error fetching asset size: @error', [
'@code' => $request->code,
'@error' => $request->error,
], WATCHDOG_NOTICE, l(t('View'), $uri));
}
}
}
return !empty($stat) ? $this
->getStat($stat) : FALSE;
}
/**
* Get the mimetype of the file.
*
* Overridden to work with the Acquia DAM uri structure.
*
* {@inheritDoc}
*/
public static function getMimeType($uri, $mapping = NULL) {
if (!isset($mapping)) {
// The default file map, defined in file.mimetypes.inc is quite big.
// We only load it when necessary.
include_once DRUPAL_ROOT . '/includes/file.mimetypes.inc';
$mapping = file_mimetype_mapping();
}
if ($target = file_uri_target($uri)) {
$extension = '';
$file_parts = explode('.', drupal_basename($target));
$extensions = $mapping['extensions'];
$mimetypes = $mapping['mimetypes'];
$parsed_overrides = static::getMimetypeOverrides();
// Remove the first part: a full filename should not match an extension.
array_shift($file_parts);
// Iterate over the file parts, trying to find a match.
// For my.awesome.image.jpeg, we try:
// - jpeg
// - image.jpeg, and
// - awesome.image.jpeg
while ($additional_part = array_pop($file_parts)) {
$extension = strtolower($additional_part . ($extension ? '.' . $extension : ''));
if (!empty($parsed_overrides[$extension])) {
$extension = $parsed_overrides[$extension];
}
if (!empty($mimetypes[$extensions[$extension]])) {
return $mimetypes[$extensions[$extension]];
}
}
}
return 'application/octet-stream';
}
/**
* Get a list of extensions mapped to other filetypes.
*
* @return array
* An array keyed by original extensions and the file types they shuld be
* treated as.
*/
protected static function getMimetypeOverrides() {
$parsed_overrides =& drupal_static(__CLASS__ . ':' . __METHOD__);
if (is_null($parsed_overrides)) {
$parsed_overrides = [];
$extension_overrides = drupal_strtolower(variable_get('media_acquiadam_extension_overrides', 'eps png'));
if (!empty($extension_overrides)) {
// We need to convert a multiline "key value" pairing into a key value
// array for ease of checking in extension/mimetype lists.
$extension_overrides = explode("\n", $extension_overrides);
foreach ($extension_overrides as $pairing) {
if (!empty($pairing)) {
list($source, $target) = explode(' ', $pairing, 2);
$parsed_overrides[trim($source)] = trim($target);
}
}
}
}
return $parsed_overrides;
}
/**
* Return the external Url.
*
* {@inheritDoc}
*/
public function getExternalUrl() {
if ('acquiadam' !== file_uri_scheme($this->uri)) {
return $this->uri;
}
$asset = static::getAssetByUri($this->uri);
if (empty($asset)) {
return FALSE;
}
$preview = $asset
->getPreviewUrl();
if (empty($preview)) {
// All other files (txt, docx, html, etc.).
return url('acquiadam/asset/' . $asset['id'], [
'absolute' => TRUE,
]);
}
return $preview;
}
/**
* Get an asset ID from an Acquia DAM Uri.
*
* @param string $uri
* The URI to parse for an asset ID.
*
* @return int|false
* The asset ID or FALSE on failure.
*/
protected static function getAssetIdFromUri($uri) {
$target = file_uri_target($uri);
list($asset_id) = explode('.', drupal_basename($target), 2);
$asset_id = intval($asset_id);
return empty($asset_id) ? FALSE : $asset_id;
}
/**
* Load an asset by the Uri.
*
* @param string $uri
* The Uri to use to look up an asset.
*
* @return AcquiaDAM_Assets_Asset|false
* The asset or FALSE on failure.
*/
protected static function getAssetByUri($uri) {
$asset_id = static::getAssetIdFromUri($uri);
return static::getAssetById($asset_id);
}
/**
* Get an asset by ID.
*
* This requires the file already exist in Drupal and has valid JSON saved
* to the database. We cannot directly look up assets using the API because
* there is no promise that the user has API access.
*
* @param int $id
* The asset ID.
*
* @return AcquiaDAM_Assets_Asset|false
* The asset or FALSE on failure.
*/
protected static function getAssetById($id) {
module_load_include('inc', 'media_acquiadam', 'includes/media_acquiadam.helpers');
try {
$asset = media_acquiadam_get_asset($id);
} catch (Exception $x) {
watchdog_exception('acquiadam_stream_wrapper', $x);
drupal_set_message(t('@class: Unable to load remote asset: @id.', [
'@class' => __CLASS__,
'@id' => $id,
]), 'warning');
}
return $asset;
}
}
Classes
Name | Description |
---|---|
AcquiaDAMStreamWrapper | Provides a remote stream wrapper for Acquia DAM assets. |