'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 .= ''; } 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; }