scald_file.module in Scald File Provider 7
Scald File is a Scald Atom Provider for Files.
File
scald_file.moduleView source
<?php
/**
* @file
* Scald File is a Scald Atom Provider for Files.
*/
/*******************************************************************************
* SCALD HOOK IMPLEMENTATIONS
*/
/**
* Implements hook_scald_wysiwyg_context_list_alter().
*/
function scald_file_scald_wysiwyg_context_list_alter(&$contexts) {
drupal_add_js(drupal_get_path('module', 'scald_file') . '/scald_file.js');
drupal_add_js(array(
'scaldFile' => array(
'path' => drupal_get_path('module', 'scald_file') . '/scald_file.css',
),
), 'setting');
}
/**
* Implements hook_scald_atom_providers().
*/
function scald_file_scald_atom_providers() {
return array(
'file' => 'File upload',
);
}
/**
* Implements hook_scald_add_form().
*/
function scald_file_scald_add_form(&$form, &$form_state) {
$defaults = scald_atom_defaults('file');
$field = field_info_field('scald_file');
$instance = field_info_instance('scald_atom', 'scald_file', 'file');
$validators = array(
'file_validate_extensions' => array(
0 => 'ppt pptx xls xlsx doc docx odt pdf txt csv odg sxw ods rtf zip rar gz 7z tar',
),
);
$location = 'public://atoms/files';
if ($field && $instance) {
$validators = file_field_widget_upload_validators($field, $instance);
$directory = file_field_widget_uri($field, $instance);
if (file_prepare_directory($directory, FILE_CREATE_DIRECTORY)) {
$location = $directory;
}
}
$form['file'] = array(
'#type' => $defaults->upload_type,
'#title' => t('File'),
'#upload_location' => $location,
'#upload_validators' => $validators,
);
}
/**
* Implements hook_scald_add_atom_count().
*/
function scald_file_scald_add_atom_count(&$form, &$form_state) {
if (is_array($form_state['values']['file'])) {
return max(count($form_state['values']['file']), 1);
}
return 1;
}
/**
* Implements hook_scald_add_form_fill().
*/
function scald_file_scald_add_form_fill(&$atoms, $form, $form_state) {
foreach ($atoms as $delta => $atom) {
if (is_array($form_state['values']['file']) && module_exists('plupload')) {
module_load_include('inc', 'scald', 'includes/scald.plupload');
$destination = $form['file']['#upload_location'] . '/' . $form_state['values']['file'][$delta]['name'];
$file = scald_plupload_save_file($form_state['values']['file'][$delta]['tmppath'], $destination);
}
else {
$file = file_load($form_state['values']['file']);
}
foreach (array(
'author',
'tag',
) as $name) {
// hacky, because variable and field name do not really match.
$field_name = 'scald_' . $name . 's';
$langcode = field_language('scald_atom', $atom, $field_name);
if (empty($form_state['values'][$field_name])) {
continue;
}
// Borrowed from taxonomy_autocomplete_validate().
$typed_terms = drupal_explode_tags($form_state['values'][$field_name]);
$vocabulary = taxonomy_vocabulary_machine_name_load(variable_get('scald_' . $name . '_vocabulary', $field_name));
foreach ($typed_terms as $typed_term) {
if ($possibilities = taxonomy_term_load_multiple(array(), array(
'name' => trim($typed_term),
'vid' => $vocabulary->vid,
))) {
$term = array_pop($possibilities);
}
else {
$term = (object) array(
'vid' => $vocabulary->vid,
'name' => $typed_term,
'vocabulary_machine_name' => $vocabulary->machine_name,
);
taxonomy_term_save($term);
}
$atom->{$field_name}[$langcode][] = array(
'tid' => $term->tid,
);
}
}
$atom->title = $file->filename;
$langcode = field_language('scald_atom', $atom, 'scald_file');
$atom->scald_file[$langcode][0] = (array) $file;
}
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function scald_file_form_scald_atom_add_form_options_alter(&$form, &$form_state, $form_id) {
$scald = $form_state['scald'];
if (isset($scald['type'])) {
$type = $scald['type']->type;
}
else {
$type = $scald['atoms'][0]->type;
}
if ($type !== 'file') {
return;
}
foreach ($form as $key => $data) {
if (strpos($key, 'atom') === 0) {
$index = intval(substr($key, 4));
if (isset($scald['atoms'][$index]->data['scald_thumbnail_default'])) {
$scald_thumbnail_default = $scald['atoms'][$index]->data['scald_thumbnail_default'];
}
else {
$scald_thumbnail_default = TRUE;
}
$form[$key]['scald_thumbnail_default'] = array(
'#type' => 'checkbox',
'#default_value' => $scald_thumbnail_default,
'#title' => t('Automatically generate thumbnail'),
'#description' => t('A thumbnail will be generated automatically, if possible, if the thumbnail field is empty.'),
'#weight' => $form[$key]['scald_thumbnail']['#weight'] + 0.5,
'#tree' => TRUE,
'#parents' => array(
$key,
'scald_thumbnail_default',
),
);
}
}
$form['#attached']['js'][drupal_get_path('module', 'scald_file') . '/scald_file_edit_form.js'] = array(
'type' => 'file',
);
array_unshift($form['#submit'], 'scald_file_default_thumbnail_handler');
}
/**
* Handler to store the default thumbnail generation option in the atom Entity.
*/
function scald_file_default_thumbnail_handler(&$form, &$form_state) {
foreach ($form as $key => $data) {
if (strpos($key, 'atom') === 0) {
$index = intval(substr($key, 4));
$form_state['scald']['atoms'][$index]->data['scald_thumbnail_default'] = $form_state['values'][$key]['scald_thumbnail_default'];
}
}
}
/**
* Generate a thumbnail for a pdf file.
*/
function _scald_file_pdf_thumbnail($atom, $file) {
if ($file->filemime === 'application/pdf') {
$uri = drupal_realpath($file->uri);
if (file_exists($uri)) {
$temp = file_directory_temp() . '/pdf_thumb.png';
if (scald_file_is_exec_available() && (scald_file_command_exists('pdfdraw') || scald_file_command_exists('mudraw') || scald_file_command_exists('convert'))) {
if (scald_file_command_exists('pdfdraw')) {
exec('pdfdraw -o ' . escapeshellarg($temp) . ' ' . escapeshellarg($uri) . ' 1');
}
elseif (scald_file_command_exists('mudraw')) {
exec('mudraw -o ' . escapeshellarg($temp) . ' ' . escapeshellarg($uri) . ' 1');
}
elseif (scald_file_command_exists('convert')) {
$uri = $uri . '[0]';
exec('convert ' . escapeshellarg($uri) . ' ' . escapeshellarg($temp));
}
}
elseif (extension_loaded('imagick') && class_exists("Imagick")) {
$im = new Imagick($uri . '[0]');
$im = $im
->flattenImages();
$im
->setImageFormat("png");
$im
->thumbnailImage(400, 0);
$im
->writeImage($temp);
}
if (file_exists($temp)) {
$handle = fopen($temp, 'r');
if ($directory = ScaldAtomController::getThumbnailPath('file')) {
$dest = $directory . '/file-' . $file->fid . '.png';
$thumb = file_save_data($handle, $dest);
$langcode = field_language('scald_atom', $atom, 'scald_thumbnail');
$atom->scald_thumbnail[$langcode][0] = (array) $thumb;
}
fclose($handle);
unlink($temp);
}
}
}
}
/**
* Implements hook_scald_fetch().
*/
function scald_file_scald_fetch($atom, $type) {
if ($type == 'atom') {
$file = file_load($atom->base_id);
$atom->base_entity = $file;
$atom->file_source = $file->uri;
$scald_thumbnail = field_get_items('scald_atom', $atom, 'scald_thumbnail');
if (!empty($scald_thumbnail)) {
$thumbnail = file_load($scald_thumbnail[0]['fid']);
$atom->thumbnail_source = $thumbnail->uri;
}
else {
$atom->thumbnail_source = _scald_file_get_default_icon($file);
}
}
}
/**
* Get the default icon.
*
* @param object $file
* The file.
*
* @return string
* The file's path.
*/
function _scald_file_get_default_icon($file) {
$name = str_replace(array(
'/',
'-',
), array(
'_',
'_',
), $file->filemime);
$path = drupal_get_path('module', 'scald_file') . '/icons/' . $name . '.png';
drupal_alter('scald_file_icon', $path, $name, $file);
return $path;
}
/**
* Synchronisation of scald_file field with base_id.
*
* The scald_file field is also the base entity. We keep them in synchronisation
* when user updates that field.
*
* @param object $atom
* Atom.
*/
function _scald_file_sync_file($atom) {
if (!empty($atom->scald_file)) {
$items = field_get_items('scald_atom', $atom, 'scald_file');
$atom->base_id = $items[0]['fid'];
}
}
/**
* Implements hook_scald_update_atom().
*/
function scald_file_scald_update_atom($atom, $mode) {
if ($mode == 'atom') {
_scald_file_sync_file($atom);
}
}
/**
* Implements hook_scald_register_atom().
*/
function scald_file_scald_register_atom($atom, $mode) {
if ($mode == 'atom') {
_scald_file_sync_file($atom);
}
}
/**
* Implements hook_scald_atom_presave().
*/
function scald_file_scald_atom_presave($atom) {
if ($atom->type == 'file' && !empty($atom->data['scald_thumbnail_default'])) {
$scald_thumbnail = field_get_items('scald_atom', $atom, 'scald_thumbnail');
if (!$scald_thumbnail) {
$langcode = field_language('scald_atom', $atom, 'scald_file');
$file = file_load($atom->scald_file[$langcode][0]['fid']);
_scald_file_pdf_thumbnail($atom, $file);
}
}
}
/**
* Implements hook_scald_prerender().
*/
function scald_file_scald_prerender($atom, $context, $options, $mode) {
if ($mode == 'atom') {
if ($context === 'sdl_library_item') {
$scald_thumbnail = field_get_items('scald_atom', $atom, 'scald_thumbnail');
if (empty($scald_thumbnail)) {
$atom->rendered->thumbnail_transcoded_url = file_create_url($atom->thumbnail_source);
}
}
else {
$config = scald_context_config_load($context);
$file = isset($atom->base_entity) ? $atom->base_entity : file_load($atom->base_id);
$transcoder = '';
if (isset($config->transcoder[$atom->type]['*'])) {
$transcoder = $config->transcoder[$atom->type]['*'];
}
if (module_exists('pdf') && !empty($transcoder) && strpos($transcoder, 'pdf') !== FALSE && $file->filemime === 'application/pdf') {
$theme = preg_match('/^file_field_pdf_/', $transcoder) ? str_replace('file_field_pdf_', 'pdf_formatter_', $transcoder) : 'pdf_formatter_default';
$atom->rendered->player = theme($theme, array(
'file' => $file,
));
}
else {
$scald_thumbnail = field_get_items('scald_atom', $atom, 'scald_thumbnail');
if (!empty($transcoder) && !empty($scald_thumbnail) && preg_match('/^style-(.*)$/', $transcoder, $match)) {
$style_name = $match[1];
$preset = image_style_load($style_name);
$thumbnail_source = image_style_url($preset['name'], $atom->thumbnail_source);
}
else {
$thumbnail_source = $atom->thumbnail_source;
}
$atom->rendered->player = theme('scald_file_render', array(
'vars' => array(
'context' => $context,
'file_source' => $atom->file_source,
'file_size' => format_size($atom->base_entity->filesize),
'thumbnail_source' => $thumbnail_source,
'file_title' => check_plain($atom->title),
),
));
}
}
}
}
/**
* Implements hook_theme().
*/
function scald_file_theme() {
return array(
'scald_file_render' => array(
'variables' => array(
'vars' => NULL,
),
'template' => 'scald-file-render',
),
);
}
/**
* Processes variables for scald_file_render.tpl.php.
*
* Defines theme hook suggestions to be able to overwrite
* the template by context.
*/
function template_preprocess_scald_file_render(&$variables) {
$variables['theme_hook_suggestions'][] = 'scald_file_render';
$variables['theme_hook_suggestions'][] = 'scald_file_render__' . $variables['vars']['context'];
}
/**
* Implements hook_views_api().
*/
function scald_file_views_api() {
return array(
'api' => 2,
'path' => drupal_get_path('module', 'scald_file') . '/includes/',
);
}
/**
* Implements hook_scald_transcoders().
*/
function scald_file_scald_transcoders() {
$transcoders = array();
if (module_exists('pdf')) {
$info = module_invoke_all('field_formatter_info');
foreach ($info as $name => $formatter) {
if (!preg_match('/^pdf_/', $name)) {
continue;
}
$transcoders[$name] = array(
'title' => $formatter['label'],
'description' => $formatter['label'],
'formats' => array(
'file' => 'passthrough',
),
);
}
}
return $transcoders;
}
/**
* Implements hook_scald_contexts().
*
* Defines a representation that can be used when an atom reference field
* or views contains both images and files.
*/
function scald_file_scald_contexts() {
$contexts['file_representation'] = array(
'title' => t('File Representation'),
'description' => t('The File Representation'),
'render_language' => 'XHTML',
'parseable' => TRUE,
'formats' => array(
'image' => array(
'passthrough',
),
'file' => array(
'passthrough',
),
),
);
return $contexts;
}
/**
* Implements hook_scald_render().
*
* Renders a representation that can be used when an atom reference field
* or views contains both images and files.
*/
function scald_file_scald_render($atom, $context, $options = array()) {
if ($context == 'file_representation') {
$config = scald_context_config_load($context);
if ('default' != $config->player['file']['*']) {
return $atom->rendered->player;
}
else {
return theme('scald_file_render', array(
'vars' => array(
'context' => $context,
'file_source' => $atom->file_source,
'file_size' => format_size($atom->base_entity->filesize),
'thumbnail_source' => $atom->type == 'image' ? drupal_get_path('module', 'scald_file') . '/icons/image_jpeg2000.png' : $atom->thumbnail_source,
'file_title' => check_plain($atom->title),
),
));
}
}
}
/**
* Implements hook_action_info().
*/
function scald_file_action_info() {
return array(
'scald_file_generate_thumbnail' => array(
'type' => 'scald_atom',
'label' => t('Generate Thumbnail'),
'configurable' => FALSE,
'behavior' => array(
'changes_property',
),
'triggers' => array(
'any',
),
),
);
}
/**
* Action callback for the thumbnail generation action.
*/
function scald_file_generate_thumbnail($entity, $context) {
if ($entity->provider === 'scald_file') {
$entity->data['scald_thumbnail_default'] = TRUE;
scald_atom_save($entity);
}
}
/**
* Determines if a command exists on the current environment.
*
* @param string $command
* The command to check.
*
* @return bool
* True if the command has been found ; otherwise, false.
*
* @codingStandardsIgnoreStart
*
* Source: http://stackoverflow.com/questions/12424787/how-to-check-if-a-shell-command-exists-from-php
*/
function scald_file_command_exists($command) {
$whereIsCommand = PHP_OS == 'WINNT' ? 'where' : 'which';
// @codingStandardsIgnoreEnd
$process = proc_open("{$whereIsCommand} {$command}", array(
// STDIN.
0 => array(
"pipe",
"r",
),
// STDOUT.
1 => array(
"pipe",
"w",
),
// STDERR.
2 => array(
"pipe",
"w",
),
), $pipes);
if ($process !== FALSE) {
$stdout = stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
return $stdout != '';
}
return FALSE;
}
/**
* Determines if exec is available.
*
* Source: http://stackoverflow.com/questions/3938120/check-if-exec-is-disabled.
*/
function scald_file_is_exec_available() {
static $available;
if (!isset($available)) {
$available = TRUE;
if (ini_get('safe_mode')) {
$available = FALSE;
}
else {
$d = ini_get('disable_functions');
$s = ini_get('suhosin.executor.func.blacklist');
if ("{$d}{$s}") {
$array = preg_split('/,\\s*/', "{$d},{$s}");
if (in_array('exec', $array)) {
$available = FALSE;
}
}
}
}
return $available;
}