'emthumb_upload_js',
'page arguments' => array(2, 3, 4),
'access callback' => 'emthumb_edit_access',
'access arguments' => array(3),
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Access callback for the JavaScript upload and deletion AHAH callbacks.
*
* The content_permissions module provides nice fine-grained permissions for
* us to check, so we can make sure that the user may actually edit the file.
*/
function emthumb_edit_access($field_name) {
if (!content_access('edit', content_fields($field_name))) {
return FALSE;
}
// No content permissions to check, so let's fall back to a more general permission.
return user_access('access content');
}
/**
* Implements hook_emfield_field_extra().
* This is called on field operations to allow us to act on emthumbs.
*/
function emthumb_emfield_field_extra($op, &$node, $field, &$items, $teaser, $page, $module) {
switch ($op) {
case 'load':
// Called after content.module loads default data.
$output = array();
if (count($items)) {
$values = array();
foreach ($items as $delta => $file) {
// For some weird reason this is_array() test is required to
// prevent php from segfaulting apache
$existing_data = array();
if (isset($file['data']) && isset($file['data']['emthumb']) && is_array($file['data']['emthumb'])) {
$existing_data = $file['data']['emthumb'];
}
// Merge new file with existing data so we include alt tag data.
$items[$delta]['data']['emthumb'] = array_merge($existing_data, _emthumb_file_load($file['data']['emthumb']['fid']));
}
return array($field['field_name'] => $items);
}
break;
case 'rss item':
// Different from load (and others) as it can be, and is, called within
// each $field individually.
$output = array();
if (count($items)) {
$values = array();
foreach ($items as $delta => $file) {
$thumbnail = _emthumb_file_load($file['data']['emthumb']['fid']);
if (isset($thumbnail['filepath'])) {
$options = array('absolute' => TRUE);
$thumbnail['filepath'] = url($thumbnail['filepath'], $options);
$output[$delta]['thumbnail'] = $thumbnail;
}
}
}
return $output;
case 'validate':
//TODO Implement this validate function
break;
case 'insert':
case 'update':
// Called before content.module defaults.
foreach ($items as $delta => $item) {
if (!$items[$delta]['data']['emthumb'] && $items[$delta]['emthumb']['emthumb']['emthumb']['emthumb']) {
// This will delete the file if the flag is on
_emthumb_file_update($node, $items[$delta]['emthumb']['emthumb']['emthumb']['emthumb']['file'], $field, $items[$delta]['emthumb']['emthumb']['emthumb']['emthumb']['flags']['delete']);
$items[$delta]['data']['emthumb'] = $items[$delta]['emthumb']['emthumb']['emthumb']['emthumb']['file'];
}
if (empty($items[$delta]['data']['emthumb']) && $field['widget']['emthumb_store_local_thumbnail']) { // was: variable_get('emthumb_store_local_thumbnail', TRUE)) {
// Fetch remote thumb because we don't have a custom one.
$items[$delta]['data']['emthumb'] = emthumb_fetch_remote_thumbnail($items[$delta], $field);
}
// Add alt text and alt title if necessary.
if (!empty($items[$delta]['emthumb']['emthumb']['emthumb']['emthumb']['emthumb_alt'])) {
$items[$delta]['data']['emthumb']['emthumb_alt'] = $items[$delta]['emthumb']['emthumb']['emthumb']['emthumb']['emthumb_alt'];
}
if (!empty($items[$delta]['emthumb']['emthumb']['emthumb']['emthumb']['emthumb_title'])) {
$items[$delta]['data']['emthumb']['emthumb_title'] = $items[$delta]['emthumb']['emthumb']['emthumb']['emthumb']['emthumb_title'];
}
if (isset($items[$delta]['emthumb'])) {
// We're saving in the data property so delete emthumb
unset($items[$delta]['emthumb']);
}
}
// Compact deltas.
$items = array_values($items);
break;
case 'delete':
foreach ($items as $delta => $item) {
_emthumb_file_delete($item['data']['emthumb'], $field['field_name']);
}
break;
}
}
/**
* Process our emthumb element.
*/
function emthumb_widget_element_process($element, $edit, &$form_state) {
$field = $element['#field'];
$field_name = $element['#field_name'];
$type_name = $element['#type_name'];
$delta = $element['#delta'];
$upload_op = 'emthumb_'. $field_name . '_' . $delta . '_upload';
$emthumb_element_name = $field_name . '_' . $delta . '_file';
// First grab the file if it's just been uploaded.
$file = _emthumb_file_upload($form_state, $field_name, $field, $delta, $upload_op, TRUE);
// If there is no uploaded file, check the form cache to see if it was
// uploaded earlier, such as from a preview or AHAH.
// @TODO: Doesn't work with AHAH.
if (empty($file) && isset($form_state['storage']) && isset($form_state['storage']['emthumb'][$upload_op])) {
$file = $form_state['storage']['emthumb'][$upload_op];
}
// If we still don't have a file, then use the version from the node.
if (empty($file) && $form_state['values'] && $form_state['values']['nid'] && $node = node_load($form_state['values']['nid'])) {
$field_data = $node->{$field_name}[$delta];
if ($node->$field_name && !empty($field_data['data']['emthumb'])) {
// Get saved file if we have it.
$file = $field_data['data']['emthumb'];
}
}
// Do not display custom thumb stuff if we don't allow a custom thumb.
if ($field['widget']['emthumb']) {
// Separate from tree becase of that silly things won't be
// displayed if they are a child of '#type' = form issue
$element[$emthumb_element_name] = array(
'#type' => 'file',
'#description' => isset($field['widget']['emthumb_description']) ? $field['widget']['emthumb_description'] : t('If you upload a custom thumbnail, then this will be displayed when the @field thumbnail is called for, overriding any automatic thumbnails by custom providers.', array('@field' => $field['widget']['label'])),
'#tree' => FALSE,
'#weight' => 9,
);
$element['emthumb-upload'] = array(
'#type' => 'submit',
'#value' => t('Upload'),
'#name' => $upload_op,
'#attributes' => array('id' => $field_name .'-attach-button'),
'#tree' => FALSE,
'#submit' => array('emthumb_widget_upload_button_submit'),
'#weight' => 10,
'#ahah' => array(
'path' => 'emthumb/js/'. $type_name .'/'. $field_name .'/'. $delta,
'wrapper' => "emthumb-wrapper-$field_name-$delta",
'progress' => array('type' => 'bar', 'message' => t('Please wait...')),
),
// @TODO: Disabled until AHAH is fixed.
'#disabled' => TRUE,
);
$element['emthumb-upload-disabled'] = array(
'#type' => 'item',
'#description' => t('The upload button is disabled until !this is resolved.', array('!this' => l(t('this issue'), 'http://drupal.org/node/802606', array('attributes' => array('target' => '_blank'))))),
'#weight' => 10,
);
}
if (isset($file) && isset($file['filepath'])) {
$element['#title'] = t('Replace');
$element['emthumb'] = array(
'#theme' => 'emthumb_edit_image_row',
);
$element['emthumb']['flags']['delete'] = array(
'#type' => 'checkbox',
'#title' => t('Delete'),
'#description' => t("Checking this field causes the thumbnail to be redownloaded, deleting the current thumbnail."),
'#default_value' => 0,
);
$filename = $file['filepath'];
$element['emthumb']['preview'] = array(
'#type' => 'markup',
'#value' => theme('emthumb_image', $file, $file['emthumb_alt'], $file['emthumb_title'], array('width' => $field['widget']['thumbnail_width'], 'height' => $field['widget']['thumbnail_height']), FALSE),
);
$element['emthumb']['description'] = array(
'#type' => 'markup',
'#value' => ''. t('Filename:') .' '. $file['filename'],
);
// Overwrite with an input field if custom_alt is flagged.
if ($field['widget']['emthumb_custom_alt']) {
$element['emthumb']['emthumb_alt'] = array(
'#type' => 'textfield',
'#title' => t('Alternate text'),
'#default_value' => $file['emthumb_alt'],
'#description' => t('Alternate text to be displayed if the image cannot be displayed.'),
'#maxlength' => 255,
'#size' => 10,
);
}
// Overwrite with an input field if custom_title is flagged.
if ($field['widget']['emthumb_custom_title']) {
$element['emthumb']['emthumb_title'] = array(
'#type' => 'textfield',
'#title' => t('Title'),
'#default_value' => $file['emthumb_title'],
'#description' => t('Text to be displayed on mouse overs.'),
'#maxlength' => 255,
'#size' => 10,
);
}
$element['emthumb']['file'] = array('#type' => 'value', '#value' => $file);
// If this was an uploaded file, we need to save it. Otherwise it will be
// forgotten on node save
$element['emthumb']['replace'] = array(
'#type' => 'markup',
'#value' => $field['widget']['emthumb'] ? t('If a new custom thumbnail is chosen, the current custom thumbnail will be replaced upon submitting the form.') : '',
);
}
else if ($field['widget']['emthumb_store_local_thumbnail']) {
$element['emthumb']['no_current_thumb'] = array(
'#type' => 'markup',
'#value' => t('If possible, a remote thumbnail will be downloaded on the next save.'),
);
if ($field['widget']['emthumb'] && emthumb_edit_access($field_name)) {
$element['emthumb']['no_current_thumb']['#value'] .= ' ' . t("Alternatively, you may specify a custom thumbnail in this field.");
}
}
if (isset($form_state['clicked_button']) && in_array('node_form_submit', $form_state['clicked_button']['#submit']) && isset($form_state['storage']['emthumb'])) {
// Form is being submitted and we want to empty our storage
// so we can redirect to wherever was specified
if (isset($form_state['storage']['emthumb'][$upload_op])) {
unset($form_state['storage']['emthumb'][$upload_op]);
}
if (empty($form_state['storage']['emthumb'])) {
unset($form_state['storage']['emthumb']);
}
}
return $element;
}
function emthumb_widget_upload_button_submit($form, &$form_state) {
$delta = substr($form_state['clicked_button']['#name'], strrpos($form_state['clicked_button']['#name'], '_', -(strlen('_upload')+1)) + 1, -strlen('_upload'));
$field_name = substr($form_state['clicked_button']['#name'], strlen('emthumb_'), -strlen("_{$delta}_upload"));
$field = $form['#field_info'][$field_name];
$upload_op = 'emthumb_'. $field_name . '_' . $delta . '_upload';
_emthumb_file_upload($form_state, $field_name, $field, $delta, $upload_op);
}
function _emthumb_file_upload(&$form_state, $field_name, $field, $delta, $upload_op, $from_process = FALSE) {
$file = array();
$limits = array(
'extensions' => 'jpg jpeg gif png',
'file_size' => 0,
'user_size' => 0,
'resolution' => 0,
);
$validators = array(
'file_validate_extensions' => array($limits['extensions']),
'file_validate_image_resolution' => array($limits['resolution']),
'file_validate_size' => array($limits['file_size'], $limits['user_size']),
);
$filename = $source = $field_name . '_' . $delta . '_file';
if ($file = file_save_upload($filename, $validators, file_create_path($field['widget']['emimport_image_path']), FILE_EXISTS_RENAME)) {
$file = (array)$file;
if (strpos($file['filemime'], 'image') !== FALSE) {
$file = _emthumb_scale_image($file, $field['widget']['emthumb_max_resolution']);
// Store the current file so it's available in a later form_get_cache.
$form_state['storage']['emthumb'][$upload_op] = $file;
}
else {
form_set_error('', t("The file you uploaded was not recognized as an image. Please upload a different image type."));
}
}
else if (!$from_process) {
form_set_error('', t("There was an error uploading your file."));
}
$file = $file ? $file : array();
return $file;
}
/**
* Scales a newly uploaded image to fit the set resolution.
* @param $file
* The file object representing the image.
* @param $resolution
* The width x height of an image, a string in the form of '[w]/[h]',
* such as '640x480'.
* @return
* The file object with the new filesize and path to scaled image.
*/
function _emthumb_scale_image($file, $resolution = 0) {
$info = image_get_info($file['filepath']);
if ($info) {
list($width, $height) = explode('x', $resolution);
if ($width && $height) {
$result = image_scale($file['filepath'], $file['filepath'], $width, $height);
if ($result) {
$file['filesize'] = filesize($file['filepath']);
drupal_set_message(t('The thumbnail was resized to fit within the maximum allowed resolution of %resolution pixels', array('%resolution' => $resolution)));
}
}
}
return $file;
}
/**
* Validate callback for emthumb_widget element.
*/
function emthumb_widget_element_validate($element, $form_state) {
return $element;
}
/**
* Implementation of hook_elements().
*/
function emthumb_elements() {
$elements = array();
$elements['emthumb_widget'] = array(
'#input' => TRUE,
'#process' => array('emthumb_widget_element_process'),
'#element_validate' => array('emthumb_widget_element_validate'),
);
return $elements;
}
/**
* Callback from hook_emfield_widget_extra_file_included()
* In Drupal 6, we need to build multipart/form-data forms manually.
* @returns
* TRUE. This ensures the form will handle files properly in d6.
*/
function emthumb_emfield_widget_extra_file_included() {
return TRUE;
}
/**
* Implements hook_emfield_widget_extra().
*
* This is called by _emfield_emfield_widget (in emfield.cck.inc) when
* building the widget on the node form. It creates a file upload element
* so the editor may upload a new thumbnail to replace the provider default.
*/
function emthumb_emfield_widget_extra($form, $form_state, $field, $items, $delta = 0, $module) {
if (module_exists('devel_themer') && (user_access('access devel theme information') || user_access('access devel information'))) {
drupal_set_message(t('Files may not be uploaded while the Theme Developer tool is enabled. It is highly recommended to disable this module unless it is actively being used.', array('!url' => url('admin/build/modules'))), 'error');
}
$element = array();
// Construct the thumbnail fieldset with the custom label.
// We do not want this fieldset if there are no items
// and the editor can't upload a thumb
if ((!empty($items) && !empty($items[0]['value']) && $field['widget']['emthumb_store_local_thumbnail']) || $field['widget']['emthumb']) {
$field_name = $field['field_name'];
$emthumb_label = isset($field['widget']['emthumb_label']) ? $field['widget']['emthumb_label'] : (isset($field['widget']['label']) ? t('@field custom thumbnail', array('@field' => $field['widget']['label'])) : t('Custom thumbnail'));
$element['emthumb'] = array(
'#type' => 'fieldset',
'#title' => $emthumb_label,
'#collapsible' => TRUE,
'#collapsed' => ($field['widget']['emthumb_start_collapsed']),
'#tree' => TRUE,
// Wrapper for fieldset contents (used by ahah.js).
'#prefix' => '
',
'#suffix' => '
',
);
if (isset($field['widget']['emthumb_weight'])) {
$element['emthumb']['#weight'] = $field['widget']['emthumb_weight'];
}
$element['emthumb']['emthumb'] = array(
'#type' => 'emthumb_widget',
'#title' => $field['widget']['emthumb'] ? t('New upload') : '',
'#field' => $field,
'#field_name' => $field['field_name'],
'#type_name' => $field['type_name'],
'#items' => $items,
'#delta' => $delta,
);
}
return $element;
}
/**
* This provides extra widget settings to emfields.
* A checkbox to allow custom thumbnails, max resolution, image path, allow
* custom alt tags, allow custom title tags.
*/
function emthumb_emfield_widget_settings_extra($op, $widget) {
switch ($op) {
case 'form':
$form = array();
$form['emthumb'] = array(
'#type' => 'fieldset',
'#title' => t('Embedded Custom Thumbnails'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['emthumb']['emthumb_store_local_thumbnail'] = array(
'#type' => 'checkbox',
'#title' => t('Store remote thumbnails for this field'),
'#description' => t('If checked, then remote thumbnails will be stored locally for this field..'),
'#default_value' => isset($widget['emthumb_store_local_thumbnail']) ? $widget['emthumb_store_local_thumbnail'] : TRUE,
);
$form['emthumb']['emthumb'] = array(
'#type' => 'checkbox',
'#title' => t('Allow custom thumbnails for this field'),
'#description' => t('If checked, then editors may specify a custom thumbnail to be used, overriding any automatic thumbnails otherwise created.'),
'#default_value' => isset($widget['emthumb']) ? $widget['emthumb'] : FALSE,
);
$form['emthumb']['emthumb_label'] = array(
'#type' => 'textfield',
'#title' => t('Custom thumbnail label'),
'#default_value' => isset($widget['emthumb_label']) ? $widget['emthumb_label'] : t('@field custom thumbnail', array('@field' => $widget['label'])),
'#description' => t('This label will be displayed when uploading a custom thumbnail.'),
);
$form['emthumb']['emthumb_description'] = array(
'#type' => 'textfield',
'#title' => t('Custom thumbnail description'),
'#default_value' => isset($widget['emthumb_description']) ? $widget['emthumb_description'] : t('If you upload a custom thumbnail, then this will be displayed when the @field thumbnail is called for, overriding any automatic thumbnails by custom providers.', array('@field' => $widget['label'])),
'#description' => t('This description will be displayed when uploading a custom thumbnail.'),
'#maxlength' => 512,
);
$form['emthumb']['emthumb_max_resolution'] = array(
'#type' => 'textfield',
'#title' => t('Maximum resolution for Images'),
'#default_value' => isset($widget['emthumb_max_resolution']) ? $widget['emthumb_max_resolution'] : 0,
'#size' => 15,
'#maxlength' => 10,
'#description' =>
t('The maximum allowed custom thumbnail size expressed as WIDTHxHEIGHT (e.g. 640x480). Set to 0 for no restriction.')
);
$form['emthumb']['emimport_image_path'] = array(
'#type' => 'textfield',
'#title' => t('Image path'),
'#default_value' => isset($widget['emimport_image_path']) ? $widget['emimport_image_path'] : '',
'#description' => t('Optional subdirectory within the "%dir" directory where images will be stored. Do not include trailing slash.', array('%dir' => variable_get('file_directory_path', 'files'))),
'#after_build' => array('emthumb_form_check_directory'),
);
$form['emthumb']['emthumb_custom_alt'] = array(
'#type' => 'checkbox',
'#title' => t('Enable custom alternate text'),
'#default_value' => isset($widget['emthumb_custom_alt']) ? $widget['emthumb_custom_alt'] : 0,
'#description' => t('Enable custom alternate text for custom thumbnails. Filename will be used if not checked.'),
);
$form['emthumb']['emthumb_custom_title'] = array(
'#type' => 'checkbox',
'#title' => t('Enable custom title text'),
'#default_value' => isset($widget['emthumb_custom_title']) ? $widget['emthumb_custom_title'] : 0,
'#description' => t('Enable custom title text for custom thumbnails. Filename will be used if not checked.'),
);
$form['emthumb']['emthumb_start_collapsed'] = array(
'#type' => 'checkbox',
'#title' => t('Default display is collapsed'),
'#default_value' => isset($widget['emthumb_start_collapsed']) ? $widget['emthumb_start_collapsed'] : 0,
'#description' => t('Enable default display to be collapsed.'),
);
return $form;
case 'save':
return array('emthumb', 'emthumb_label', 'emthumb_description', 'emthumb_max_resolution', 'emimport_image_path', 'emthumb_custom_alt', 'emthumb_custom_title', 'emthumb_store_local_thumbnail', 'emthumb_start_collapsed');
}
}
/**
* Wrapper function for emthumb_check_directory that accepts a form element
* to validate - if user specified one. Won't allow form submit unless the
* directory exists & is writable
*
* @param $form_element
* The form element containing the name of the directory to check.
*/
function emthumb_form_check_directory($form_element) {
if (!empty($form_element['#value'])) {
emthumb_check_directory($form_element['#value'], $form_element);
}
return $form_element;
}
/**
* Create the image directory relative to the 'files' dir recursively for every
* directory in the path.
*
* @param $directory
* The directory path under files to check, such as 'photo/path/here'
* @param $form_element
* A form element to throw an error on if the directory is not writable
*/
function emthumb_check_directory($directory, $form_element = array()) {
foreach (explode('/', $directory) as $dir) {
$dirs[] = $dir;
$path = file_create_path(implode($dirs, '/'));
file_check_directory($path, FILE_CREATE_DIRECTORY, $form_element['#parents'][0]);
}
return true;
}
/**
* Insert a file into the database.
* @param $node
* Node object file will be associated with.
* @param $file
* File to be inserted, passed by reference since fid should be attached.
* @TODO: use hook_file
*/
function _emthumb_file_insert($node, &$file, $field) {
$field_name = $field['field_name'];
$filepath = file_create_path($field['widget']['emimport_image_path']) .'/'. $file['filename'];
$file = (object) $file;
$status = file_set_status($file, 1);
if (!$status) {
// Include file name in upload error.
drupal_set_message(t('Thumbnail upload (%filename) was unsuccessful.', array('%filename' => $file['filename'])), 'error');
return FALSE;
}
$file = (array)$file;
}
/**
* update the file record if necessary
* @param $node
* @param $file
* @param $field
*/
function _emthumb_file_update($node, &$file, $field, $delete = FALSE) {
$file = (array)$file;
if ($delete) {
_emthumb_file_delete($file, $field['field_name']);
$file = array();
return array();
}
if (!$file['status']) {
_emthumb_file_insert($node, $file, $field);
return $file;
}
else {
// if fid is not numeric here we should complain.
// else we update the file table.
}
return $file;
}
function _emthumb_file_delete($file, $field_name) {
if (is_numeric($file['fid'])) {
db_query('DELETE FROM {files} WHERE fid = %d', $file['fid']);
}
return file_delete($file['filepath']);
}
function _emthumb_file_load($fid = NULL) {
// Don't bother if we weren't passed an fid.
if (isset($fid)) {
// Test to catch fid, eventual plan to have node_load syntax
// once file_attributes table is complete
if (is_numeric($fid)) {
$result = db_query('SELECT * FROM {files} WHERE fid = %d', $fid);
$file = db_fetch_array($result);
return ($file ? $file : array());
}
}
return array();
}
/**
* Return the custom thumbnail URL for an item.
* @param $item
* The field item.
* @return
* The path to the custom thumbnail file.
*/
function emthumb_thumbnail_path($item) {
if (is_array($item['data']['emthumb']) && $item['data']['emthumb']['filepath']) {
return file_create_path($item['data']['emthumb']['filepath']);
}
}
/**
* Menu callback; Shared AHAH callback for uploads and deletions.
*
* This rebuilds the form element for a particular field item. As long as the
* form processing is properly encapsulated in the widget element the form
* should rebuild correctly using FAPI without the need for additional callbacks
* or processing.
*/
function emthumb_upload_js($type_name, $field_name, $delta) {
$field = content_fields($field_name, $type_name);
if (empty($field) || empty($_POST['form_build_id'])) {
// Invalid request.
drupal_set_message(t('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (@size) that this server supports.', array('@size' => format_size(file_upload_max_size()))), 'error');
print drupal_to_js(array('data' => theme('status_messages')));
exit;
}
// Build the new form.
$form_state = array('submitted' => FALSE);
$form_build_id = $_POST['form_build_id'];
$form = form_get_cache($form_build_id, $form_state);
if (!$form) {
// Invalid form_build_id.
drupal_set_message(t('An unrecoverable error occurred. This form was missing from the server cache. Try reloading the page and submitting again.'), 'error');
print drupal_to_js(array('data' => theme('status_messages')));
exit;
}
// Build the form. This calls the file field's #value_callback function and
// saves the uploaded file. Since this form is already marked as cached
// (the #cache property is TRUE), the cache is updated automatically and we
// don't need to call form_set_cache().
$args = $form['#parameters'];
$form_id = array_shift($args);
$form['#post'] = $_POST;
$form = form_builder($form_id, $form, $form_state);
// Update the cached form with the new element at the right place in the form.
if (module_exists('fieldgroup') && ($group_name = _fieldgroup_field_get_group($type_name, $field_name))) {
if (isset($form['#multigroups']) && isset($form['#multigroups'][$group_name][$field_name])) {
$form_element = $form[$group_name][$delta][$field_name]['emthumb'];
}
else {
$form_element = $form[$group_name][$field_name][$delta]['emthumb'];
}
}
else {
$form_element = $form[$field_name][$delta]['emthumb'];
}
if (isset($form_element['_weight'])) {
unset($form_element['_weight']);
}
$output = drupal_render($form_element);
// AHAH is not being nice to us and doesn't know the "other" button (that is,
// either "Upload" or "Delete") yet. Which in turn causes it not to attach
// AHAH behaviours after replacing the element. So we need to tell it first.
// Loop through the JS settings and find the settings needed for our buttons.
$javascript = drupal_add_js(NULL, NULL);
$emthumb_ahah_settings = array();
if (isset($javascript['setting'])) {
foreach ($javascript['setting'] as $settings) {
if (isset($settings['ahah'])) {
foreach ($settings['ahah'] as $id => $ahah_settings) {
if (strpos($id, 'emthumb-upload') || strpos($id, 'emthumb-remove')) {
$emthumb_ahah_settings[$id] = $ahah_settings;
}
}
}
}
}
// Add the AHAH settings needed for our new buttons.
if (!empty($emthumb_ahah_settings)) {
$output .= '';
}
$output = theme('status_messages') . $output;
// For some reason, file uploads don't like drupal_json() with its manual
// setting of the text/javascript HTTP header. So use this one instead.
$GLOBALS['devel_shutdown'] = FALSE;
print drupal_to_js(array('status' => TRUE, 'data' => $output));
exit;
}
/**
* @legacy
*/
function emthumb_thumbnail_url($item) {
if ($item['data']['emthumb']['filepath']) {
return file_create_url($item['data']['emthumb']['filepath']);
}
}
/**
* This fetches the thumbnail from the remote provider for local storage.
*/
function emthumb_fetch_remote_thumbnail($item, $field) {
// Obviously, only go forward if our item has been parsed for a provider.
if ($item['provider']) {
// Get the URL to the original thumbnail.
$thumbnail = emfield_include_invoke($field['module'], $item['provider'], 'thumbnail', $field, $item, 'thumbnail', NULL, $field['widget']['thumbnail_width'], $field['widget']['thumbnail_height'], array());
// Go forward only if we have a URL to go by.
if ($thumbnail) {
// The new file will be associated with the global user.
global $user;
// Attempt to fetch the thumbnail from the provided URL.
$request = drupal_http_request($thumbnail);
// Only go forward if we actually have an image stream.
if ($image = $request->data) {
// Add in our check of the the file name length.
$validators['file_validate_name_length'] = array();
// Allow for transliteration, which will take unicode data and convert
// it to US-ASCII for better file storage.
if (module_exists('transliteration')) {
// Transliterate our original URL.
$thumbnail = transliteration_get($thumbnail);
}
// We need to account for slashes in the value, such as from hulu.
// Thus we'll convert them to dashes.
// Our new filepath will be in the form of emvideo-youtube-xd3ewke.jpg.
$basename = $field['module'] .'-'. $item['provider'] .'-'. str_replace('/', '-', $item['value']) .'.'. pathinfo($thumbnail, PATHINFO_EXTENSION);
// Get the base Drupal files path.
$directory = file_directory_path();
if ($field['widget']['emimport_image_path']) {
// Add the field's image path here.
$directory .= '/'. $field['widget']['emimport_image_path'];
}
// Create a new filepath from our desired filename.
$filepath = file_create_filename($basename, $directory);
// Begin building file object.
$file = new stdClass();
$file->uid = $user->uid;
// Strip out the query if provided.
$basename_arr = parse_url($basename);
$filepath_arr = parse_url($filepath);
$file->filename = $basename_arr['path'];
$file->filepath = $filepath_arr['path'];
// If we have mimedetect, then do so. Otherwise we make a best guess
// based on the filename.
$file->filemime = module_exists('mimedetect') ? mimedetect_mime($file) : file_get_mimetype($file->filename);
// Rename potentially executable files, to help prevent exploits.
if (preg_match('/\.(php|pl|py|cgi|asp|js)$/i', $file->filename) && (substr($file->filename, -4) != '.txt')) {
$file->filemime = 'text/plain';
$file->filepath .= '.txt';
$file->filename .= '.txt';
}
// If the destination is not provided, or is not writable, then use the
// temporary directory.
if (empty($dest) || file_check_path($dest) === FALSE) {
$dest = file_directory_temp();
}
$file->source = 'emthumb_fetch_remote_thumbnail';
$file->destination = file_destination($file->filepath, $replace);
$file->filesize = strlen($image);
// Call the validation functions.
$errors = array();
foreach ($validators as $function => $args) {
array_unshift($args, $file);
$errors = array_merge($errors, call_user_func_array($function, $args));
}
// Check for validation errors.
if (!empty($errors)) {
$message = t('The selected file %name could not be saved.', array('%name' => $file->filename));
if (count($errors) > 1) {
$message .= '- '. implode('
- ', $errors) .'
';
}
else {
$message .= ' '. array_pop($errors);
}
form_set_error($file->source, $message);
return 0;
}
if (!file_save_data($image, $file->filepath, FILE_EXISTS_RENAME)) {
form_set_error($file->source, t('Thumbnail error. Could not copy provider thumbnail.'));
watchdog('file', 'Upload error. Could not move file %file to destination %destination.', array('%file' => $file->filename, '%destination' => $file->destination));
return 0;
}
// If we made it this far it's safe to record this file in the database.
$file->status = FILE_STATUS_PERMANENT;
$file->timestamp = time();
drupal_write_record('files', $file);
// Let modules add additional properties to the yet barebone file object.
// This uses the future hook_file from d7's API. Not sure if anything
// actually uses this right now, but they might in the future.
foreach (module_implements('file_insert') as $module) {
$function = $module .'_file_insert';
$function($file);
}
return (array)$file;
}
}
}
return array();
}
/**
* *********** THEME FUNCTIONS ***********
*/
/**
* Implementation of hook_theme().
*/
function emthumb_theme() {
$themes = array(
'emthumb_view_image' => array(
'arguments' => array('file' => NULL, 'alt' => '', 'title' => '', 'attributes' => NULL, 'getsize' => TRUE),
),
'emthumb_edit_image_row' => array(
'arguments' => array('element' => NULL),
),
'emthumb_image' => array(
'arguments' => array('file' => NULL, 'alt' => '', 'title' => '', 'attributes' => NULL, 'getsize' => TRUE),
),
'emthumb_multiple' => array(
'arguments' => array('images' => NULL),
),
'emthumb_widget' => array(
'arguments' => array('element' => NULL),
),
);
if (module_exists('imagecache')) {
foreach (imagecache_presets() as $preset) {
$themes['emthumb_formatter_'. $preset['presetname'] .'_default'] = array(
'arguments' => array('element' => NULL),
'function' => 'theme_emthumb_imagecache_formatter_default',
'file' => 'emthumb.theme.inc',
);
$themes['emthumb_formatter_'. $preset['presetname'] .'_linked'] = array(
'arguments' => array('element' => NULL),
'function' => 'theme_emthumb_imagecache_formatter_linked',
'file' => 'emthumb.theme.inc',
);
$themes['emthumb_formatter_'. $preset['presetname'] .'_imagelink'] = array(
'arguments' => array('element' => NULL),
'function' => 'theme_emthumb_imagecache_formatter_imagelink',
'file' => 'emthumb.theme.inc',
);
$themes['emthumb_formatter_'. $preset['presetname'] .'_path'] = array(
'arguments' => array('element' => NULL),
'function' => 'theme_emthumb_imagecache_formatter_path',
'file' => 'emthumb.theme.inc',
);
$themes['emthumb_formatter_'. $preset['presetname'] .'_url'] = array(
'arguments' => array('element' => NULL),
'function' => 'theme_emthumb_imagecache_formatter_url',
'file' => 'emthumb.theme.inc',
);
$themes['emthumb_formatter_'. $preset['presetname'] .'_providerlink'] = array(
'arguments' => array('element' => NULL),
'function' => 'theme_emthumb_imagecache_formatter_provider_link',
'file' => 'emthumb.theme.inc',
);
$themes['emthumb_formatter_'. $preset['presetname'] .'_full'] = array(
'arguments' => array('element' => NULL),
'function' => 'theme_emthumb_imagecache_formatter_full',
'file' => 'emthumb.theme.inc',
);
$themes['emthumb_formatter_'. $preset['presetname'] .'_preview'] = array(
'arguments' => array('element' => NULL),
'function' => 'theme_emthumb_imagecache_formatter_preview',
'file' => 'emthumb.theme.inc',
);
$themes['emthumb_formatter_'. $preset['presetname'] .'_thickbox'] = array(
'arguments' => array('element' => NULL),
'function' => 'theme_emthumb_imagecache_formatter_thickbox',
'file' => 'emthumb.theme.inc',
);
$themes['emthumb_formatter_'. $preset['presetname'] .'_lightbox2'] = array(
'arguments' => array('element' => NULL),
'function' => 'theme_emthumb_imagecache_formatter_lightbox2',
'file' => 'emthumb.theme.inc',
);
$themes['emthumb_formatter_'. $preset['presetname'] .'_shadowbox'] = array(
'arguments' => array('element' => NULL),
'function' => 'theme_emthumb_imagecache_formatter_shadowbox',
'file' => 'emthumb.theme.inc',
);
}
}
return $themes;
}
/**
* Returns the HTML to display a custom thumbnail image.
*/
function theme_emthumb_image($file, $alt = '', $title = '', $attributes = NULL, $getsize = TRUE) {
$file = (array)$file;
$path = file_create_url($file['filepath']);
$alt = empty($alt) ? $file['emthumb_alt'] : $alt;
$title = empty($title) ? $file['emthumb_title'] : $title;
return theme('image', $path, $alt, $title, $attributes, $getsize);
}
/**
* formats an array of images.
* @param images
* array of individually themed images
* @return
* html string
*/
function theme_emthumb_multiple($images) {
return implode("\n", $images);
}
/**
* Returns the image thumbnail.
* @TODO: Is this even being used?
*/
function theme_emthumb_view_image($file, $alt = '', $title = '', $attributes = NULL, $getsize = TRUE) {
return theme('emthumb_image', $file, $alt, $title, $attributes , $getsize);
}
/**
* Theme the emthumb element on the node edit form when there's a custom
* thumbnail already in place.
*/
function theme_emthumb_edit_image_row($element) {
$output = ''. drupal_render($element['preview']) .'
';
$output .= '';
$output .= '
'. drupal_render($element['flags']) .'
';
$output .= '
'. drupal_render($element['description']);
$output .= '
';
$output .= drupal_render($element['emthumb_alt']);
$output .= drupal_render($element['emthumb_title']);
$output .= '
';
$output = ''. $output .'
';
if (isset($element['replace'])) {
$output .= ''. drupal_render($element['replace']) .'
';
}
return $output;
}
/**
* Theme function for the emthumb_widget element.
*/
function theme_emthumb_widget($element) {
return theme('form_element', $element, $element['#children']);
}
/**
* Implementation of hook_field_formatter_info().
*
* imagecache formatters are named as $presetname_$style
* $style is used to determine how the preset should be rendered.
* If you are implementing custom imagecache formatters please treat _ as
* reserved.
*
* @todo: move the linking functionality up to imagefield and clean up the default image
* integration.
*/
function emthumb_field_formatter_info() {
$formatters = array();
if (!module_exists('imagecache')) {
return $formatters;
}
$field_types = array('emvideo', 'emimage', 'emaudio');
foreach (imagecache_presets() as $preset) {
$formatters[$preset['presetname'] .'_default'] = array(
'label' => t('@preset image', array('@preset' => $preset['presetname'])),
'field types' => $field_types,
);
$formatters[$preset['presetname'] .'_linked'] = array(
'label' => t('@preset image linked to node', array('@preset' => $preset['presetname'])),
'field types' => $field_types,
);
$formatters[$preset['presetname'] .'_imagelink'] = array(
'label' => t('@preset image linked to original image', array('@preset' => $preset['presetname'])),
'field types' => $field_types,
);
$formatters[$preset['presetname'] .'_path'] = array(
'label' => t('@preset file path', array('@preset' => $preset['presetname'])),
'field types' => $field_types,
);
$formatters[$preset['presetname'] .'_url'] = array(
'label' => t('@preset URL', array('@preset' => $preset['presetname'])),
'field types' => $field_types,
);
$formatters[$preset['presetname'] .'_providerlink'] = array(
'label' => t('@preset image linked to provider', array('@preset' => $preset['presetname'])),
'field types' => $field_types,
);
$formatters[$preset['presetname'] .'_full'] = array(
'label' => t('@preset image -> Full Size Media', array('@preset' => $preset['presetname'])),
'field types' => $field_types,
);
$formatters[$preset['presetname'] .'_preview'] = array(
'label' => t('@preset image -> Preview Size Media', array('@preset' => $preset['presetname'])),
'field types' => $field_types,
);
// Add thickbox formatter if thickbox module exists.
if (module_exists('thickbox')) {
$formatters[$preset['presetname'] .'_thickbox'] = array(
'label' => t('Thickbox: @preset image -> Full Size Media', array('@preset' => $preset['presetname'])),
'field types' => $field_types,
);
}
if (module_exists('lightbox2')) {
$formatters[$preset['presetname'] .'_lightbox2'] = array(
'label' => t('Lightbox2: @preset image -> Full Size Media', array('@preset' => $preset['presetname'])),
'field types' => $field_types,
);
}
if (module_exists('shadowbox')) {
$formatters[$preset['presetname'] .'_shadowbox'] = array(
'label' => t('Shadowbox: @preset image -> Full Size Media', array('@preset' => $preset['presetname'])),
'field types' => $field_types,
);
}
}
return $formatters;
}