View source
<?php
use Aws\Credentials\CredentialProvider;
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
use Aws\Sdk;
class S3fsException extends Exception {
}
function s3fs_stream_wrappers() {
if (module_exists('composer_manager')) {
composer_manager_register_autoloader();
}
return array(
's3' => array(
'name' => 'S3 File System',
'class' => 'S3fsStreamWrapper',
'description' => t('Amazon Simple Storage Service'),
'type' => STREAM_WRAPPERS_NORMAL,
),
);
}
function s3fs_stream_wrappers_alter(&$wrappers) {
$config = _s3fs_get_config();
if (!empty($config['use_s3_for_public'])) {
$wrappers['public'] = array(
'name' => t('Public files (s3fs)'),
'class' => 'S3fsStreamWrapper',
'description' => t('Public files served from Amazon S3.'),
'type' => STREAM_WRAPPERS_NORMAL,
);
}
if (!empty($config['use_s3_for_private'])) {
$wrappers['private'] = array(
'name' => t('Private files (s3fs)'),
'class' => 'S3fsStreamWrapper',
'description' => t('Private files served from Amazon S3.'),
'type' => STREAM_WRAPPERS_NORMAL,
'private' => TRUE,
);
}
}
function s3fs_libraries_info() {
return array(
'awssdk' => array(
'title' => 'AWS SDK for PHP',
'vendor url' => 'http://docs.aws.amazon.com/aws-sdk-php/guide/latest/index.html',
'download url' => 'https://github.com/aws/aws-sdk-php/releases',
'version arguments' => array(
'file' => 'Aws/Sdk.php',
'pattern' => "/const VERSION = '(.*)';/",
'lines' => 500,
),
'files' => array(
'php' => array(
'aws-autoloader.php',
),
),
),
);
}
function s3fs_menu() {
$items = array();
$items['admin/config/media/s3fs'] = array(
'title' => 'S3 File System',
'description' => 'Configure S3 File System.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
's3fs_settings',
),
'access arguments' => array(
'administer s3fs',
),
'file' => 's3fs.admin.inc',
'type' => MENU_NORMAL_ITEM,
);
$items['admin/config/media/s3fs/settings'] = array(
'title' => 'Settings',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
);
$items['admin/config/media/s3fs/actions'] = array(
'title' => 'Actions',
'description' => 'Actions for S3 File System.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
's3fs_actions',
),
'access arguments' => array(
'administer s3fs',
),
'file' => 's3fs.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 10,
);
$items['admin/config/media/s3fs/actions/copy-images'] = array(
'title' => 'Copy System Images to S3',
'description' => 'Copy system image files from modules, themes, and libraries to S3.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
's3fs_copy_system_images_confirm_form',
),
'access arguments' => array(
'administer s3fs',
),
'file' => 's3fs.admin.inc',
'type' => MENU_LOCAL_TASK,
);
$items['s3/files/styles/%image_style'] = array(
'title' => 'Generate image style in S3',
'page callback' => '_s3fs_image_style_deliver',
'page arguments' => array(
3,
),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
function s3fs_permission() {
return array(
'administer s3fs' => array(
'title' => t('Administer S3 File System'),
),
);
}
function s3fs_help($path, $arg) {
$actions = 'admin/config/media/s3fs/actions';
$settings = 'admin/config/media/s3fs';
if ($path == $settings) {
$msg = t('To perform actions such as refreshing the metadata cache, visit the !link.<br>
Disabled fields have been hard-coded in settings.php, and cannot be changed here. See the !README for details.', array(
'!link' => l(t('actions page'), $actions),
'!README' => l('README', drupal_get_path('module', 's3fs') . '/README.txt'),
));
return "<p>{$msg}</p>";
}
elseif ($path == $actions) {
$msg = t('These are the actions that you can perform upon S3 File System.');
$msg .= '<br>' . t('To change your settings, visit the !link.', array(
'!link' => l(t('settings page'), $settings),
));
return "<p>{$msg}</p>";
}
}
function s3fs_form_system_file_system_settings_alter(&$form, &$form_state, $form_id) {
$config = _s3fs_get_config();
if (!empty($config['use_s3_for_public'])) {
$form['file_public_path']['#attributes'] = array(
'disabled' => 'disabled',
);
$form['file_public_path']['#description'] = 'S3 File System has taken control of the public:// filesystem, making this setting irrelevant for typical use.';
}
if (!empty($config['use_s3_for_private'])) {
$form['file_private_path']['#attributes'] = array(
'disabled' => 'disabled',
);
$form['file_private_path']['#description'] = 'S3 File System has taken control of the private:// filesystem, making this setting irrelevant for typical use.';
}
}
function _s3fs_image_style_deliver() {
$args = func_get_args();
$style = array_shift($args);
$scheme = array_shift($args);
$filename = implode('/', $args);
$valid = !empty($style) && file_stream_wrapper_valid_scheme($scheme);
if (!variable_get('image_allow_insecure_derivatives', FALSE) || strpos(ltrim($filename, '\\/'), 'styles/') === 0) {
$valid = $valid && isset($_GET[IMAGE_DERIVATIVE_TOKEN]) && $_GET[IMAGE_DERIVATIVE_TOKEN] === image_style_path_token($style['name'], "{$scheme}://{$filename}");
}
if (!$valid) {
return MENU_ACCESS_DENIED;
}
$image_uri = "{$scheme}://{$filename}";
$derivative_uri = image_style_path($style['name'], $image_uri);
if (!is_file($image_uri)) {
watchdog('s3fs', 'Source image at %source_image_path not found while trying to generate derivative image at %derivative_path.', array(
'%source_image_path' => $image_uri,
'%derivative_path' => $derivative_uri,
));
return MENU_NOT_FOUND;
}
$lock_name = "_s3fs_image_style_deliver:{$style['name']}:" . drupal_hash_base64($image_uri);
if (!file_exists($derivative_uri)) {
$lock_acquired = lock_acquire($lock_name);
if (!$lock_acquired) {
drupal_add_http_header('Status', '503 Service Unavailable');
drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
drupal_add_http_header('Retry-After', 3);
print t('Image generation in progress. Try again shortly.');
drupal_exit();
}
}
$success = file_exists($derivative_uri);
if (!$success) {
$success = image_style_create_derivative($style, $image_uri, $derivative_uri);
file_stream_wrapper_get_instance_by_scheme('s3')
->waitUntilFileExists($derivative_uri);
}
if (!empty($lock_acquired)) {
lock_release($lock_name);
}
if ($success) {
if (_s3fs_get_setting('no_redirect_derivatives', False)) {
$image = image_load($derivative_uri);
$settings = array(
'Content-Type' => $image->info['mime_type'],
'Content-Length' => $image->info['file_size'],
);
file_transfer($image->source, $settings);
}
else {
drupal_goto(file_create_url($derivative_uri));
}
}
else {
watchdog('S3 File System', 'Unable to generate an image derivative at %path.', array(
'%path' => $derivative_uri,
));
drupal_add_http_header('Status', '500 Internal Server Error');
drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
print t('Error generating image.');
drupal_exit();
}
}
function _s3fs_validate_config($config) {
if (!empty($config['use_customhost']) && empty($config['hostname'])) {
form_set_error('s3fs_hostname', 'You must specify a Hostname to use the Custom Host feature.');
return FALSE;
}
if (!empty($config['use_cname']) && empty($config['domain'])) {
form_set_error('s3fs_domain', 'You must specify a CDN Domain Name to use the CNAME feature.');
return FALSE;
}
switch ($config['domain_root']) {
case 'root':
if (empty($config['root_folder'])) {
form_set_error('s3fs_root_folder', 'You must specify a Root folder to map the Domain Name to it.');
return FALSE;
}
break;
case 'public':
if (empty($config['public_folder'])) {
form_set_error('s3fs_public_folder', 'You must specify a Public folder to map the Domain Name to it.');
return FALSE;
}
elseif (!empty($config['root_folder'])) {
form_set_error('s3fs_root_folder', 'For the Public folder option, the Root folder must be blank. Otherwise, use the "Root & Public folders" option.');
return FALSE;
}
break;
case 'root_public':
if (empty($config['root_folder']) || empty($config['public_folder'])) {
form_set_error('s3fs_domain_root', 'You must specify both Root and Public folders to map the Domain Name to it.');
return FALSE;
}
break;
}
try {
$s3 = _s3fs_get_amazons3_client($config);
} catch (S3fsException $e) {
form_set_error('form', $e
->getMessage());
return FALSE;
}
try {
$list_obj_args = array(
'Bucket' => $config['bucket'],
'MaxKeys' => 1,
);
if (!empty($config['root_folder'])) {
$list_obj_args['Prefix'] = "{$config['root_folder']}/";
}
$s3
->listObjects($list_obj_args);
} catch (S3Exception $e) {
form_set_error('form', t('An unexpected %exception occurred, with the following error message:<br>%error', array(
'%exception' => $e
->getAwsErrorCode(),
'%error' => $e
->getMessage(),
)));
return FALSE;
}
return TRUE;
}
function _s3fs_refresh_cache($config) {
if (!_s3fs_validate_config($config)) {
form_set_error('s3fs_refresh_cache][refresh', t('Unable to validate S3 configuration settings.'));
return;
}
if (function_exists('drush_log')) {
drush_log('Getting Amazon S3 client...');
}
$s3 = _s3fs_get_amazons3_client($config);
$iterator_args = array(
'Bucket' => $config['bucket'],
);
if (!empty($config['root_folder'])) {
$iterator_args['Prefix'] = "{$config['root_folder']}/";
}
$op_name = _s3fs_get_setting('use_versioning') ? 'ListObjectVersions' : 'ListObjects';
$iterator = $s3
->getPaginator($op_name, $iterator_args);
if (function_exists('drush_log')) {
drush_log('Creating temporary tables...');
}
module_load_install('s3fs');
$schema = s3fs_schema();
try {
db_create_table('s3fs_file_temp', $schema['s3fs_file']);
} catch (DatabaseSchemaObjectExistsException $e) {
db_truncate('s3fs_file_temp')
->execute();
}
try {
$folder_schema = $schema['s3fs_file'];
unset($folder_schema['primary key'], $folder_schema['indexes']);
db_create_table('s3fs_folder_temp', $folder_schema);
$options = Database::getConnectionInfo('default');
switch ($options['default']['driver']) {
case 'pgsql':
break;
case 'sqlite':
break;
case 'mysql':
db_query('ALTER TABLE {s3fs_folder_temp} CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin');
break;
}
} catch (DatabaseSchemaObjectExistsException $e) {
db_truncate('s3fs_folder_temp')
->execute();
}
$folders = array();
$file_metadata_list = array();
$existing_folders = db_select('s3fs_file', 's')
->fields('s', array(
'uri',
))
->condition('dir', 1, '=');
$folder_counter = 0;
foreach ($existing_folders
->execute()
->fetchCol(0) as $folder_uri) {
$folders[rtrim($folder_uri, '/')] = TRUE;
if ($folder_counter++ % 1000 == 0) {
_s3fs_write_metadata($file_metadata_list, $folders);
}
}
foreach ($iterator as $result) {
if (!isset($result['Contents'])) {
continue;
}
foreach ($result['Contents'] as $s3_metadata) {
$key = $s3_metadata['Key'];
if (!empty($config['root_folder'])) {
$key = str_replace("{$config['root_folder']}/", '', $key);
}
$public_folder_name = !empty($config['public_folder']) ? $config['public_folder'] : 's3fs-public';
$private_folder_name = !empty($config['private_folder']) ? $config['private_folder'] : 's3fs-private';
if (strpos($key, "{$public_folder_name}/") === 0) {
$key = str_replace("{$public_folder_name}/", '', $key);
$uri = "public://{$key}";
}
elseif (strpos($key, "{$private_folder_name}/") === 0) {
$key = str_replace("{$private_folder_name}/", '', $key);
$uri = "private://{$key}";
}
else {
$uri = "s3://{$key}";
}
$max_uri_length = $schema['s3fs_file']['fields']['uri']['length'];
if (strlen($uri) >= $max_uri_length) {
watchdog('s3fs', 'URI "@uri" is too long, ignoring', array(
'@uri' => $uri,
), WATCHDOG_WARNING);
continue;
}
if ($uri[strlen($uri) - 1] == '/') {
$folders[rtrim($uri, '/')] = TRUE;
}
else {
if (isset($s3_metadata['IsLatest']) && !$s3_metadata['IsLatest']) {
continue;
}
if (!isset($s3_metadata['StorageClass'])) {
continue;
}
if (isset($s3_metadata['VersionId']) && $s3_metadata['VersionId'] == 'null') {
unset($s3_metadata['VersionId']);
}
$file_metadata_list[] = _s3fs_convert_metadata($uri, $s3_metadata);
}
_s3fs_write_metadata($file_metadata_list, $folders);
}
}
$query = db_select('s3fs_folder_temp')
->distinct();
$query
->fields('s3fs_folder_temp');
$folder_counter = 0;
$result = $query
->execute();
$insert_query = db_insert('s3fs_file_temp')
->fields(array(
'uri',
'filesize',
'timestamp',
'dir',
'version',
));
foreach ($result as $record) {
$insert_query
->values((array) $record);
if ($folder_counter++ % 1000 == 0) {
$insert_query
->execute();
}
}
$insert_query
->execute();
if (function_exists('drush_log')) {
drush_log(dt('Flushed @folders folders to the file table.', array(
'@folders' => $folder_counter,
)));
}
db_drop_table('s3fs_folder_temp');
db_rename_table('s3fs_file', 's3fs_file_old');
db_rename_table('s3fs_file_temp', 's3fs_file');
db_drop_table('s3fs_file_old');
if (function_exists('drush_log')) {
drush_log(dt('S3 File System cache refreshed.'));
}
else {
drupal_set_message(t('S3 File System cache refreshed.'));
}
}
function _s3fs_write_metadata(&$file_metadata_list, &$folders) {
if (!empty($file_metadata_list)) {
$insert_query = db_insert('s3fs_file_temp')
->fields(array(
'uri',
'filesize',
'timestamp',
'dir',
'version',
));
foreach ($file_metadata_list as $key => $metadata) {
$uri = drupal_dirname($metadata['uri']);
if (!$metadata['dir']) {
$insert_query
->values($metadata);
}
else {
$folders[$uri] = $metadata;
unset($file_metadata_list[$key]);
}
$root = file_uri_scheme($uri) . '://';
while ($uri != $root) {
$folders[rtrim($uri, '/')] = TRUE;
$uri = drupal_dirname($uri);
}
}
$insert_query
->execute();
if (function_exists('drush_log')) {
drush_log(' ' . dt('Wrote @files file(s).', array(
'@files' => count($file_metadata_list),
)));
}
$file_metadata_list = array();
}
if (!empty($folders)) {
$insert_query = db_insert('s3fs_folder_temp')
->fields(array(
'uri',
'filesize',
'timestamp',
'dir',
'version',
));
foreach ($folders as $folder_name => $folder_data) {
if (is_bool($folder_data)) {
$insert_query
->values(_s3fs_convert_metadata($folder_name, array()));
}
else {
$insert_query
->values($folder_data);
}
}
$insert_query
->execute();
if (function_exists('drush_log')) {
drush_log(' ' . dt('Wrote @folders folder(s).', array(
'@folders' => count($folders),
)));
}
$folders = array();
}
}
function _s3fs_convert_metadata($uri, $s3_metadata) {
$metadata = array(
'uri' => $uri,
'filesize' => 0,
'timestamp' => REQUEST_TIME,
'dir' => 0,
'version' => '',
);
if (empty($s3_metadata)) {
$metadata['dir'] = 1;
}
else {
if (isset($s3_metadata['ContentLength'])) {
$metadata['filesize'] = $s3_metadata['ContentLength'];
}
elseif (isset($s3_metadata['Size'])) {
$metadata['filesize'] = $s3_metadata['Size'];
}
if (isset($s3_metadata['LastModified'])) {
$metadata['timestamp'] = date('U', strtotime($s3_metadata['LastModified']));
}
if (isset($s3_metadata['VersionId']) && $s3_metadata['VersionId'] != 'null') {
$metadata['version'] = $s3_metadata['VersionId'];
}
}
return $metadata;
}
function _s3fs_get_amazons3_client($config) {
static $s3;
static $static_config;
if (!isset($s3) || $static_config != $config) {
$access_key = _s3fs_get_setting('awssdk_access_key');
if (isset($config['awssdk_access_key'])) {
$access_key = $config['awssdk_access_key'];
}
$secret_key = _s3fs_get_setting('awssdk_secret_key');
if (isset($config['awssdk_secret_key'])) {
$secret_key = $config['awssdk_secret_key'];
}
$use_instance_profile = _s3fs_get_setting('use_instance_profile');
if (isset($config['use_instance_profile'])) {
$use_instance_profile = $config['use_instance_profile'];
}
$credentials_file = _s3fs_get_setting('credentials_file');
if (isset($config['credentials_file'])) {
$credentials_file = $config['credentials_file'];
}
$sdk_loaded = FALSE;
if (module_exists('composer_manager')) {
$sdk_loaded = class_exists('Aws\\Sdk');
}
elseif (module_exists('libraries')) {
$library = _s3fs_load_awssdk_library();
$sdk_loaded = $library['loaded'];
}
if (!$sdk_loaded) {
throw new S3fsException(t('Unable to load the AWS SDK. Please ensure that the AWS SDK library is installed correctly.'));
}
elseif (!class_exists('Aws\\S3\\S3Client')) {
throw new S3fsException(t('Cannot load Aws\\S3\\S3Client class. Please ensure that the AWS SDK library is installed correctly.'));
}
$client_config = array();
if ($use_instance_profile) {
if ($credentials_file) {
$provider = CredentialProvider::ini(NULL, $credentials_file);
}
else {
$provider = CredentialProvider::instanceProfile();
}
$provider = CredentialProvider::memoize($provider);
$client_config['credentials'] = $provider;
}
elseif (!empty($access_key) && !empty($secret_key)) {
$client_config['credentials'] = array(
'key' => $access_key,
'secret' => $secret_key,
);
}
if (!empty($config['region'])) {
$client_config['region'] = $config['region'];
$client_config['signature'] = 'v4';
}
if (!empty($config['use_customhost']) && !empty($config['hostname'])) {
$client_config['base_url'] = $config['hostname'];
}
$client_config['version'] = '2006-03-01';
$s3 = new S3Client($client_config);
}
$static_config = $config;
return $s3;
}
function _s3fs_get_config($reset = FALSE) {
$config =& drupal_static('_s3fs_get_config');
if ($config === NULL || $reset) {
global $conf;
$config = array();
foreach ($conf as $key => $value) {
if (substr($key, 0, 5) == 's3fs_') {
$config[substr($key, 5)] = $value;
}
}
foreach ($conf as $key => $value) {
if (substr($key, 0, 7) == 'awssdk_') {
$config[$key] = $value;
}
}
if (!empty($config['root_folder'])) {
$config['root_folder'] = trim($config['root_folder'], '\\/');
}
if (!empty($config['public_folder'])) {
$config['public_folder'] = trim($config['public_folder'], '\\/');
}
if (!empty($config['private_folder'])) {
$config['private_folder'] = trim($config['private_folder'], '\\/');
}
}
return $config;
}
function _s3fs_get_setting($setting, $default = '') {
$config = _s3fs_get_config();
return !empty($config[$setting]) ? $config[$setting] : $default;
}
function _s3fs_load_awssdk_library() {
$library = libraries_load('awssdk');
if (!empty($library['loaded'])) {
return $library;
}
cache_clear_all('awssdk', 'cache_libraries');
drupal_static_reset('libraries_load');
return libraries_load('awssdk');
}
function _s3fs_copy_file_system_to_s3($scheme) {
if ($scheme == 'public') {
$source_folder = realpath(variable_get('file_public_path', conf_path() . '/files'));
}
elseif ($scheme == 'private') {
$source_folder = variable_get('file_private_path', '');
$source_folder_real = realpath($source_folder);
if (empty($source_folder) || empty($source_folder_real)) {
drupal_set_message('Private file system base path is unknown. Unable to perform S3 copy.', 'error');
return;
}
}
$file_paths = _s3fs_recursive_dir_scan($source_folder);
foreach ($file_paths as $path) {
$relative_path = str_replace($source_folder . '/', '', $path);
print "Copying {$scheme}://{$relative_path} into S3...\n";
copy($path, "{$scheme}://{$relative_path}");
}
drupal_set_message(t('Copied all local %scheme files to S3.', array(
'%scheme' => $scheme,
)), 'status');
}
function _s3fs_recursive_dir_scan($dir) {
$output = array();
$files = scandir($dir);
foreach ($files as $file) {
$path = "{$dir}/{$file}";
if ($file != '.' && $file != '..') {
if ($path == realpath(variable_get('file_private_path'))) {
continue;
}
if (is_dir($path)) {
$output = array_merge($output, _s3fs_recursive_dir_scan($path));
}
else {
$output[] = $path;
}
}
}
return $output;
}
function s3fs_copy_system_images_confirm_form($form, &$form_state) {
if (!variable_get('s3fs_no_rewrite_cssjs', FALSE)) {
drupal_goto('admin/config/media/s3fs/actions');
}
$wrapper = variable_get('file_default_scheme', 'public') . '://';
$directories = s3fs_copy_system_images_directories();
if (!empty($directories['root_dirs'])) {
$description = t('<h2><strong><span class="warning">Warning: Unrelated files may be deleted. Proceed with caution.</span></strong></h2>');
$description .= t('
<p>All files located in the S3 directories shown below will be deleted as part of this copy process. If you have stored files in
one of these locations that is not related to S3 system images, <strong>cancel this process immediately and resolve the conflicts
before proceeding.</strong> If a large number of modules are installed, this process can take several minutes to complete.</p>');
$description .= t('<h3>!count images to be copied to S3:</h3>', array(
'!count' => $directories['total'],
));
$description .= t('<h4>Summary</h4>');
$description .= '<ul>';
foreach ($directories['root_dirs'] as $root_dir => $root_count) {
$description .= '<li>' . $wrapper . $root_dir . ' (' . $root_count . ')</li>';
}
$description .= '</ul><br>';
$description .= t('<h3>Details</h3>');
$description .= '<ul>';
foreach ($directories['dirs'] as $dir => $count) {
$description .= '<li>' . $wrapper . $dir . ' (' . $count . ')</li>';
}
$description .= '</ul><br>';
}
else {
$description = t('<p>Copy system images from modules, themes, and libraries to the S3 File System.</p>
<p>If a large number of modules are installed, this process can take several minutes to complete.</p>');
}
$form = confirm_form($form, t('Copy System Images to S3'), array(
'path' => 'admin/config/media/s3fs/actions',
), $description);
$form_state['build_info']['system_stream_wrapper'] = $wrapper;
$form_state['build_info']['system_image_directories'] = $directories;
$form['actions']['submit']['#submit'] = array(
's3fs_copy_system_images_confirm_form_submit',
);
return $form;
}
function s3fs_copy_system_images_confirm_form_submit($form, &$form_state) {
$wrapper = $form_state['build_info']['system_stream_wrapper'];
$directories = $form_state['build_info']['system_image_directories'];
s3fs_copy_system_images_batch_set($wrapper, $directories);
drupal_set_message(t('Copying of system images from modules, themes, and libraries to S3 is complete.'));
$form_state['redirect'] = array(
'path' => 'admin/config/media/s3fs/actions',
);
}
function s3fs_copy_system_images_batch_set($wrapper, $directories) {
$operations = array();
foreach ($directories['root_dirs'] as $directory => $count) {
$operations[] = array(
's3fs_copy_system_images_delete_batch',
array(
$wrapper,
$directory,
),
);
}
foreach ($directories['dirs'] as $directory => $count) {
$operations[] = array(
's3fs_copy_system_images_save_batch',
array(
$wrapper,
$directory,
),
);
}
$batch = array(
'title' => t('Copying system images to S3'),
'operations' => $operations,
'init_message' => t('Starting process of copying system files to S3.'),
'error_message' => t('Copying system files to S3 has encountered an error.'),
);
batch_set($batch);
}
function s3fs_copy_system_images_directories() {
$dirs = array(
'misc',
'modules',
);
foreach (libraries_get_libraries() as $library_name => $library_path) {
$dirs[] = $library_path;
}
foreach (module_list() as $module_name => $module) {
$dirs[] = drupal_get_path('module', $module_name);
}
foreach (list_themes() as $theme_name => $theme) {
$dirs[] = drupal_get_path('theme', $theme_name);
}
$dirs = array_values(array_unique($dirs));
$image_dirs = array();
foreach ($dirs as $dir) {
if ($files = file_scan_directory($dir, '/^.*\\.(png|gif|jpe?g|svg|bmp)$/')) {
$image_dirs[$dir] = count($files);
}
}
$root_image_dirs = array();
foreach ($image_dirs as $image_dir => $image_count) {
$dir_split = explode('/', $image_dir);
if (array_key_exists($dir_split[0], $root_image_dirs)) {
$root_image_dirs[$dir_split[0]] = $root_image_dirs[$dir_split[0]] + $image_count;
}
else {
$root_image_dirs[$dir_split[0]] = $image_count;
}
}
ksort($image_dirs);
ksort($root_image_dirs);
return array(
'total' => array_sum($image_dirs),
'dirs' => $image_dirs,
'root_dirs' => $root_image_dirs,
);
}
function s3fs_copy_system_images_delete_batch($wrapper, $directory) {
file_unmanaged_delete_recursive($wrapper . $directory);
}
function s3fs_copy_system_images_save_batch($wrapper, $directory) {
$local_files = file_scan_directory($directory, '/^.*\\.(png|gif|jpe?g|svg|bmp)$/');
foreach ($local_files as $local_file_uri => $local_file) {
$remote_file_path = str_replace('/' . $local_file->filename, '', $local_file_uri);
if (!is_dir($wrapper . $remote_file_path)) {
drupal_mkdir($wrapper . $remote_file_path, NULL, TRUE, NULL);
}
file_unmanaged_copy($local_file_uri, $wrapper . $local_file_uri, FILE_EXISTS_REPLACE);
}
}
function s3fs_field_default_field_bases_alter(&$fields) {
if ($uri_scheme = variable_get('s3fs_file_uri_scheme_override', FALSE)) {
foreach ($fields as $key => $item) {
if (isset($item['settings']['uri_scheme'])) {
$fields[$key]['settings']['uri_scheme'] = $uri_scheme;
}
}
}
}