You are here

media_acquiadam.module in Media: Acquia DAM 7

Same filename and directory in other branches
  1. 8 media_acquiadam.module

File

media_acquiadam.module
View source
<?php

/**
 * @file
 * Drupal hook implementations.
 */
require_once __DIR__ . '/includes/media_acquiadam.helpers.inc';
require_once __DIR__ . '/includes/media_acquiadam.cache.inc';

/**
 * Implements hook_menu().
 */
function media_acquiadam_menu() {
  $items = [];
  $items['admin/config/media/acquiadam'] = [
    'title' => 'Media: Acquia DAM settings',
    'description' => 'Configure the API settings for Acquia DAM.',
    'page callback' => 'drupal_get_form',
    'page arguments' => [
      'media_acquiadam_config_settings',
    ],
    'access arguments' => [
      'administer media acquiadam',
    ],
    'file path' => drupal_get_path('module', 'media_acquiadam') . '/includes',
    'file' => 'media_acquiadam.admin.inc',
  ];
  $items['acquiadam/asset/%media_acquiadam_asset'] = [
    'title' => 'Acquia DAM Asset',
    'description' => 'Redirect to an available asset download link.',
    'page callback' => 'media_acquiadam_download_redirect_page',
    'page arguments' => [
      2,
    ],
    'access callback' => 'media_acquiadam_asset_access',
    'access arguments' => [
      'view',
      2,
    ],
    'file path' => drupal_get_path('module', 'media_acquiadam') . '/includes',
    'file' => 'media_acquiadam.pages.inc',
    'type' => MENU_CALLBACK,
  ];
  $directory_path = file_stream_wrapper_get_instance_by_scheme(file_default_scheme())
    ->getDirectoryPath();
  $pos = count(explode('/', $directory_path)) + 1;
  $items[$directory_path . '/styles/%/acquiadam/%/%media_acquiadam_asset'] = [
    'title' => 'Acquia DAM Asset derivative',
    'page callback' => 'media_acquiadam_image_style_deliver',
    'page arguments' => [
      $pos,
      $pos + 3,
    ],
    'load arguments' => [
      $pos + 2,
    ],
    'access callback' => 'media_acquiadam_asset_access',
    'access arguments' => [
      'view',
      $pos + 3,
    ],
    'file path' => drupal_get_path('module', 'media_acquiadam') . '/includes',
    'file' => 'media_acquiadam.image.inc',
    'type' => MENU_CALLBACK,
  ];
  $items['file/%file/dam-refresh'] = [
    'title' => 'Force refresh from Acquia DAM',
    'description' => 'Updates the Acquia DAM asset from the remote DAM source.',
    'page callback' => 'media_acquiadam_dam_refresh_page',
    'page arguments' => [
      1,
    ],
    'access callback' => 'file_entity_access',
    'access arguments' => [
      'refresh',
      1,
    ],
    'file path' => drupal_get_path('module', 'media_acquiadam') . '/includes',
    'file' => 'media_acquiadam.pages.inc',
    'type' => MENU_LOCAL_ACTION,
  ];
  $items['file/%file/dam-view'] = [
    'title' => 'View in Acquia DAM',
    'description' => 'Directs the user to the asset inside Acquia DAM.',
    'page callback' => 'media_acquiadam_dam_view_page',
    'page arguments' => [
      1,
    ],
    'access callback' => 'file_entity_access',
    'access arguments' => [
      'view',
      1,
    ],
    'file path' => drupal_get_path('module', 'media_acquiadam') . '/includes',
    'file' => 'media_acquiadam.pages.inc',
    'type' => MENU_LOCAL_ACTION,
  ];
  $items['user/%user/acquiadam/deauth'] = [
    'title' => 'Clear DAM access token',
    'description' => 'Removes the current users DAM OAuth2 access token.',
    'page callback' => 'media_acquiadam_deauth_page',
    'access arguments' => [
      'view acquiadam assets',
    ],
    'file' => 'includes/media_acquiadam.pages.inc',
    'type' => MENU_LOCAL_ACTION,
  ];
  return $items;
}

/**
 * Implements hook_url_inbound_alter().
 */
