1 # Copyright 2002-2011 Interchange Development Group and others
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version. See the LICENSE file for details.
8 UserTag image Order src
9 UserTag image AttrAlias geometry makesize
10 UserTag image AttrAlias resize makesize
12 UserTag image Version 1.25
13 UserTag image Routine <<EOR
16 my ($image, $path, $secure, $sku);
17 my ($imagedircurrent, $imagedir, $imagedirsecure);
19 my @descriptionfields = grep /\S/, split /\s+/,
20 $opt->{descriptionfields} || $::Variable->{DESCRIPTIONFIELDS} || $Vend::Cfg->{DescriptionField};
21 @descriptionfields = qw( description ) if ! @descriptionfields;
23 my @imagefields = grep /\S/, split /\s+/,
24 $opt->{imagefields} || $::Variable->{IMAGEFIELDS};
25 @imagefields = qw( image ) if ! @imagefields;
27 my @imagesuffixes = qw( jpg gif png jpeg );
28 my $filere = qr/\.\w{2,4}$/;
29 my $absurlre = qr!^(?i:https?)://!;
32 # unless no image dir specified, add locale string
33 my $locale = $Scratch->{mv_locale} ? $Scratch->{mv_locale} : 'en_US';
34 $imagedir = $::Variable->{UI_IMAGE_DIR}
35 || $Global::Variable->{UI_IMAGE_DIR};
36 $imagedirsecure = $::Variable->{UI_IMAGE_DIR}
37 || $Global::Variable->{UI_IMAGE_DIR};
38 for ($imagedir, $imagedirsecure) {
40 $_ .= '/' if substr($_, -1, 1) ne '/';
45 $imagedir = $Vend::Cfg->{ImageDir};
46 $imagedirsecure = $Vend::Cfg->{ImageDirSecure} || $imagedir ;
49 # make sure there's a trailing slash on directories
50 for ($imagedir, $imagedirsecure) {
51 $_ .= '/' if $_ and substr($_, -1, 1) ne '/';
54 if (defined $opt->{secure}) {
55 $secure = $opt->{secure} ? 1 : 0;
57 $secure = $CGI::secure;
60 $imagedircurrent = $secure ? $imagedirsecure : $imagedir;
62 return $imagedircurrent if $opt->{dir_only};
64 $opt->{getsize} = 1 unless defined $opt->{getsize}
65 or (defined($opt->{height}) and defined($opt->{width}));
66 $opt->{imagesubdir} ||= $::Scratch->{mv_imagesubdir}
67 if defined $::Scratch->{mv_imagesubdir};
68 $opt->{default} ||= $::Scratch->{mv_imagedefault}
69 if defined $::Scratch->{mv_imagedefault};
74 # assume src option is a sku if it doesn't look like a filename
75 if ($src !~ /$filere/) {
81 if($opt->{name_only} and $src) {
82 my $ret = $src =~ /$absurlre/ ? $src : "$imagedircurrent$src";
83 $ret =~ s/%(?!25)/%25/g;
87 if ($src =~ /$absurlre/) {
88 # we have no way to check validity or create/read sizes of full URLs,
89 # so we just assume they're good
94 push @srclist, $src if $src;
96 # check all products tables for image fields
97 for ( @{$Vend::Cfg->{ProductFiles}} ) {
98 my $db = Vend::Data::database_exists_ref($_)
99 or die "Bad database $_?";
101 my $view = $db->row_hash($sku)
102 if $db->record_exists($sku);
103 if (ref $view eq 'HASH') {
105 push @srclist, $view->{$_} if $view->{$_};
107 # grab product description for alt attribute
108 unless (defined $opt->{alt}) {
109 for (@descriptionfields) {
110 ($opt->{alt} = $view->{$_}, last)
117 push @srclist, $sku if $sku;
118 push @srclist, $opt->{default} if $opt->{default};
120 if ($opt->{imagesubdir}) {
121 $opt->{imagesubdir} .= '/' unless $opt->{imagesubdir} =~ m:/$:;
123 my $dr = $::Variable->{DOCROOT};
124 my $id = $imagedircurrent;
129 for my $try (@srclist) {
130 ($image = $try, last) if $try =~ /$absurlre/;
131 $try = $opt->{imagesubdir} . $try;
133 if ($try and $try !~ /$filere/) {
134 @trylist = map { "$try.$_" } @imagesuffixes;
139 if ($id and m{^[^/]}) {
140 if ($opt->{force} or ($dr and -f "$dr$id/$_")) {
145 if ($opt->{force} or ($dr and -f "$dr/$_")) {
150 last IMAGE_EXISTS if $image;
154 return unless $image;
155 return 1 if $opt->{exists_only};
159 if($opt->{makesize} and $path) {
161 $dir =~ s:/([^/]+$)::;
163 my $siz = $opt->{makesize};
165 # Support complete mogrify -geometry syntax
166 # This matches: AxB, A or xB, followed by 0, 1, or 2 [+-]number
167 # specs, followed by none or one of @!%><.
168 $siz =~ m{^(()|\d+())(x\d+\3|x\d+\2|\3)([+-]\d+){0,2}([@!%><])?$}
170 logError("%s: Unable to make image with bad size '%s'", 'image tag', $siz);
174 (my $siz_path = $siz) =~ s:[^\dx]::g;
175 $dir .= "/$siz_path";
177 my $newpath = "$dir/$fn";
179 if($opt->{check_date}) {
180 my $mod1 = -M $newpath;
182 unless ($mod2 < $mod1) {
183 $image =~ s:(/?)([^/]+$):$1$siz_path/$2:;
189 $image =~ s:(/?)([^/]+$):$1$siz_path/$2:;
198 File::Path::mkpath($dir);
201 my $mgkpath = $newpath;
203 $mgkpath =~ s/\.(\w+)$/.mgk/
206 File::Copy::copy($path, $newpath)
208 logError("%s: Unable to create image '%s'", 'image tag', $newpath);
211 my $exec = $Global::Variable->{IMAGE_MOGRIFY};
213 my @dirs = split /:/, "/usr/X11R6/bin:$ENV{PATH}";
215 next unless -x "$_/mogrify";
216 $exec = "$_/mogrify";
217 $Global::Variable->{IMAGE_MOGRIFY} = $exec;
221 last MOGIT unless $exec;
222 system qq{$exec -geometry "$siz" '$newpath'};
224 logError("%s: Unable to mogrify image '%s'", 'image tag', $newpath);
229 rename $mgkpath, $newpath
230 or die "Could not overwrite image with new one!";
232 $image =~ s:(/?)([^/]+$):$1$siz_path/$2:;
237 umask($mask) if defined $mask;
239 if ($opt->{getsize} and $path) {
242 my ($width, $height) = Image::Size::imgsize($path);
243 $opt->{height} = $height
244 if defined($height) and not exists($opt->{height});
245 $opt->{width} = $width
246 if defined($width) and not exists($opt->{width});
247 if ($opt->{size_scratch_prefix}) {
248 Vend::Interpolate::set_tmp($opt->{size_scratch_prefix} . '_' . $_, $opt->{$_})
249 for qw/width height/;
255 $image = $imagedircurrent . $image unless
256 $image =~ /$absurlre/ or substr($image, 0, 1) eq '/';
258 $image =~ s/%(?!25)/%25/g;
259 return $image if $opt->{src_only};
261 $opt->{title} = $opt->{alt} if ! defined $opt->{title} and $opt->{alt};
264 for (qw: width height alt title border hspace vspace align valign style class name id :) {
265 if (defined $opt->{$_}) {
266 my $val = $opt->{$_};
267 $val = HTML::Entities::encode($val) if $val =~ /\W/;
268 $opts .= qq{ $_="$val"};
272 $opts .= " $opt->{extra}";
274 $image =~ s/"/"/g;
275 return qq{<img src="$image"$opts$Vend::Xtrailer>};