<?php// $Id: teaserthumbnail.module,v 1.5 2009/02/14 04:51:09 hunvreus Exp $/** * @file * A module that allows thumbnail generation for teasers from pictures attached * to the nodes or inserted in their body. *//** * Menu callback; displays the teaserthumbnail module settings page. */function teaserthumbnail_admin_settings() { $form['default_thumbnail_settings'] = array( '#type' => 'fieldset', '#title' => t('Default thumbnail settings'), '#description' => t('These settings will apply to any selected content type but can be overriden by type specific settings.'), ); $presets = imagecache_presets(TRUE); $options = array('' => ''); foreach ($presets as $preset) { $options[$preset['presetname']] = $preset['presetname']; } $form['default_thumbnail_settings']['teaserthumbnail_preset'] = array( '#type' => 'select', '#title' => t('Thumbnail preset'), '#default_value' => variable_get('teaserthumbnail_preset', ''), '#description' => t('An imagecache preset for building the thumbnails.'), '#options' => $options, '#required' => TRUE, ); $form['default_thumbnail_settings']['teaserthumbnail_min_height'] = array( '#type' => 'textfield', '#title' => t('Minimum height'), '#default_value' => variable_get('teaserthumbnail_min_height', ''), '#description' => t('Minimum height a picture should have to be used as a thumbnail.'), '#maxlength' => '50', '#size' => '50', ); $form['default_thumbnail_settings']['teaserthumbnail_min_width'] = array( '#type' => 'textfield', '#title' => t('Minimum width'), '#default_value' => variable_get('teaserthumbnail_min_width', ''), '#description' => t('Minimum width a picture should have to be used as a thumbnail.'), '#maxlength' => '50', '#size' => '50', ); return system_settings_form($form);}/** * Implementation of hook_form_alter(). */function teaserthumbnail_form_alter(&$form, $form_state, $form_id) { if ($form_id == 'node_type_form') { $form['teaserthumbnail'] = array( '#type' => 'fieldset', '#title' => t('Teaser thumbnail'), '#collapsible' => TRUE, '#collapsed' => TRUE, ); $form['teaserthumbnail']['teaserthumbnail'] = array( '#type' => 'radios', '#title' => t('Generate thumbnail'), '#default_value' => variable_get('teaserthumbnail_'. $form['#node_type']->type, 0), '#options' => array(t('Disabled'), t('Enabled')), '#description' => t('Enable to use Teaser Thumbnail functionalities.'), ); $form['teaserthumbnail']['teaserthumbnail_attachment'] = array( '#type' => 'checkbox', '#title' => t('Use attachments'), '#default_value' => variable_get('teaserthumbnail_attachment_'. $form['#node_type']->type, 0), '#description' => t('If checked, the thumbnail may be built from file attachments as well for teasers and RSS feeds (not views fields).'), ); $form['teaserthumbnail']['teaserthumbnail_teaser'] = array( '#type' => 'radios', '#title' => t('Teaser display'), '#default_value' => variable_get('teaserthumbnail_teaser_'. $form['#node_type']->type, 1), '#options' => array(t('Disabled'), t('Before the teaser body.'), t('After the teaser body.')), '#description' => t('Use this setting to display the thumbnail in the teaser. If disabled you can still use the thumbnail in views, templates...'), ); $form['teaserthumbnail']['teaserthumbnail_rss'] = array( '#type' => 'radios', '#title' => t('RSS display'), '#default_value' => variable_get('teaserthumbnail_rss_'. $form['#node_type']->type, 1), '#options' => array(t('Disabled'), t('Before the rss body.'), t('After the rss body.')), '#description' => t('Use this setting to display the thumbnail in the RSS feeds. If disabled you can still use the thumbnail in views, templates...'), ); $form['teaserthumbnail']['teaserthumbnail_link'] = array( '#type' => 'checkbox', '#title' => t('Display thumbnail as link'), '#default_value' => variable_get('teaserthumbnail_link_'. $form['#node_type']->type, 1), '#description' => t('Use this setting to display the thumbnail as a link in teasers and RSS feeds.'), ); $form['teaserthumbnail']['teaserthumbnail_align'] = array( '#type' => 'radios', '#title' => t('Thumbnail alignment'), '#default_value' => variable_get('teaserthumbnail_align_'. $form['#node_type']->type, 0), '#options' => array(t('None'), t('Left'), t('Right')), '#description' => t('This setting will add an "align" attribute to the thumbnail inin teasers and RSS feeds.'), ); $presets = imagecache_presets(TRUE); $options = array('' => ''); foreach ($presets as $preset) { $options[$preset['presetname']] = $preset['presetname']; } $form['teaserthumbnail']['teaserthumbnail_preset'] = array( '#type' => 'select', '#title' => t('Thumbnail preset'), '#default_value' => variable_get('teaserthumbnail_preset_'. $form['#node_type']->type, 0), '#options' => $options, '#description' => t('The Imagecache you want to use to build the thumbnail. If blank, the default preset (define in the settings page) will be used.'), ); $form['teaserthumbnail']['teaserthumbnail_min_height'] = array( '#type' => 'textfield', '#title' => t('Minimum height'), '#default_value' => variable_get('teaserthumbnail_min_height_'. $form['#node_type']->type, ''), '#maxlength' => '50', '#size' => '10', '#description' => t('The minimum height (in px) for a picture to be used as a thumbnail. If blank, the default preset (define in the settings page) will be used.'), ); $form['teaserthumbnail']['teaserthumbnail_min_width'] = array( '#type' => 'textfield', '#title' => t('Minimum width'), '#default_value' => variable_get('teaserthumbnail_min_width'. $form['#node_type']->type, ''), '#maxlength' => '50', '#size' => '10', '#description' => t('The minimum width (in px) for a picture to be used as a thumbnail. If blank, the default preset (define in the settings page) will be used.'), ); }}/** * Implementation of hook_help(). */function teaserthumbnail_help($path, $arg) { switch ($path) { case 'admin/help#teaserthumbnail': return '<p>'. t('The Teaser Thumbnail module allows you to automatically generate thumbnails from pictures from the node content for teasers, RSS feeds and Views.') .'</p>'; }}/** * Implementation of hook_init(). */function teaserthumbnail_init() { // Views support if (module_exists('views')) { include_once drupal_get_path('module', 'teaserthumbnail') .'/teaserthumbnail.views.inc'; }}/** * Implementation of hook_menu(). */function teaserthumbnail_menu() { $items['admin/settings/teaserthumbnail'] = array( 'title' => 'Teaser thumbnail', 'page callback' => 'drupal_get_form', 'page arguments' => array('teaserthumbnail_admin_settings'), 'access arguments' => array('administer site configuration'), 'description' => 'Define thumbnails related settings : size, types, preset.', ); return $items;}/** * Implementation of hook_nodeapi(). */function teaserthumbnail_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) { if (variable_get('teaserthumbnail_'. $node->type, 0)) { switch ($op) { case 'insert': case 'update': _teaserthumbnail_process($node, $node->body); break; case 'delete': _teaserthumbnail_delete_thumb($node); break; case 'load': // We add the thumbnail filepath as an attribute of the node so that we // can use it outside of the teaser (in a listing for ex.) $node->teaserthumbnail = _teaserthumbnail_get_thumbnail_source($node); break; case 'view': if ($a3) { // If we display the thumbnail in the teaser, we use either a very low // or a very high weight for displaying the thumbnail respectively before // or after the teaser body $display = variable_get('teaserthumbnail_teaser_'. $node->type, 1); if ($display) { // Define atrributes $attributes = array('class' => 'teaserthumbnail'); $align = variable_get('teaserthumbnail_align_'. $node->type, 0); if ($align) $attributes['align'] = ($align == 1) ? 'left' : 'right'; // Build the thumbnail $thumbnail = theme('teaserthumbnail_thumbnail', $node, $attributes); if (variable_get('teaserthumbnail_link_'. $node->type, 1)) $thumbnail = l($thumbnail, 'node/'. $node->nid, array('html' => TRUE)); $node->content['teaserthumbnail'] = array( '#value' => $thumbnail, '#weight' => ($display == 1) ? -50 : 50, ); // We then remove media (both flash and pictures) from the teaser $node->content['body']['#value'] = _teaserthumbnail_strip_media($node->content['body']['#value']); } } break; case 'rss item': // If we display the thumbnail in the RSS feed $display = variable_get('teaserthumbnail_rss_'. $node->type, 1); if ($display) { // Define atrributes $attributes = array('class' => 'teaserthumbnail'); $align = variable_get('teaserthumbnail_align_'. $node->type, 0); if ($align) $attributes['align'] = ($align == 1) ? 'left' : 'right'; // Build the thumbnail $thumbnail = theme('teaserthumbnail_thumbnail', $node, $attributes); if (variable_get('teaserthumbnail_link_'. $node->type, 1)) $thumbnail = l($thumbnail, 'node/'. $node->nid, array('html' => TRUE)); // We then remove media (both flash and pictures) from the teaser/body // and append/prepend the thumbnail $node->teaser = ($display == 1) ? $thumbnail . _teaserthumbnail_strip_media($node->teaser) : _teaserthumbnail_strip_media($node->teaser) . $thumbnail; $node->body = ($display == 1) ? $thumbnail . _teaserthumbnail_strip_media($node->body) : _teaserthumbnail_strip_media($node->teaser) . $thumbnail; } break; } }}/** * Implementation of hook_nodeapi(). */function teaserthumbnail_theme() { return array( 'teaserthumbnail_thumbnail' => array( 'arguments' => array('node'), ), );}/** * Output the thumbnail picture */function theme_teaserthumbnail_thumbnail($node, $attributes = NULL) { $thumbnail = $node->teaserthumbnail; // We define if we prepend a thumbnail to the teaser if (!empty($thumbnail)) { $preset = variable_get('teaserthumbnail_preset_'. $node->type, ''); $preset = empty($preset) ? variable_get('teaserthumbnail_preset', '') : $preset ; $thumbnail = theme('imagecache', $preset, $thumbnail, '', '', $attributes); } return $thumbnail;}/** * Delete any thumbnail reference in the db for the specified node. */function _teaserthumbnail_delete_thumb($node) { db_query('DELETE FROM {teaserthumbnail} WHERE nid = %d', $node->nid);}/** * Retrieve all the URL of local pictures in a HTML string (i.e. <img> with a * relative path). */function _teaserthumbnail_get_local_images($text) { //completly rewritten by tech-o-matic global $base_url; $images = array(); preg_match_all("/(img|src)=(\"|')[^\"'>]+/i", $text, $media); //preg_match_all('/<img.*?src="(.+?)"(.*?)>/i', $text, $media); unset($data); $data = preg_replace("/(img|src)(\"|'|=\"|=')(.*)/i","$3", $media[0]); foreach($data as $url) { $info = pathinfo($url); if (isset($info['extension'])) { if (($info['extension'] == 'jpg') || ($info['extension'] == 'jpeg') || ($info['extension'] == 'gif') || ($info['extension'] == 'png')) array_push($images, $url); } } $local_pics = array(); foreach($images as $url){ if ($url != '' && !strstr($url, 'mailto:') && $url[0] != '#' && (!strstr($url, '://') || strstr($url, $base_url)) ) { $local_pics[] = $url; } } return $local_pics;}/** * Retrieve the filepath of the picture used for building the thumbnail */function _teaserthumbnail_get_thumbnail_source($node) { $thumbnail = db_result(db_query("SELECT filepath FROM {teaserthumbnail} WHERE nid = %d", $node->nid)); // We look in the attachments if necessary and if possible if (variable_get('teaserthumbnail_attachment_'. $node->type, 0) && empty($thumbnail) && module_exists('upload')) { $files = upload_load($node); if ($files) { // We retrieve the mininum size for a picture to be considered suitable $min_height = variable_get('teaserthumbnail_min_height_'.$node->type, ''); if (empty($min_height)) $min_height = variable_get('teaserthumbnail_min_height', ''); if (empty($min_height)) $min_height = 0; $min_width = variable_get('teaserthumbnail_min_width_'.$node->type, ''); if (empty($min_width)) $min_width = variable_get('teaserthumbnail_min_width', ''); if (empty($min_width)) $min_width = 0; foreach ($files as $file) { $image_info = image_get_info($file->filepath); // We want a picture with a valid extension if ($image_info && isset($image_info['extension'])) { // We check for minimum width and height if (($image_info['width'] >= $min_width) && ($image_info['height'] >= $min_height)) { $thumbnail = $file->filepath; } } if (!empty($thumbnail)) break; } } } return $thumbnail;}/** * Process a node on submit: find if there is a valid picture for building a * thumbnail and stores a reference to it. */function _teaserthumbnail_process(&$node, $field) { $teaser_prefix = ''; global $base_url; // We retrieve the local pictures $local_pics = _teaserthumbnail_get_local_images($field); if (count($local_pics)) { // We retrieve the mininum size for a picture to be considered suitable $min_height = variable_get('teaserthumbnail_min_height_'.$node->type, ''); if (empty($min_height)) $min_height = variable_get('teaserthumbnail_min_height', ''); if (empty($min_height)) $min_height = 0; $min_width = variable_get('teaserthumbnail_min_width_'.$node->type, ''); if (empty($min_width)) $min_width = variable_get('teaserthumbnail_min_width', ''); if (empty($min_width)) $min_width = 0; // We browse the array until we find a valid local file with the right dimensions $thumb_source = ''; $i = 0; do { // We ensure we have a relative path (we remove the base path from the beginning of the path) $relative_path = $local_pics[$i]; //changed by tech-o-matic if(substr( $relative_path, 0, strlen($base_url.'/')) == $base_url.'/'){ $relative_path = substr($relative_path, strlen($base_url.'/')); }elseif(substr( $relative_path, 0, strlen(base_path())) == base_path()){ $relative_path = substr($relative_path, strlen(base_path())); } // We check that it is a picture $image_info = image_get_info($relative_path); // We want a picture with a valid extension if ($image_info && isset($image_info['extension'])) { // We check for minimum width and height if (($image_info['width'] >= $min_width) && ($image_info['height'] >= $min_height)) { _teaserthumbnail_save_thumb($node, $relative_path, $relative_path); return; } } $i ++; } while (($thumb_source == '') && ($i < count($local_pics))); } else { _teaserthumbnail_delete_thumb($node); }}/** * Save a reference to the picture selected to build the thumbnail in the db. */function _teaserthumbnail_save_thumb($node, $filepath) { watchdog('tt_save', 'save:'.$filepath, array(),WATCHDOG_WARNING); $num_rows = db_result(db_query("SELECT count(*) FROM {teaserthumbnail} WHERE nid = %d", $node->nid)); if ($num_rows) { db_query("UPDATE {teaserthumbnail} SET filepath = '%s' WHERE nid = %d", $filepath, $node->nid); } else { db_query("INSERT INTO {teaserthumbnail} (nid, filepath) VALUES (%d, '%s')", $node->nid, $filepath); }}/** * Remove media (<img> and <object>) from a string. */function _teaserthumbnail_strip_media($string) { // We remove all the pictures from the text $img_pattern = "/<img[^>]+src=\"[^\"]+\"[^>]*>/i"; $string = preg_replace($img_pattern, '', $string); // We now remove the object blocks (video, flash) $object_pattern = "/<object[0-9 a-z_?*=\":\-\/\.#\,<>\\n\\r\\t]+<\/object>/smi"; $text = preg_replace($object_pattern, '', $string); return $string;}