| 1 |
<?php
|
| 2 |
// $Id: image_filter.module,v 1.27 2009/06/07 14:36:41 raintonr Exp $
|
| 3 |
|
| 4 |
function image_filter_short_tip_translated() {
|
| 5 |
return t(
|
| 6 |
'You may link to images on this site <a href="!explanation-url">using a special syntax</a>',
|
| 7 |
//array('!explanation-url' => url('filter/tips', NULL, 'filter-image_filter-0')));
|
| 8 |
array('!explanation-url' => url('filter/tips')));
|
| 9 |
}
|
| 10 |
|
| 11 |
function image_filter_long_tip_translated() {
|
| 12 |
return t(
|
| 13 |
'<p>You may quickly link to image nodes using a special syntax. Each image code will be replaced by thumbnail linked to full size image node. Syntax:</p>
|
| 14 |
<blockquote><code>[image:<em>node_id</em> align=<em>alignment</em> hspace=<em>n</em> vspace=<em>n</em> border=<em>n</em> size=<em>label</em> width=<em>n</em> height=<em>n</em> nolink=(0|1) class=<em>name</em> style=<em>style-data</em> node=<em>id</em>]</code></blockquote>
|
| 15 |
<p>Every parameter except <em>node_id</em> is optional.</p>
|
| 16 |
<p>Typically, you will specify one of <code>size</code>, <code>width</code>, or <code>height</code>, or none of them. If you use <code>size=<em>label</em></code>, where <em>label</em> is one of the image size labels specified on the image settings page, the size associated with that label will be used. The sizes "thumbnail", "preview", and "original" are always available. If you use <code>width=<em>n</em></code> or <code>height=<em>n</em></code>, the image will be scaled to fit the specified width or height. If you use none of them, the thumbnail image size will be used.</p>
|
| 17 |
<p>If you specify <code>nolink=1</code>, no link will be created to the image node. The default is to create a link to the image.</p>
|
| 18 |
<p>Alternatively, if you specify <code>node=id</code>, a link will be created to the node with the given id.</p>
|
| 19 |
<p>The <code>align</code>, <code>hspace</code>, <code>vspace</code>, <code>border</code>, <code>class</code>, and <code>style</code> parameters set the corresponding attributes in the generated <code>img</code> tag.</p>');
|
| 20 |
}
|
| 21 |
|
| 22 |
function image_filter_help($section = 'admin/help#image_filter') {
|
| 23 |
$output = '';
|
| 24 |
switch ($section) {
|
| 25 |
case 'admin/help#image_filter':
|
| 26 |
$output = t('<p>Sometimes, you want to add an image to another node like a blog entry or a story. You may do this by creating an image node in Drupal for the target image, and then referencing that image in your story, blog, etc. To enable this feature and learn the proper syntax, visit the <a href="!filters">input formats configuration page</a>.</p>', array('!filters' => url('admin/settings/filters')));
|
| 27 |
break;
|
| 28 |
case 'admin/modules#description':
|
| 29 |
$output = t("Allow users to reference images from other nodes.");
|
| 30 |
break;
|
| 31 |
case 'filter#short-tip':
|
| 32 |
return image_filter_short_tip_translated();
|
| 33 |
case 'filter#long-tip':
|
| 34 |
return image_filter_long_tip_translated();
|
| 35 |
}
|
| 36 |
|
| 37 |
return $output;
|
| 38 |
}
|
| 39 |
|
| 40 |
/**
|
| 41 |
* Hook which handles filtering.
|
| 42 |
*/
|
| 43 |
function image_filter_filter($op, $delta = 0, $format = -1, $text = '') {
|
| 44 |
switch ($op) {
|
| 45 |
// case 'no cache':
|
| 46 |
// return TRUE;
|
| 47 |
case 'list':
|
| 48 |
return array(0 => t('Image filter'));
|
| 49 |
case 'description':
|
| 50 |
return t('Allow users to reference images from other nodes.');
|
| 51 |
case 'process':
|
| 52 |
return image_filter_process($text);
|
| 53 |
default:
|
| 54 |
return $text;
|
| 55 |
}
|
| 56 |
}
|
| 57 |
|
| 58 |
/**
|
| 59 |
*
|
| 60 |
*/
|
| 61 |
function image_filter_filter_tips($delta = 0, $format = -1, $long = false) {
|
| 62 |
if ($long) {
|
| 63 |
return image_filter_long_tip_translated();
|
| 64 |
}
|
| 65 |
else {
|
| 66 |
return image_filter_short_tip_translated();
|
| 67 |
}
|
| 68 |
}
|
| 69 |
|
| 70 |
define("IMAGE_FILTER_WORD", 1);
|
| 71 |
define("IMAGE_FILTER_INTEGER", 2);
|
| 72 |
define("IMAGE_FILTER_STRING", 3);
|
| 73 |
|
| 74 |
function image_filter_attr_value($text, $value_type = IMAGE_FILTER_WORD) {
|
| 75 |
// Strip off initial and final quotes.
|
| 76 |
$first = substr($text, 0, 1);
|
| 77 |
if ($first == "\"" || $first == "\'") {
|
| 78 |
if (substr($text, -1, 1) == $first) {
|
| 79 |
$text = substr($text, 1, -1);
|
| 80 |
}
|
| 81 |
}
|
| 82 |
switch ($value_type) {
|
| 83 |
case IMAGE_FILTER_WORD:
|
| 84 |
return preg_replace("/\W/", '', $text);
|
| 85 |
case IMAGE_FILTER_INTEGER:
|
| 86 |
return preg_replace("/\D/", '', $text);
|
| 87 |
default:
|
| 88 |
return check_plain($text);
|
| 89 |
}
|
| 90 |
}
|
| 91 |
|
| 92 |
|
| 93 |
/**
|
| 94 |
* Actually execute filter on given text.
|
| 95 |
*/
|
| 96 |
function image_filter_process($text) {
|
| 97 |
// Find all the image codes and loop over them, replacing each with an img tag.
|
| 98 |
preg_match_all("/\[image:(\d+)(\s*,)?\s*(.*?)\]/i", $text, $matches, PREG_SET_ORDER);
|
| 99 |
foreach ($matches as $match) {
|
| 100 |
|
| 101 |
$args = array();
|
| 102 |
if (strlen($match[2]) > 0) {
|
| 103 |
// Original syntax: [image:NID,align,hspace,vspace,border]
|
| 104 |
$a = preg_replace('/\W/', '', preg_split("/\s*,\s*/", $match[3]));
|
| 105 |
$args['align'] = image_filter_attr_value($a[0], IMAGE_FILTER_WORD);
|
| 106 |
$args['hspace'] = image_filter_attr_value($a[1], IMAGE_FILTER_INTEGER);
|
| 107 |
$args['vspace'] = image_filter_attr_value($a[2], IMAGE_FILTER_INTEGER);
|
| 108 |
$args['border'] = image_filter_attr_value($a[3], IMAGE_FILTER_INTEGER);
|
| 109 |
}
|
| 110 |
else {
|
| 111 |
// New syntax: [image:node_id (left|right|top|middle|bottom|absmiddle|texttop|baseline|align=alignment) hspace=n vspace=n border=n size=label width=n height=n nolink=(0|1) class=name style=style-data node=id]
|
| 112 |
|
| 113 |
// Convert bare alignment 'X' to 'align="X"'.
|
| 114 |
$match[3] = preg_replace("/^(left|right|top|middle|bottom|absmiddle|texttop|baseline)\b/i",
|
| 115 |
"align=\"$1\"", $match[3]);
|
| 116 |
|
| 117 |
preg_match_all("/(\w+)\=(\"[^\"]*\"|\S*)/", $match[3], $a, PREG_SET_ORDER);
|
| 118 |
foreach ($a as $arg) {
|
| 119 |
$args[strtolower($arg[1])] = $arg[2];
|
| 120 |
}
|
| 121 |
}
|
| 122 |
|
| 123 |
$width = image_filter_attr_value($args['width'], IMAGE_FILTER_INTEGER);
|
| 124 |
$height = image_filter_attr_value($args['height'], IMAGE_FILTER_INTEGER);
|
| 125 |
$size = image_filter_attr_value($args['size'], IMAGE_FILTER_WORD);
|
| 126 |
|
| 127 |
$img = NULL;
|
| 128 |
|
| 129 |
// $result = db_query(db_rewrite_sql("SELECT n.nid, n.title, f.filename, f.filepath FROM {files} f, {node} n WHERE n.status = 1 AND f.filemime LIKE 'image/%%' AND f.nid = n.nid AND n.nid = %d" . (strlen($size) != 0 ? " AND f.filename IN ('" . db_escape_string($size) . "','_original')" : '')), $match[1]);
|
| 130 |
/* TODO: handle fieldname and delta for imagefields */
|
| 131 |
$node = node_load($match[1], NULL, TRUE);
|
| 132 |
|
| 133 |
if (empty($node->images)) {
|
| 134 |
/* This is not an image node (as defined by the image.module). */
|
| 135 |
if (module_exists('imagecache') && module_exists('imagefield')) {
|
| 136 |
/* So look for imagefield */
|
| 137 |
$fields = content_fields(NULL, $node->type);
|
| 138 |
foreach ($fields as $field_name => $field) {
|
| 139 |
if ($field['widget']['module'] == 'imagefield') {
|
| 140 |
if (!empty($node->$field_name)) {
|
| 141 |
$node_field = $node->$field_name;
|
| 142 |
$filepath = $node_field[0]['filepath'];
|
| 143 |
$img->filepath = $filepath;
|
| 144 |
|
| 145 |
/* Get requested size */
|
| 146 |
$preset = imagecache_preset_by_name($size);
|
| 147 |
if (empty($preset)) {
|
| 148 |
/* Requested doesn't exits so fetch them all */
|
| 149 |
$request_size = $size;
|
| 150 |
$presets = imagecache_presets();
|
| 151 |
} else {
|
| 152 |
$presets[$preset['presetid']] = $preset;
|
| 153 |
}
|
| 154 |
|
| 155 |
/* Find smallest preset - this will be the named on if that was found */
|
| 156 |
/* TODO: have configurable default */
|
| 157 |
$src = $filepath;
|
| 158 |
foreach ($presets as $preset) {
|
| 159 |
$dst = imagecache_create_path($preset['presetname'], $filepath);
|
| 160 |
imagecache_build_derivative($preset['actions'], $src, $dst);
|
| 161 |
$image = image_get_info($dst);
|
| 162 |
if (empty($width) ||
|
| 163 |
$image ['width'] * $image['height'] < $width * $height) {
|
| 164 |
$size = $preset['presetname'];
|
| 165 |
$width = $image ['width'];
|
| 166 |
$height = $image ['height'];
|
| 167 |
}
|
| 168 |
}
|
| 169 |
|
| 170 |
$img->filename = $size;
|
| 171 |
$img->fileurl = imagecache_create_url($size, $filepath);
|
| 172 |
$img->nid = $node->nid;
|
| 173 |
$img->title = $node->title;
|
| 174 |
|
| 175 |
/* Warn the user if preset wasn't found */
|
| 176 |
if ($size != $request_size && !empty($request_size)) {
|
| 177 |
drupal_set_message(
|
| 178 |
t('Preset %request_size unavailable - using %size.',
|
| 179 |
array('%request_size' => $request_size, '%size' => $size)), 'warning');
|
| 180 |
}
|
| 181 |
}
|
| 182 |
}
|
| 183 |
}
|
| 184 |
}
|
| 185 |
} else {
|
| 186 |
/* Find most appropriate image size*/
|
| 187 |
if ($size == 'original') { $size = '_original'; }
|
| 188 |
if (!$width && !$height && strlen($size) == 0) { $size = 'thumbnail'; }
|
| 189 |
// Loop over the files found for this image and select the best match.
|
| 190 |
foreach($node->images as $key => $img_path) {
|
| 191 |
$i->filepath = $img_path;
|
| 192 |
$i->filename = $key;
|
| 193 |
$i->fileurl = file_create_url($img_path);
|
| 194 |
$i->nid = $node->nid;
|
| 195 |
$i->title = $node->title;
|
| 196 |
$i->size = getimagesize(file_create_path($i->filepath));
|
| 197 |
if (! $img) {
|
| 198 |
$img = $i;
|
| 199 |
}
|
| 200 |
// If we find a match for the desired image size label, take it.
|
| 201 |
if ((strlen($size) != 0) && ($i->filename == $size)) {
|
| 202 |
$img = $i;
|
| 203 |
break;
|
| 204 |
}
|
| 205 |
// If we find a better match for the desired image width or height, tentatively take it.
|
| 206 |
if ($width && $i->size[0] >= $width && $i->size[1] >= $height) {
|
| 207 |
if ($i->size[0] < $img->size[0] || $img->size[0] < $width) {
|
| 208 |
$img = $i;
|
| 209 |
}
|
| 210 |
}
|
| 211 |
if ($height && $i->size[1] >= $height && $i->size[0] >= $width) {
|
| 212 |
if ($i->size[1] < $img->size[1] || $img->size[1] < $height) {
|
| 213 |
$img = $i;
|
| 214 |
}
|
| 215 |
}
|
| 216 |
}
|
| 217 |
}
|
| 218 |
|
| 219 |
// If we found a matching image, replace the image code with an <img> tag.
|
| 220 |
if ($img) {
|
| 221 |
if (! $width && ! $height) {
|
| 222 |
$img->width = $img->size[0];
|
| 223 |
$img->height = $img->size[1];
|
| 224 |
}
|
| 225 |
else if ($width && ! $height) {
|
| 226 |
$img->width = $width;
|
| 227 |
$img->height = round($img->size[1] * $width / $img->size[0]);
|
| 228 |
}
|
| 229 |
else if ($height && ! $width) {
|
| 230 |
$img->height = $height;
|
| 231 |
$img->width = round($img->size[0] * $height / $img->size[1]);
|
| 232 |
}
|
| 233 |
else {
|
| 234 |
$img->width = $width;
|
| 235 |
$img->height = $height;
|
| 236 |
}
|
| 237 |
|
| 238 |
$img->align = image_filter_attr_value($args['align'], IMAGE_FILTER_WORD);
|
| 239 |
$img->hspace = image_filter_attr_value($args['hspace'], IMAGE_FILTER_INTEGER);
|
| 240 |
$img->vspace = image_filter_attr_value($args['vspace'], IMAGE_FILTER_INTEGER);
|
| 241 |
$img->border = image_filter_attr_value($args['border'], IMAGE_FILTER_INTEGER);
|
| 242 |
$img->class = image_filter_attr_value($args['class'], IMAGE_FILTER_WORD);
|
| 243 |
$img->style = image_filter_attr_value($args['style'], IMAGE_FILTER_STRING);
|
| 244 |
$linkid = image_filter_attr_value($args['node'], IMAGE_FILTER_INTEGER);
|
| 245 |
$img->link = $args['nolink']
|
| 246 |
? NULL
|
| 247 |
: ($linkid ? "node/$linkid" : "node/$img->nid");
|
| 248 |
$img->caption = isset($args['caption'])
|
| 249 |
? image_filter_attr_value($args['caption'], IMAGE_FILTER_STRING)
|
| 250 |
: NULL;
|
| 251 |
|
| 252 |
$img_tag = theme("image_inline_img", $img);
|
| 253 |
$text = str_replace($match[0], $img_tag, $text);
|
| 254 |
}
|
| 255 |
}
|
| 256 |
|
| 257 |
return $text;
|
| 258 |
}
|
| 259 |
|
| 260 |
/**
|
| 261 |
* Drupal 6 theme hook to declared themeable links:
|
| 262 |
*/
|
| 263 |
function image_filter_theme() {
|
| 264 |
return array(
|
| 265 |
'image_inline_img' => array(
|
| 266 |
'arguments' => array('img'),
|
| 267 |
),
|
| 268 |
);
|
| 269 |
}
|
| 270 |
|
| 271 |
|
| 272 |
/**
|
| 273 |
* Theme function to render image in a node.
|
| 274 |
* Displays a thumbnail with a link to the image.
|
| 275 |
*/
|
| 276 |
function theme_image_inline_img($img) {
|
| 277 |
drupal_add_css(drupal_get_path('module', 'image_filter') .'/image_filter.css');
|
| 278 |
|
| 279 |
$imgtag = "<img src=\"$img->fileurl\"" .
|
| 280 |
($img->width ? " width=\"$img->width\"" : '') .
|
| 281 |
($img->height ? " height=\"$img->height\"" : '') .
|
| 282 |
($img->align ? " align=\"$img->align\"" : '') .
|
| 283 |
($img->border ? " border=\"$img->border\"" : '') .
|
| 284 |
($img->hspace ? " hspace=\"$img->hspace\"" : '') .
|
| 285 |
($img->vspace ? " vspace=\"$img->vspace\"" : '') .
|
| 286 |
" alt=\"$img->title\"" .
|
| 287 |
" title=\"$img->title\"" .
|
| 288 |
($img->class ? " class=\"$img->class\"" : '') .
|
| 289 |
($img->style ? " style=\"$img->style\"" : '') . " />";
|
| 290 |
if ($img->link) {
|
| 291 |
$imgtag = l($imgtag, $img->link, array( 'html' => TRUE ));
|
| 292 |
}
|
| 293 |
if (isset($img->caption)) {
|
| 294 |
$imgtag = "<div class=\"image_filter\">$imgtag<br />" .
|
| 295 |
"<div class=\"if_caption\">$img->caption</div></div>";
|
| 296 |
}
|
| 297 |
return $imgtag;
|
| 298 |
}
|
| 299 |
|
| 300 |
// Local Variables:
|
| 301 |
// mode: php
|
| 302 |
// indent-tabs-mode: nil
|
| 303 |
// tab-width: 2
|
| 304 |
// c-basic-offset: 2
|
| 305 |
// End:
|
| 306 |
|
| 307 |
?>
|