You are here

amazons3.module in AmazonS3 7

Same filename and directory in other branches
  1. 7.2 amazons3.module

Provides S3 stream wrapper

File

amazons3.module
View source
<?php

/**
 * @file
 * Provides S3 stream wrapper
 */

/**
 * Implements hook_stream_wrappers().
 *
 * Create a stream wrapper for S3.
 */
function amazons3_stream_wrappers() {
  return array(
    's3' => array(
      'name' => 'Amazon S3',
      'class' => 'AmazonS3StreamWrapper',
      'description' => t('Amazon Simple Storage Service'),
    ),
  );
}

/**
 * Implements hook_menu().
 */
function amazons3_menu() {
  $items = array();
  $items['admin/config/media/amazons3'] = array(
    'title' => 'Amazon S3',
    'description' => 'Configure S3 credentials and settings',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'amazons3_admin',
    ),
    'access arguments' => array(
      'administer amazons3',
    ),
  );
  return $items;
}

/**
 * Implements hook_permission().
 */
function amazons3_permission() {
  return array(
    'administer amazons3' => array(
      'title' => t('Administer AmazonS3'),
    ),
  );
}

/**
 * Implements hook_help().
 */
function amazons3_help($path, $arg) {
  switch ($path) {
    case 'admin/config/media/amazons3':
      if (module_exists('awssdk_ui')) {
        return '<p>' . t('Amazon Web Services authentication can be configured at the <a href="@awssdk_config">AWS SDK configuration page</a>.', array(
          '@awssdk_config' => url('admin/config/media/awssdk'),
        )) . '</p>';
      }
      else {
        return '<p>' . t("Enable 'AWS SDK for PHP UI' module to configure your Amazon Web Services authentication. Configuration can also be defined in the \$conf array in settings.php.", array(
          '@awssdk_config' => url('admin/config/media/awssdk'),
        )) . '</p>';
      }
      break;
  }
}

/**
 * Implements hook_admin().
 */
function amazons3_admin() {
  $form = array();
  $form['amazons3_bucket'] = array(
    '#type' => 'textfield',
    '#title' => t('Default Bucket Name'),
    '#default_value' => variable_get('amazons3_bucket', ''),
    '#required' => TRUE,
  );
  $form['amazons3_cache'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enable database caching'),
    '#description' => t('Enable a local file metadata cache, this significantly reduces calls to S3'),
    '#default_value' => variable_get('amazons3_cache', 1),
  );
  $form['amazons3_cname'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enable CNAME'),
    '#description' => t('Serve files from a custom domain by using an appropriately named bucket e.g. "mybucket.mydomain.com"'),
    '#default_value' => variable_get('amazons3_cname', 0),
  );
  $form['amazons3_domain'] = array(
    '#type' => 'textfield',
    '#title' => t('CDN Domain Name'),
    '#description' => t('If serving files from CloudFront then the bucket name can differ from the domain name.'),
    '#default_value' => variable_get('amazons3_domain', ''),
    '#states' => array(
      'visible' => array(
        ':input[id=edit-amazons3-cname]' => array(
          'checked' => TRUE,
        ),
      ),
    ),
  );
  $form['amazons3_cloudfront'] = array(
    '#type' => 'checkbox',
    '#title' => t('Enable CloudFront'),
    '#description' => t('Deliver URLs through a CloudFront domain when using presigned URLs.'),
    '#default_value' => variable_get('amazons3_cloudfront', 0),
    '#states' => array(
      'visible' => array(
        ':input[id=edit-amazons3-cname]' => array(
          'checked' => TRUE,
        ),
      ),
    ),
  );
  $form['amazons3_hostname'] = array(
    '#type' => 'textfield',
    '#title' => t('Custom Hostname'),
    '#description' => t('For use with an alternative API compatible service e.g. <a href="@cloud">Google Cloud Storage</a>', array(
      '@cloud' => 'https://cloud.google.com/storage‎',
    )),
    '#default_value' => variable_get('amazons3_hostname', ''),
  );
  $form['amazons3_https'] = array(
    '#type' => 'textarea',
    '#title' => t('Force HTTPS'),
    '#description' => t('A list of paths that should be delivered through a https url. This is not necessary if the current page being served is already HTTPS. Enter one value per line e.g. "mydir/*". Paths are relative to the Drupal file directory and use patterns as per <a href="@preg_match">preg_match</a>.', array(
      '@preg_match' => 'http://php.net/preg_match',
    )),
    '#default_value' => variable_get('amazons3_https', ''),
    '#rows' => 10,
  );
  $form['amazons3_torrents'] = array(
    '#type' => 'textarea',
    '#title' => t('Torrents'),
    '#description' => t('A list of paths that should be delivered through a torrent url. Enter one value per line e.g. "mydir/*". Paths are relative to the Drupal file directory and use patterns as per <a href="@preg_match">preg_match</a>. This won\'t work for CloudFront presigned URLs.', array(
      '@preg_match' => 'http://php.net/preg_match',
    )),
    '#default_value' => variable_get('amazons3_torrents', ''),
    '#rows' => 10,
  );
  $form['amazons3_presigned_urls'] = array(
    '#type' => 'textarea',
    '#title' => t('Presigned URLs'),
    '#description' => t('A list of timeouts and paths that should be delivered through a presigned url. Enter one value per line, in the format &lt;timeout&gt;|&lt;path&gt;|&lt;protocol&gt;. e.g. "60|mydir/*" or "60|mydir/*|https". Paths are relative to the Drupal file directory and use patterns as per <a href="@preg_match">preg_match</a>.', array(
      '@preg_match' => 'http://php.net/preg_match',
    )),
    '#default_value' => variable_get('amazons3_presigned_urls', ''),
    '#rows' => 10,
  );
  $form['amazons3_saveas'] = array(
    '#type' => 'textarea',
    '#title' => t('Force Save As'),
    '#description' => t('A list of paths that force the user to save the file by using Content-disposition header. Prevents autoplay of media. Enter one value per line. e.g. "mydir/*". Paths are relative to the Drupal file directory and use patterns as per <a href="@preg_match">preg_match</a>. Files must use a presigned url to use this, however it won\'t work for CloudFront presigned URLs and you\'ll need to set the content-disposition header in the file metadata before saving.', array(
      '@preg_match' => 'http://php.net/preg_match',
    )),
    '#default_value' => variable_get('amazons3_saveas', ''),
    '#rows' => 10,
  );
  $form['amazons3_rrs'] = array(
    '#type' => 'textarea',
    '#title' => t('Reduced Redundancy Storage'),
    '#description' => t('A list of paths that save the file in <a href="@rrs">Reduced Redundancy Storage</a>. Enter one value per line. e.g. "styles/*". Paths are relative to the Drupal file directory and use patterns as per <a href="@preg_match">preg_match</a>.', array(
      '@rrs' => 'http://aws.amazon.com/s3/faqs/#rrs_anchor',
      '@preg_match' => 'http://php.net/preg_match',
    )),
    '#default_value' => variable_get('amazons3_rrs', ''),
    '#rows' => 10,
  );
  $form['amazons3_clear_cache'] = array(
    '#type' => 'fieldset',
    '#title' => t('Clear cache'),
  );
  $form['amazons3_clear_cache']['clear'] = array(
    '#type' => 'submit',
    '#value' => t('Clear file metadata cache'),
    '#submit' => array(
      'amazons3_clear_cache_submit',
    ),
  );
  return system_settings_form($form);
}

