File Coverage

blib/lib/Labyrinth/Plugin/Album/Pages.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             package Labyrinth::Plugin::Album::Pages;
2              
3 1     1   5357 use strict;
  1         1  
  1         38  
4 1     1   4 use warnings;
  1         2  
  1         73  
5              
6             our $VERSION = '1.10';
7              
8             =head1 NAME
9              
10             Labyrinth::Plugin::Album::Pages - Photo album pages handler for Labyrinth
11              
12             =head1 DESCRIPTION
13              
14             Contains all the photo album handling functionality for the Labyrinth
15             framework.
16              
17             =cut
18              
19             #----------------------------------------------------------------------------
20             # Libraries
21              
22 1     1   8 use base qw(Labyrinth::Plugin::Base);
  1         2  
  1         472  
23              
24             use File::Path;
25              
26             use Labyrinth::Audit;
27             use Labyrinth::DBUtils;
28             use Labyrinth::DTUtils;
29             use Labyrinth::Media;
30             use Labyrinth::Metadata;
31             use Labyrinth::MLUtils;
32             use Labyrinth::Support;
33             use Labyrinth::Variables;
34              
35             use Labyrinth::Plugin::Hits;
36              
37             # -------------------------------------
38             # Constants
39              
40             use constant MaxPhotoWidth => 1024;
41             use constant MaxPhotoHeight => 1024;
42             use constant MaxThumbWidth => 200;
43             use constant MaxThumbHeight => 200;
44              
45             #----------------------------------------------------------------------------
46             # Variables
47              
48             # type: 0 = optional, 1 = mandatory
49             # html: 0 = none, 1 = text, 2 = textarea
50              
51             my %fields = (
52             title => { type => 1, html => 1 },
53             summary => { type => 0, html => 2 },
54             area => { type => 0, html => 1 },
55             year => { type => 0, html => 1 },
56             month => { type => 0, html => 1 },
57             pageid => { type => 0, html => 1 },
58             parent => { type => 0, html => 1 },
59             hide => { type => 0, html => 1 },
60             );
61              
62             my (@mandatory,@allfields);
63             for(keys %fields) {
64             push @mandatory, $_ if($fields{$_}->{type});
65             push @allfields, $_;
66             }
67              
68             my @savefields = qw(parent title summary year month hide pageid);
69             my @addfields = qw(parent title summary year month hide area path);
70              
71             my $INDEXKEY = 'pageid';
72             my $LEVEL = PUBLISHER;
73              
74             my $hits = Labyrinth::Plugin::Hits->new();
75              
76             #----------------------------------------------------------------------------
77             # Public Interface Functions
78              
79             =head1 PUBLIC INTERFACE METHODS
80              
81             =head2 Public Methods
82              
83             =over 4
84              
85             =item List
86              
87             Provides a list of all the public photo albums.
88              
89             =item Children
90              
91             Provides a list of photo albums for which the specified photo album is their
92             parent.
93              
94             =item Search
95              
96             Search for photo albums matching a given set of metadata.
97              
98             =back
99              
100             =cut
101              
102             sub List {
103             my ($key,@args);
104              
105             my $now = time() - 2419200; # seconds in a 4 week month
106              
107             my ($where,@where);
108             if($cgiparams{all}) {
109             $key = 'SearchPages';
110             } elsif($cgiparams{latest}) {
111             $key = 'SearchPagesLatest';
112             } elsif($cgiparams{month} || $cgiparams{year} || $cgiparams{metadata}) {
113             push @where, "p.month=$cgiparams{month}" if($cgiparams{month});
114             push @where, "p.year=$cgiparams{year}" if($cgiparams{year});
115             push @where, "p.title='%$cgiparams{metadata}%'" if($cgiparams{metadata});
116             $key = 'SearchPages';
117             } else {
118             $cgiparams{year} = formatDate(1);
119             push @where, "p.year=$cgiparams{year}";
120             $key = 'SearchPages';
121             }
122              
123             $where = ' AND ' . join(' AND ',@where) if(@where);
124              
125             my @rs = $dbi->GetQuery('hash',$key,{where=>$where});
126             for my $rec (@rs) {
127             $rec->{month} = isMonth($rec->{month});
128             $rec->{new} = ($rec->{now} > $now ? 1 : 0);
129             #LogDebug( "$now < $rec->{now} = ".localtime($rec->{now})) if($rec->{new});
130             for(keys %fields) {
131             if($fields{$_}->{html} == 1) { $rec->{$_} = CleanHTML($rec->{$_}); }
132             elsif($fields{$_}->{html} == 2) { $rec->{$_} = CleanTags($rec->{$_}); }
133             }
134              
135             my $dw = $settings{gallerythumbwidth} || MaxThumbWidth;
136             my $dh = $settings{gallerythumbheight} || MaxThumbHeight;
137              
138             if($rec->{dimensions}) {
139             my ($w,$h) = split('x',$rec->{dimensions});
140             if($w/$dw > $h/$dh) {
141             $rec->{width} = $dw;
142             } else {
143             $rec->{height} = $dh;
144             }
145             }
146             }
147              
148             $tvars{records} = \@rs if(@rs);
149             $tvars{month} = $cgiparams{month} || '';
150             $tvars{year} = $cgiparams{year} || '';
151             $tvars{ddmonths} = MonthSelect($cgiparams{month},1);
152             $tvars{ddyears} = YearSelect($cgiparams{year},2,1);
153             $tvars{pid} = 4;
154             $tvars{iid} = 0;
155             }
156              
157             sub Children {
158             $cgiparams{'pageid'} ||= $cgiparams{'pid'};
159             my @rs = $dbi->GetQuery('hash','GetChildPages',$cgiparams{pageid});
160             $tvars{album}{children} = \@rs if(@rs);
161             }
162              
163             sub Search {
164             my $limit = $settings{limit};
165              
166             my $now = time() - 2419200; # seconds in a 4 week month
167             my @rs;
168              
169             if($cgiparams{metadata}) {
170             my @data = split(qr/[ ,]+/,$cgiparams{metadata});
171             @rs = MetaSearch( 'keys' => ['PagePhoto','Photo'],
172             'meta' => \@data,
173             'where' => "hide=0",
174             'limit' => ($limit || ''));
175             for my $rec (@rs) {
176             $rec->{month} = isMonth($rec->{month});
177             $rec->{new} = ($rec->{now} > $now ? 1 : 0);
178             #LogDebug( "$now < $rec->{now} = ".localtime($rec->{now})) if($rec->{new});
179             for(keys %fields) {
180             if($fields{$_}->{html} == 1) { $rec->{$_} = CleanHTML($rec->{$_}); }
181             elsif($fields{$_}->{html} == 2) { $rec->{$_} = SafeHTML($rec->{$_}); }
182             }
183             }
184             }
185              
186             $tvars{records} = \@rs if(@rs);
187             $tvars{month} = $cgiparams{month} || '';
188             $tvars{year} = $cgiparams{year} || '';
189             $tvars{ddmonths} = MonthSelect($cgiparams{month},1);
190             $tvars{ddyears} = YearSelect($cgiparams{year},2,1);
191             $tvars{pid} = 4;
192             $tvars{iid} = 0;
193             }
194              
195             #----------------------------------------------------------------------------
196             # Administration Interface Functions
197              
198             =head1 ADMIN INTERFACE METHODS
199              
200             =head2 Administration Methods
201              
202             =over 4
203              
204             =item Admin
205              
206             Provides a list of all the current photo albums, with additional administrator
207             functions.
208              
209             =item Add
210              
211             Prep for adding a photo album.
212              
213             =item ArchiveEdit
214              
215             Delete archived photos or Move photos to public albums.
216              
217             =item Edit
218              
219             Edit details of a photo album.
220              
221             =item Save
222              
223             Save the details of a photo album.
224              
225             =item Delete
226              
227             Delete a public album, moving all photos to the archive album.
228              
229             =item PageSelect
230              
231             Provides a HTML drop-down list of available pages.
232              
233             =item Selection
234              
235             Shortcut to PageSelect, automatically selecting the current album.
236              
237             =back
238              
239             =cut
240              
241             sub Admin {
242             return unless AccessUser($LEVEL);
243              
244             my (%current,$where,@rs);
245             if($cgiparams{doaction} || $cgiparams{order}) {
246             $where = '';
247             if($cgiparams{was}) {
248             my @was;
249             my ($this,$that) = split("/",$cgiparams{was});
250             push @was, "month=$cgiparams{month}" if($this);
251             push @was, "year=$cgiparams{year}" if($that);
252             $where = 'WHERE ' . join(' AND ',@was) if(@was);
253             }
254              
255             @rs = $dbi->GetQuery('hash','AdminPages',{where=>$where});
256             $current{$_->{pageid}} = $_ for(@rs);
257             }
258              
259             if($cgiparams{doaction}) {
260             if($cgiparams{doaction} eq 'Update') {
261              
262             # check whether we need to hide/show any pages
263             my @ids = CGIArray('HIDE');
264             my %hide = map {$_ => 1} @ids;
265             my @show;
266             my $where = '';
267              
268             for(keys %hide) {
269             if($current{$_}->{hide}) { delete $current{$_}; delete $hide{$_}; }
270             }
271             for(keys %current) {
272             if($current{$_}->{hide}) { push @show, $_; }
273             }
274              
275             $dbi->DoQuery('HidePages',{list=>join(",",keys %hide)}) if(keys %hide);
276             $dbi->DoQuery('ShowPages',{list=>join(",",@show)}) if(@show);
277             $hits->SetUpdates('album',0,@show) if(@show);
278             }
279             }
280              
281             # reorder a specific page
282             if($cgiparams{'order'} && $cgiparams{'pageid'}) {
283             my $order = $cgiparams{'order'};
284             my $pageid = $cgiparams{'pageid'};
285             my (@was,%order,%pages) = ();
286              
287             push @was, "month=$current{$pageid}->{month}";
288             push @was, "year=$current{$pageid}->{year}";
289             $where = 'WHERE ' . join(' AND ',@was);
290             @rs = $dbi->GetQuery('hash','AdminPages',{where=>$where});
291             if(@rs > 1) {
292             my $max = my $inx = @rs;
293             for(@rs) {
294             $order{$inx} = $_->{pageid};
295             $pages{$_->{pageid}} = $inx--;
296             }
297              
298             my $changed = 0;
299             if($order =~ /up/i) {
300             # LogDebug("max=$inx, this=$pages{$pageid}");
301             if($pages{$pageid} < $max) {
302             $inx = $pages{$pageid};
303             $order{$inx} = $order{$inx + 1};
304             $order{$inx + 1} = $pageid;
305             $changed = 1;
306             }
307             } else {
308             if($pages{$pageid} > 1) {
309             $inx = $pages{$pageid};
310             $order{$inx} = $order{$inx - 1};
311             $order{$inx - 1} = $pageid;
312             $changed = 1;
313             }
314             }
315              
316             if($changed) {
317             $dbi->DoQuery('ReorderPage',$_,$order{$_}) for(keys %order);
318             }
319             }
320             }
321              
322             # now show the latest settings :)
323             $where = '';
324             my @where;
325             push @where, "month=$cgiparams{month}" if($cgiparams{month});
326             push @where, "year=$cgiparams{year}" if($cgiparams{year});
327             $where = 'WHERE ' . join(' AND ',@where) if(@where);
328              
329             @rs = $dbi->GetQuery('hash','AdminPages',{where=>$where});
330             foreach my $rec (@rs) {
331             $rec->{year} = '-' unless($rec->{year});
332             $rec->{month} = isMonth($rec->{month});
333             for(keys %fields) {
334             if($fields{$_}->{html} == 1) { $rec->{$_} = CleanHTML($rec->{$_}); }
335             elsif($fields{$_}->{html} == 2) { $rec->{$_} = CleanTags($rec->{$_}); }
336             }
337             }
338              
339             $tvars{month} = $cgiparams{month} || '';
340             $tvars{year} = $cgiparams{year} || '';
341              
342             $tvars{ddmonths} = MonthSelect($cgiparams{month},1);
343             $tvars{ddyears} = YearSelect($cgiparams{year},2,1);
344             $tvars{records} = \@rs if(@rs);
345             }
346              
347             sub Add {
348             return unless AccessUser($LEVEL);
349              
350             $tvars{data}->{senarios} = [
351             { id=>2, title=>'Photos Section' },
352             ];
353              
354             $tvars{data}->{ddmonths} = MonthSelect($tvars{data}->{month});
355             $tvars{data}->{ddyears} = YearSelect($tvars{data}->{year},2);
356             }
357              
358             sub ArchiveEdit {
359             return unless AccessUser($LEVEL);
360              
361             if($cgiparams{doaction}) {
362             my @ids = CGIArray('LISTED');
363              
364             if($cgiparams{doaction} eq 'Delete') {
365             for my $id (@ids) {
366             my @rows = $dbi->GetQuery('hash','GetPhotoByID',$id);
367             unlink "$settings{webdir}/photos/".$rows[0]->{image};
368             unlink "$settings{webdir}/photos/".$rows[0]->{thumb};
369             }
370              
371             $dbi->DoQuery('DeletePhotos',1,{ids=>join(',',@ids)});
372              
373             } elsif($cgiparams{doaction} eq 'Move') {
374             $cgiparams{'pageid'} ||= 1;
375             $dbi->DoQuery('MovePhotos',{ids=>join(',',@ids)},$cgiparams{'pageid'}) if(@ids);
376             }
377             }
378              
379             $cgiparams{'pageid'} = 1;
380             }
381              
382             sub Edit {
383             return unless AccessUser($LEVEL);
384              
385             my $order = $cgiparams{'order'};
386             my $pageid = $cgiparams{'pageid'};
387             my $photoid = $cgiparams{'photoid'};
388             my ($sql,@rs);
389              
390             if($order && $photoid) {
391             @rs = $dbi->GetQuery('hash','GetPhotosInOrder',$pageid);
392             my ($old,$cnt) = (-1,-1);
393             foreach (@rs) {
394             $cnt++;
395             if($_->{photoid} == $photoid) {
396             $old = $cnt;
397             last;
398             }
399             }
400              
401             my $max = @rs;
402             if($old >= 0) {
403             my $new = $old;
404             if($order eq 'up' && $old > 0) { $new--; }
405             elsif($order eq 'down' && $old < $max) { $new++; }
406              
407             if($old != $new) {
408             $dbi->DoQuery('ReorderPhoto',$rs[$old]->{orderno},$rs[$new]->{photoid});
409             $dbi->DoQuery('ReorderPhoto',$rs[$new]->{orderno},$rs[$old]->{photoid});
410             }
411             }
412             }
413              
414             @rs = $dbi->GetQuery('hash','GetPage',$pageid);
415             if(@rs) {
416             for(keys %fields) {
417             if($fields{$_}->{html} == 1) { $rs[0]->{$_} = CleanHTML($rs[0]->{$_}) }
418             elsif($fields{$_}->{html} == 2) { $rs[0]->{$_} = SafeHTML($rs[0]->{$_}) }
419             elsif($fields{$_}->{html} == 3) { $rs[0]->{$_} = SafeHTML($rs[0]->{$_}) }
420             }
421              
422             # $rs[0]->{title} =~ s/'/\'/g if $rs[0]->{title};
423             # $rs[0]->{summary} =~ s/'/\'/g if $rs[0]->{summary};
424             $tvars{data} = $rs[0];
425              
426             @rs = $dbi->GetQuery('hash','GetPhotosInOrder',$pageid);
427             foreach my $rec (@rs) {
428             $rec->{tagline} =~ s/'/\'/g if $rec->{tagline};
429             $rec->{metadata} = MetaGet($rec->{photoid},'Photo');
430             }
431              
432             $tvars{photos} = \@rs if(@rs);
433             }
434              
435             $tvars{data}->{ddmonths} = MonthSelect($tvars{data}->{month});
436             $tvars{data}->{ddyears} = YearSelect($tvars{data}->{year},2);
437             $tvars{data}->{ddpages} = PageSelect(undef,1,'parent',$tvars{data}->{pageid});
438              
439             # check we have an accessible directory to store photos
440             if($tvars{data}->{path}) {
441             $settings{webdir} ||= '';
442             my $dir = "$settings{webdir}/$tvars{data}->{path}";
443             $tvars{data}->{exists} = -e "$settings{webdir}/$tvars{data}->{path}" ? 1 : 0;
444             $tvars{data}->{directory} = -d "$settings{webdir}/$tvars{data}->{path}" ? 1 : 0;
445             $tvars{data}->{readable} = -r "$settings{webdir}/$tvars{data}->{path}" ? 1 : 0;
446             $tvars{data}->{writeable} = -w "$settings{webdir}/$tvars{data}->{path}" ? 1 : 0;
447             $tvars{data}->{executable} = -x "$settings{webdir}/$tvars{data}->{path}" ? 1 : 0;
448             } else {
449             $tvars{data}->{$_} = 0 for(qw(exists directory readable writeable executable));
450             }
451              
452             # default image sizes
453             $tvars{dimensions}->{photowidth} = $settings{maxphotowidth} || MaxPhotoWidth;
454             $tvars{dimensions}->{photoheight} = $settings{maxphotoheight} || MaxPhotoHeight;
455             $tvars{dimensions}->{thumbwidth} = $settings{maxthumbwidth} || MaxThumbWidth;
456             $tvars{dimensions}->{thumbheight} = $settings{maxthumbheight} || MaxThumbHeight;
457              
458             $tvars{timestamp} = formatDate(0);
459             }
460              
461             sub Save {
462             return unless AccessUser($LEVEL);
463             return unless AuthorCheck('GetPage','pageid',$LEVEL);
464              
465             for(keys %fields) {
466             if($fields{$_}->{html} == 1) { $cgiparams{$_} = CleanHTML($cgiparams{$_}) }
467             elsif($fields{$_}->{html} == 2) { $cgiparams{$_} = CleanTags($cgiparams{$_}) }
468             elsif($fields{$_}->{html} == 3) { $cgiparams{$_} = CleanLink($cgiparams{$_}) }
469             }
470              
471             return if FieldCheck(\@allfields,\@mandatory);
472              
473             my (undef,$month,$year) = split("/",formatDate(3));
474             $tvars{data}->{year} ||= $year;
475             $tvars{data}->{month} ||= $month;
476              
477             # only create the path when a new page is created
478             unless($tvars{data}->{pageid}) {
479             $tvars{data}->{path} = 'photos/' . formatDate(11);
480             my $path = $settings{webdir} . '/' . $tvars{data}->{path};
481             mkpath($path);
482             }
483              
484             $tvars{data}->{parent} ||= 0; # no parent by default
485             $tvars{data}->{area} ||= 2; # photo album
486             $tvars{data}->{hide} = $tvars{data}->{hide} ? 1 : 0; # visible by default
487             my @columns = $tvars{data}->{pageid} ? @savefields : @addfields;
488             my @fields = map {(defined $tvars{data}->{$_} ? $tvars{data}->{$_} : undef)} @columns;
489             #LogDebug("columns=[@columns], fields=[@fields]");
490             if($tvars{data}->{pageid})
491             { $dbi->DoQuery('UpdatePage',@fields) }
492             else {$tvars{data}->{pageid} = $dbi->IDQuery('InsertPage',@fields) }
493              
494             $cgiparams{pageid} = $tvars{data}->{pageid};
495             $hits->SetUpdates('album',0,$tvars{data}->{pageid});
496             $tvars{thanks_message} = 'Page saved successfully.';
497             return unless($tvars{data}->{pageid});
498              
499             # archive unwanted photos
500             my @ids = grep { /^\d+$/ } CGIArray('DELETE');
501             # LogDebug("Delete IDs: @ids");
502             if(@ids) {
503             if($cgiparams{pageid} == 1) {
504             # only delete photos in the archive
505             my @rows = $dbi->GetQuery('hash','CheckPhotos',{ids => join(',',@ids)},1);
506             for(@rows) {
507             my @photo = $dbi->GetQuery('hash','CheckPhoto',1,$_->{photoid});
508             if(@photo && $photo[0]->{count} == 1) { # only delete if no others match
509             DeleteFile( file => "$settings{webdir}/photos/$_->{image}" );
510             DeleteFile( file => "$settings{webdir}/photos/$_->{thumb}" );
511             }
512             $dbi->DoQuery('DeletePhoto',$_->{photoid});
513             }
514             } else {
515             $dbi->DoQuery('MovePhotos',{ids => join(',',@ids)},1) if(@ids);
516             }
517             }
518              
519             # get fresh list
520             my @rs = $dbi->GetQuery('hash','GetPhotosInOrder',$tvars{data}->{pageid});
521              
522             # store hidden photos
523             @ids = CGIArray('HIDE');
524             my %hidden = map {$_ => 1} @ids;
525              
526             # update tags, order and metadata
527             my $order = 1;
528             foreach my $rec (@rs) {
529             my $id = $rec->{photoid};
530             my $tag = defined $cgiparams{"TAG$id"} ? $cgiparams{"TAG$id"} : '';
531             my $hide = $hidden{$id} ? 1 : 0;
532             my $cover = defined $cgiparams{"COVER"} && $cgiparams{"COVER"} == $id ? 1 : 0;
533              
534             $dbi->DoQuery('UpdatePhoto',$order,$hide,$tag,$cover,$id);
535             $order++;
536              
537             my $data = defined $cgiparams{"META$id"} ? $cgiparams{"META$id"} : '';
538             MetaSave($id,['Photo'],split(/[ ,]+/,$data)) if($data);
539             }
540              
541             # upload new photos
542             my $inx = 0;
543             while($cgiparams{"file_$inx"}) {
544             SavePhotoFile(
545             param => "file_$inx",
546             path => $tvars{data}->{path},
547             page => $tvars{data}->{pageid},
548             iwidth => $settings{maxphotowidth} || MaxPhotoWidth,
549             iheight => $settings{maxphotoheight} || MaxPhotoHeight,
550             twidth => $settings{maxthumbwidth} || MaxThumbWidth,
551             theight => $settings{maxthumbheight} || MaxThumbHeight,
552             order => $order++,
553             tag => ''
554             );
555             $inx++;
556             }
557              
558             $tvars{thanks_message} = 'Page saved successfully.';
559             }
560              
561             sub Delete {
562             return unless AccessUser(ADMIN);
563             return unless $cgiparams{$INDEXKEY};
564             return unless $cgiparams{$INDEXKEY} > 2; # Cannot delete the Archive or Homepage folders
565              
566             my @rows = $dbi->GetQuery('array','GetPhotos',$cgiparams{$INDEXKEY});
567             $dbi->DoQuery('MovePhoto',1,$_->[0]) for(@rows);
568             $dbi->DoQuery('DeletePage',$cgiparams{$INDEXKEY});
569              
570             $tvars{thanks_message} = 'Page deleted successfully.';
571             }
572              
573             sub Selection {
574             my $pageid = $tvars{data}->{pageid} || 1;
575             $tvars{ddpages} = PageSelect($pageid,1);
576             }
577              
578             sub PageSelect {
579             my ($opt,$blank,$name,@ignore) = @_;
580             my (@list,%ignore);
581              
582             $name ||= 'pageid';
583             %ignore = map {$_=>1} grep {$_} @ignore;
584              
585             my @rs = $dbi->GetQuery('hash','AdminPages');
586             for my $rec (@rs) {
587             next if($ignore{$rec->{pageid}});
588             push @list, {id=>$rec->{pageid},value=>"$rec->{title}"};
589             }
590              
591             unshift @list, {id=>0,value=>'Select Gallery Page'} if(defined $blank && $blank == 1);
592             return DropDownRows($opt,$name,'id','value',@list);
593             }
594              
595             1;
596              
597             __END__