function media_acquiadam_url_inbound_alter(&$path, $original_path, $path_language) {

  // Hijack the normal image style path and redirect it to our custom handler
  // path so we can avoid having to guess asset type when delivering images.
  $directory_path = file_stream_wrapper_get_instance_by_scheme(file_default_scheme())
    ->getDirectoryPath();
  $regex = preg_quote($directory_path) . '\\/styles\\/(\\w+?)\\/acquiadam\\/(\\d+)\\.\\w+';
  if (preg_match("|^{$regex}|", $original_path, $matches)) {

    // Folders do not normally trigger image style creation and should be styled
    // with theme('image_style', ...) directly. We can safely hard-code the
    // asset type here.
    $path = vsprintf('%s/styles/%s/acquiadam/asset/%d', [
      $directory_path,
      $matches[1],
      $matches[2],
    ]);
  }
}

/**
 * Implements hook_permission().
 */
function media_acquiadam_permission() {
  $perms = [];
  $perms['administer media acquiadam'] = [
    'title' => t('Administer Media: Acquia DAM'),
    'description' => t('Allows administration of Media: Acquia DAM'),
    'restrict access' => TRUE,
  ];
  $perms['view acquiadam assets'] = [
    'title' => t('View Acquia DAM assets'),
    'description' => t('Allows viewing of Acquia DAM assets'),
  ];
  $perms['view expired acquiadam assets'] = [
    'title' => t('View expired Acquia DAM assets'),
    'description' => t('Allows viewing of Acquia DAM assets that have expired'),
    'restrict access' => TRUE,
  ];
  $perm['refresh acquiadam assets'] = [
    'title' => t('Refresh Acquia DAM asset information'),
    'description' => t('Allows refreshing Acquia DAM asset information if the local cache is out of date'),
  ];
  $perms['view acquiadam links'] = [
    'title' => t('View Acquia DAM links'),
    'description' => t('Allows the user to view links to Acquia DAM.'),
  ];
  return $perms;
}

/**
 * Implements hook_oauth2_clients().
 */
function media_acquiadam_oauth2_clients() {
  global $base_url;
  $client_url = $base_url;
  $server_url = variable_get('media_acquiadam_api_endpoint', 'https://apiv2.webdamdb.com');
  $base_auth = [
    'token_endpoint' => $server_url . '/oauth2/token',
    'client_id' => variable_get('media_acquiadam_client_id'),
    'client_secret' => variable_get('media_acquiadam_client_secret'),
  ];

  // This setup redirects the user to the Acquia DAM OAuth2 endpoint for
  // authentication instead of passing username/password information from Drupal
  // to Acquia DAM.
  $oauth2_clients['acquiadam-server-auth'] = $base_auth + [
    'auth_flow' => 'server-side',
    'authorization_endpoint' => $server_url . '/oauth2/authorize',
    'redirect_uri' => $client_url . '/oauth2/authorized',
  ];

  // This method requires configuration of a username and password so it is
  // inherently less secure than handing authentication off to the user. We only
  // use this for the background user and never regular Drupal users.
  $oauth2_clients['acquiadam-user-auth'] = $base_auth + [
    'auth_flow' => 'user-password',
    'username' => variable_get('media_acquiadam_background_user'),
    'password' => variable_get('media_acquiadam_background_pass'),
  ];

  // Client credentials are not supported but still defined here.
  $oauth2_clients['acquiadam-client-auth'] = $base_auth + [
    'auth_flow' => 'client-credentials',
  ];
  return $oauth2_clients;
}

/**
 * Implements hook_stream_wrappers().
 */
function media_acquiadam_stream_wrappers() {
  return [
    'acquiadam' => [
      'name' => t('Acquia DAM files'),
      'class' => 'AcquiaDAMStreamWrapper',
      'description' => t('Provides read-only paths to Acquia DAM files.'),
      'type' => STREAM_WRAPPERS_REMOTE,
      'remote' => TRUE,
    ],
  ];
}

/**
 * Implements hook_schema_alter().
 */