/**
 * Validate the admin form.
 */
function amazons3_admin_validate($form, &$form_state) {
  $bucket = $form_state['values']['amazons3_bucket'];
  $cloudfront = $form_state['values']['amazons3_cloudfront'];
  if ($cloudfront) {
    $keypair = variable_get('aws_cloudfront_keypair', '');
    $pem = variable_get('aws_cloudfront_pem', '');
    if (empty($keypair) || empty($pem)) {
      form_set_error('amazons3_cloudfront', t('You must configure your CloudFront credentials in the awksdk module.'));
    }
  }
  if (!libraries_load('awssdk')) {
    form_set_error('amazons3_bucket', t('Unable to load the AWS SDK. Please check you have installed the library correctly and configured your S3 credentials.'));
  }
  elseif (!class_exists('AmazonS3')) {
    form_set_error('amazons3_bucket', t('Cannot load AmazonS3 class. Please check the awssdk is installed correctly'));
  }
  else {
    try {
      $s3 = new AmazonS3();
      if (!empty($form_state['values']['amazons3_hostname'])) {
        $s3
          ->set_hostname($form_state['values']['amazons3_hostname']);
      }
      $response = $s3
        ->list_objects($bucket, array(
        'max-keys' => 1,
      ));
      if (!$s3
        ->if_bucket_exists($bucket) || !$response
        ->isOK()) {
        form_set_error('amazons3_bucket', t('The S3 access credentials are invalid or the bucket does not exist'));
      }
    } catch (RequestCore_Exception $e) {
      if (strstr($e
        ->getMessage(), 'SSL certificate problem')) {
        form_set_error('amazons3_bucket', t('There was a problem with the SSL certificate. Try setting AWS_CERTIFICATE_AUTHORITY to true in "libraries/awssdk/config.inc.php". You may also have a curl library (e.g. the default shipped with MAMP) that does not contain trust certificates for the major authorities. The following exception was thrown: @exception', array(
          '@exception' => $e
            ->getMessage(),
        )));
      }
      else {
        form_set_error('amazons3_bucket', t('There was a problem connecting to S3. The following exception was thrown: @exception', array(
          '@exception' => $e
            ->getMessage(),
        )));
      }
    } catch (Exception $e) {
      form_set_error('amazons3_bucket', t('There was a problem using S3. The following exception was thrown: @exception', array(
        '@exception' => $e
          ->getMessage(),
      )));
    }
  }
}

/**
 * Admin sub-form submit callback; clear file metadata cache.
 */
function amazons3_clear_cache_submit($form, &$form_state) {
  db_query('TRUNCATE TABLE {amazons3_file}');
  drupal_set_message(t('Cache cleared.'));
}

/**
 * Implements hook_field_default_field_bases_alter().
 *
 * Allows a variable to override all exported field bases to use 'Amazon S3' as
 * the Upload destination. For example this can be added to environment-specific
 * Drupal settings files, to allow certain environments to upload to S3 while
 * other environments upload to the exported (public or private) URI scheme:
 * @code
 * $conf['amazons3_file_uri_scheme_override'] = 's3';
 * @endcode
 */
function amazons3_field_default_field_bases_alter(&$fields) {
  if ($uri_scheme = variable_get('amazons3_file_uri_scheme_override', FALSE)) {
    foreach ($fields as $key => $item) {
      if (isset($item['settings']['uri_scheme'])) {
        $fields[$key]['settings']['uri_scheme'] = $uri_scheme;
      }
    }
  }
}

Functions

Namesort descending Description
amazons3_admin Implements hook_admin().
amazons3_admin_validate Validate the admin form.
amazons3_clear_cache_submit Admin sub-form submit callback; clear file metadata cache.
amazons3_field_default_field_bases_alter Implements hook_field_default_field_bases_alter().
amazons3_help Implements hook_help().
amazons3_menu Implements hook_menu().
amazons3_permission Implements hook_permission().
amazons3_stream_wrappers Implements hook_stream_wrappers().