# Copyright 2002-2016 Interchange Development Group and others # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. See the LICENSE file for details. UserTag image Order src UserTag image AttrAlias geometry makesize UserTag image AttrAlias resize makesize UserTag image AddAttr UserTag image Version 1.26 UserTag image Routine <{descriptionfields} || $::Variable->{DESCRIPTIONFIELDS} || $Vend::Cfg->{DescriptionField}; @descriptionfields = qw( description ) if ! @descriptionfields; my @imagefields = grep /\S/, split /\s+/, $opt->{imagefields} || $::Variable->{IMAGEFIELDS}; @imagefields = qw( image ) if ! @imagefields; my @imagesuffixes = qw( jpg gif png jpeg ); my $filere = qr/\.\w{2,4}$/; my $absurlre = qr!^(?i:https?)://!; if ($opt->{ui}) { # unless no image dir specified, add locale string my $locale = $Scratch->{mv_locale} ? $Scratch->{mv_locale} : 'en_US'; $imagedir = $::Variable->{UI_IMAGE_DIR} || $Global::Variable->{UI_IMAGE_DIR}; $imagedirsecure = $::Variable->{UI_IMAGE_DIR} || $Global::Variable->{UI_IMAGE_DIR}; for ($imagedir, $imagedirsecure) { if ($_) { $_ .= '/' if substr($_, -1, 1) ne '/'; $_ .= $locale . '/'; } } } else { $imagedir = $Vend::Cfg->{ImageDir}; $imagedirsecure = $Vend::Cfg->{ImageDirSecure} || $imagedir ; } # make sure there's a trailing slash on directories for ($imagedir, $imagedirsecure) { $_ .= '/' if $_ and substr($_, -1, 1) ne '/'; } if (defined $opt->{secure}) { $secure = $opt->{secure} ? 1 : 0; } else { $secure = $CGI::secure; } $imagedircurrent = $secure ? $imagedirsecure : $imagedir; return $imagedircurrent if $opt->{dir_only}; $opt->{getsize} = 1 unless defined $opt->{getsize} or (defined($opt->{height}) and defined($opt->{width})); $opt->{imagesubdir} ||= $::Scratch->{mv_imagesubdir} if defined $::Scratch->{mv_imagesubdir}; $opt->{default} ||= $::Scratch->{mv_imagedefault} if defined $::Scratch->{mv_imagedefault}; if ($opt->{sku}) { $sku = $opt->{sku}; } else { # assume src option is a sku if it doesn't look like a filename if ($src !~ /$filere/) { $sku = $src; undef $src; } } if($opt->{name_only} and $src) { my $ret = $src =~ /$absurlre/ ? $src : "$imagedircurrent$src"; $ret =~ s/%(?!25)/%25/g; return $ret; } if ($src =~ /$absurlre/) { # we have no way to check validity or create/read sizes of full URLs, # so we just assume they're good $image = $src; } else { my @srclist; push @srclist, $src if $src; if ($sku) { # check all products tables for image fields for ( @{$Vend::Cfg->{ProductFiles}} ) { my $db = Vend::Data::database_exists_ref($_) or die "Bad database $_?"; $db = $db->ref(); my $view = $db->row_hash($sku) if $db->record_exists($sku); if (ref $view eq 'HASH') { for (@imagefields) { push @srclist, $view->{$_} if $view->{$_}; } # grab product description for alt attribute unless (defined $opt->{alt}) { for (@descriptionfields) { ($opt->{alt} = $view->{$_}, last) if $view->{$_}; } } } } } push @srclist, $sku if $sku; push @srclist, $opt->{default} if $opt->{default}; if ($opt->{imagesubdir}) { $opt->{imagesubdir} .= '/' unless $opt->{imagesubdir} =~ m:/$:; } my $dr = $::Variable->{DOCROOT}; my $id = $imagedircurrent; $id =~ s:/+$::; $id =~ s:/~[^/]+::; IMAGE_EXISTS: for my $try (@srclist) { ($image = $try, last) if $try =~ /$absurlre/; $try = $opt->{imagesubdir} . $try; my @trylist; if ($try and $try !~ /$filere/) { @trylist = map { "$try.$_" } @imagesuffixes; push @trylist, map { $try . '.' . uc($_) } @imagesuffixes; my %uniq = map { $_ => undef } @trylist; @trylist = sort keys %uniq; } else { @trylist = ($try); } for (@trylist) { if ($id and m{^[^/]}) { if ($opt->{force} or ($dr and -f "$dr$id/$_")) { $image = $_; $path = "$dr$id/$_"; } } elsif (m{^/}) { if ($opt->{force} or ($dr and -f "$dr/$_")) { $image = $_; $path = "$dr/$_"; } } last IMAGE_EXISTS if $image; } } return unless $image; return 1 if $opt->{exists_only}; my $mask; if($opt->{makesize} and $path) { my $dir = $path; $dir =~ s:/([^/]+$)::; my $fn = $1; my $siz = $opt->{makesize}; MOGIT: { # Support complete mogrify -geometry syntax # This matches: AxB, A or xB, followed by 0, 1, or 2 [+-]number # specs, followed by none or one of @!%><. $siz =~ m{^(()|\d+())(x\d+\3|x\d+\2|\3)([+-]\d+){0,2}([@!%><])?$} or do { logError("%s: Unable to make image with bad size '%s'", 'image tag', $siz); last MOGIT; }; (my $siz_path = $siz) =~ s:[^\dx]::g; $dir .= "/$siz_path"; my $newpath = "$dir/$fn"; if(-f $newpath) { if($opt->{check_date}) { my $mod1 = -M $newpath; my $mod2 = -M $path; unless ($mod2 < $mod1) { $image =~ s:(/?)([^/]+$):$1$siz_path/$2:; $path = $newpath; last MOGIT; } } else { $image =~ s:(/?)([^/]+$):$1$siz_path/$2:; $path = $newpath; last MOGIT; } } $mask = umask(02); unless(-d $dir) { File::Path::mkpath($dir); } my $mgkpath = $newpath; my $ext; $mgkpath =~ s/\.(\w+)$/.mgk/ and $ext = $1; File::Copy::copy($path, $newpath) or do { logError("%s: Unable to create image '%s'", 'image tag', $newpath); last MOGIT; }; my $exec = $Global::Variable->{IMAGE_MOGRIFY}; if(! $exec) { my @dirs = split /:/, "/usr/X11R6/bin:$ENV{PATH}"; for(@dirs) { next unless -x "$_/mogrify"; $exec = "$_/mogrify"; $Global::Variable->{IMAGE_MOGRIFY} = $exec; last; } } last MOGIT unless $exec; system qq{$exec -geometry "$siz" '$newpath' >/dev/null 2>/dev/null}; if($?) { logError("%s: Unable to mogrify image '%s'", 'image tag', $newpath); last MOGIT; } if(-f $mgkpath) { rename $mgkpath, $newpath or die "Could not overwrite image with new one!"; } $image =~ s:(/?)([^/]+$):$1$siz_path/$2:; $path = $newpath; } } umask($mask) if defined $mask; if ($opt->{getsize} and $path) { eval { require Image::Size; my ($width, $height) = Image::Size::imgsize($path); $opt->{height} = $height if defined($height) and not exists($opt->{height}); $opt->{width} = $width if defined($width) and not exists($opt->{width}); if ($opt->{size_scratch_prefix}) { Vend::Interpolate::set_tmp($opt->{size_scratch_prefix} . '_' . $_, $opt->{$_}) for qw/width height/; } }; } } $image = $imagedircurrent . $image unless $image =~ /$absurlre/ or substr($image, 0, 1) eq '/'; $image =~ s/%(?!25)/%25/g; return $image if $opt->{src_only}; $opt->{title} = $opt->{alt} if ! defined $opt->{title} and $opt->{alt}; my $opts = ''; for (qw: width height alt title border hspace vspace align valign style class name id :) { if (defined $opt->{$_}) { my $val = $opt->{$_}; $val = HTML::Entities::encode($val) if $val =~ /\W/; $opts .= qq{ $_="$val"}; } } if($opt->{extra}) { $opts .= " $opt->{extra}"; } $image =~ s/"/"/g; return qq{}; } EOR