function media_acquiadam_schema_alter(&$schema) {

  // Add an asset_id property to the file_managed table so we can easily find
  // related cache without having to parse/manipulate strings.
  $file_managed =& $schema['file_managed'];
  $file_managed['fields']['acquiadam_id'] = [
    'description' => st('The Acquia DAM asset identifier.'),
    'type' => 'int',
    'unsigned' => TRUE,
    'not null' => FALSE,
  ];
  $file_managed['indexes']['acquiadam_id'] = [
    'acquiadam_id',
  ];
  $file_managed['indexes']['fid_acquiadam_id'] = [
    'fid',
    'acquiadam_id',
  ];
}

/**
 * Implements hook_cron().
 */
function media_acquiadam_cron() {
  media_acquiadam_flush_outdated_cache();
}

/**
 * Implements hook_help().
 */
function media_acquiadam_help($path, $arg) {
  switch ($path) {
    case 'admin/help#media_acquiadam':
      $output = '<h3>' . t('About Media: Acquia DAM') . '</h3>';
      $output .= '<p>' . t('Media: Acquia DAM provides Acquia DAM integration within the Drupal site. This integration allows Drupal users with Acquia DAM accounts to browse assets they have access to and create Drupal files that reference these assets.') . '</p>';
      $output .= '<p>' . t('Once an asset is referenced within Drupal normal Drupal permission mechanisms will take over.') . '</p>';
      $output .= '<p>' . t('DAM permissions will still apply to the CDN-rendered images.') . '</p>';
      return $output;
  }
}

/**
 * Load an Acquia DAM asset.
 *
 * Used for the menu system.
 *
 * @param int $assetId
 *   The ID of the asset to load.
 * @param string $assetType
 *   The type of asset to load.
 *
 * @return AcquiaDAM_Assets_AbstractAsset|false
 *   The loaded asset or FALSE.
 */
function media_acquiadam_asset_load($assetId, $assetType = 'asset') {
  return media_acquiadam_get_helper($assetType, $assetId);
}

/**
 * Access callback for the menu system.
 *
 * @param string $op
 *   The operation being performed.
 * @param AcquiaDAM_Assets_AbstractAsset $asset
 *   The asset to check permissions for.
 * @param object $account
 *   The account to check permissions against.
 *
 * @return bool
 *   If the account has permissions to perform the given operation.
 */
function media_acquiadam_asset_access($op, AcquiaDAM_Assets_AbstractAsset $asset, $account = NULL) {
  if (empty($account)) {
    $account = $GLOBALS['user'];
  }
  $rights =& drupal_static(__FUNCTION__, []);
  if (isset($rights[$account->uid][$asset['id']][$op])) {
    return $rights[$account->uid][$asset['id']][$op];
  }
  elseif ('view' == $op) {
    return $rights[$account->uid][$asset['id']][$op] = $asset
      ->isExpired() ? user_access('view expired acquiadam assets', $account) : user_access('view acquiadam assets', $account);
  }
  elseif ('refresh' == $op) {
    return $rights[$account->uid][$asset['id']][$op] = user_access('refresh acquiadam assets', $account);
  }
  return FALSE;
}

/**
 * Implements hook_entity_delete().
 */
function media_acquiadam_entity_delete($entity, $type) {
  if ('file' == $type && !empty($entity->acquiadam_id)) {
    media_acquiadam_flush_cache([
      $entity->acquiadam_id,
    ]);
  }
}

/**
 * Implements hook_file_entity_access().
 */
function media_acquiadam_file_entity_access($op, $file, $account) {
  if (empty($file->acquiadam_id)) {
    return FILE_ENTITY_ACCESS_IGNORE;
  }
  $asset = media_acquiadam_file_to_asset($file);

  // We had an asset id linked to the file, but we were not able to load the
  // asset. This can happen when the API user does not have access to the file.
  // We do not IGNORE because this also happens when an asset is expired.
  if (empty($asset)) {
    return FILE_ENTITY_ACCESS_DENY;
  }
  return media_acquiadam_asset_access($op, $asset, $account) ? FILE_ENTITY_ACCESS_ALLOW : FILE_ENTITY_ACCESS_DENY;
}