File Coverage

blib/lib/Labyrinth/Plugin/Event.pm
Criterion Covered Total %
statement 12 12 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 16 16 100.0


line stmt bran cond sub pod time code
1             package Labyrinth::Plugin::Event;
2              
3 5     5   186885 use warnings;
  5         9  
  5         194  
4 5     5   27 use strict;
  5         6  
  5         311  
5              
6 5     5   25 use vars qw($VERSION);
  5         10  
  5         444  
7             $VERSION = '1.10';
8              
9             =head1 NAME
10              
11             Labyrinth::Plugin::Event - Events handler for the Labyrinth framework.
12              
13             =head1 DESCRIPTION
14              
15             Contains all the event functionality for Labyrinth.
16              
17             =cut
18              
19             # -------------------------------------
20             # Library Modules
21              
22 5     5   26 use base qw(Labyrinth::Plugin::Base);
  5         6  
  5         6201  
23              
24             use Clone qw(clone);
25             use Time::Local;
26              
27             use Labyrinth::Audit;
28             use Labyrinth::DBUtils;
29             use Labyrinth::DTUtils;
30             use Labyrinth::MLUtils;
31             use Labyrinth::Session;
32             use Labyrinth::Support;
33             use Labyrinth::Users;
34             use Labyrinth::Variables;
35              
36             use Labyrinth::Plugin::Articles::Sections;
37             use Labyrinth::Plugin::Event::Sponsors;
38             use Labyrinth::Plugin::Event::Types;
39              
40             # -------------------------------------
41             # Variables
42              
43             my $ADAY = 86400;
44             my %abbreviations;
45              
46             # type: 0 = optional, 1 = mandatory
47             # html: 0 = none, 1 = text, 2 = textarea
48              
49             my %fields = (
50             eventid => { type => 0, html => 0 },
51             folderid => { type => 0, html => 0 },
52             userid => { type => 0, html => 0 },
53             imageid => { type => 0, html => 0 },
54             title => { type => 1, html => 1 },
55             listeddate => { type => 1, html => 1 },
56             eventdate => { type => 1, html => 1 },
57             eventtime => { type => 1, html => 1 },
58             eventtypeid => { type => 1, html => 0 },
59             sponsorid => { type => 0, html => 0 },
60             venueid => { type => 0, html => 0 },
61             publish => { type => 1, html => 0 },
62             body => { type => 1, html => 2 },
63             links => { type => 0, html => 2 },
64             image => { type => 0, html => 0 },
65             align => { type => 0, html => 0 },
66             );
67              
68             my (@mandatory,@allfields);
69             for(keys %fields) {
70             push @mandatory, $_ if($fields{$_}->{type});
71             push @allfields, $_;
72             }
73              
74             my $LEVEL = EDITOR;
75              
76             # -------------------------------------
77             # The Subs
78              
79             =head1 PUBLIC INTERFACE METHODS
80              
81             =head2 Full Event Details
82              
83             =over 4
84              
85             =item NextEvent()
86              
87             Retrieves the next event for event type.
88              
89             =item NextEvents()
90              
91             Retrieves all the future events for event type.
92              
93             =item PrevEvents()
94              
95             Retrieves all the future events for event type.
96              
97             =back
98              
99             =cut
100              
101             sub NextEvent {
102             my $timer = _get_timer();
103             my @rows;
104              
105             $cgiparams{eventtypeid} ||= 0;
106              
107             if($cgiparams{eventtypeid}) {
108             @rows = $dbi->GetQuery('hash','GetNextEventByType',$timer,$cgiparams{eventtypeid});
109             } else {
110             @rows = $dbi->GetQuery('hash','GetNextEvent',$timer);
111             }
112             return unless(@rows);
113              
114             $tvars{event}{$cgiparams{eventtypeid}}{next} = $rows[0];
115              
116             my @talks = $dbi->GetQuery('hash','GetEventTalks',$rows[0]->{eventid});
117             if(@talks) {
118             for my $talk (@talks) {
119             my %talk = map {$_ => $talk->{$_}} qw(userid realname guest talktitle abstract);
120             push @{ $tvars{event}{$cgiparams{eventtypeid}}{talks} }, \%talk;
121             }
122             }
123              
124             my @dates;
125             push @dates, formatDate(10,$_->{listdate}) for(@rows);
126             $tvars{events}{$cgiparams{eventtypeid}}{dates} = \@dates if(@dates);
127             }
128              
129             sub NextEvents {
130             my $timer = _get_timer();
131             my @rows;
132              
133             $cgiparams{eventtypeid} ||= 0;
134              
135             if($cgiparams{eventtypeid}) {
136             @rows = $dbi->GetQuery('hash','GetNextEventsByType',$timer,$cgiparams{eventtypeid});
137             } else {
138             @rows = $dbi->GetQuery('hash','GetNextEvents',$timer);
139             }
140             LogDebug("NextEvents rows=".scalar(@rows));
141             return unless(@rows);
142              
143             my @dates;
144             for my $row (@rows) {
145             push @dates, formatDate(10,$row->{listdate});
146             }
147              
148             $tvars{events}{$cgiparams{eventtypeid}}{future} = $rows[0];
149             $tvars{events}{$cgiparams{eventtypeid}}{dates} = \@dates if(@dates);
150              
151             if($cgiparams{eventtypeid}) {
152             my $sections = Labyrinth::Plugin::Articles::Sections->new();
153             $sections->GetSection('eventtype' . $cgiparams{eventtypeid});
154             $tvars{events}{$cgiparams{eventtypeid}}{intro} = $tvars{page}{section};
155             }
156             }
157              
158             sub PrevEvents {
159             my $timer = _get_timer();
160             my @rows;
161              
162             $cgiparams{eventtypeid} ||= 0;
163              
164             if($cgiparams{eventtypeid}) {
165             @rows = $dbi->GetQuery('hash','GetPrevEventsByType',$timer,$cgiparams{eventtypeid});
166             } else {
167             @rows = $dbi->GetQuery('hash','GetPrevEvents',$timer);
168             }
169             LogDebug("PrevEvents rows=".scalar(@rows));
170              
171             my %data;
172             for my $row (@rows) {
173             $data{$row->{listdate}}->{$_} = $row->{$_} for(keys %$row);
174              
175             next unless($row->{talktitle}); # ignore talks without a title
176             my %talk = map {$_ => $row->{$_}} qw(realname guest talktitle);
177             push @{$data{$row->{listdate}}->{talks}}, \%talk;
178              
179             }
180             my @data = map {$data{$_}} reverse sort keys %data;
181             $tvars{events}{$cgiparams{eventtypeid}}{past} = \@data if(@data);
182              
183             if($cgiparams{eventtypeid}) {
184             my $sections = Labyrinth::Plugin::Articles::Sections->new();
185             $sections->GetSection('eventtype' . $cgiparams{eventtypeid});
186             $tvars{events}{$cgiparams{eventtypeid}}{intro} = $tvars{page}{section};
187             }
188             }
189              
190             sub _get_timer {
191             my $date = formatDate(3);
192             my ($day,$month,$year) = split("/",$date);
193              
194             return timelocal(0,0,0,$day,$month-1,$year);
195             }
196              
197             =head2 Event Lists
198              
199             =over 4
200              
201             =item ShortList()
202              
203             Provides a list of forthcoming events, with abbreviations as appropriate.
204             Defaults to 365 days or 20 events, but these limits can be set in the
205             configuration as 'eventsshortlistdays' and 'eventsshortlistcount' respectively.
206              
207             =item LongList()
208              
209             Provides a list of forthcoming events. No defaults, will return the list based
210             on the configured limits or all future events if no configuration. Values can
211             be set for 'eventslonglistdays' and 'eventslonglistcount'.
212              
213             =item Item()
214              
215             Provides the specified event.
216              
217             =back
218              
219             =cut
220              
221             sub ShortList {
222             my $date = formatDate(3);
223             my ($day,$month,$year) = split("/",$date);
224             my $daylimit = $settings{eventsshortlistdays} || 365;
225             my $numlimit = $settings{eventsshortlistcount} || 20;
226              
227             unless(%abbreviations) {
228             for(@{ $settings{abbreviations} }) {
229             my ($name,$value) = split(/=/,$_,2);
230             $abbreviations{$name} = $value;
231             }
232             }
233              
234             my @events;
235             my $events = _events_list($year,$month,$day,$daylimit,$numlimit);
236             for my $event (@$events) {
237             for my $abbr (keys %abbreviations) {
238             $event->{title} =~ s/$abbr/$abbreviations{$abbr}/;
239             }
240             $event->{eventdate} =~ s/\s+/ /g;
241             push @events, $event;
242             }
243              
244             $tvars{events}{shortlist} = \@events;
245             }
246              
247             sub LongList {
248             my ($day,$month,$year) = _startdate();
249             my $daylimit = $settings{eventslonglistdays};
250             my $numlimit = $settings{eventslonglistcount};
251              
252             my $eventtypes = Labyrinth::Plugin::Event::Types->new();
253              
254             my $list = _events_list($year,$month,$day,$daylimit,$numlimit);
255              
256             $tvars{events}{longlist} = $list if(defined $list);
257             $tvars{events}{ddpublish} = PublishSelect($cgiparams{'publish'},1);
258             $tvars{events}{ddtypes} = $eventtypes->EventTypeSelect($cgiparams{'eventtypeid'},1);
259             }
260              
261             sub _events_list {
262             my ($year,$month,$day,$daylimit,$numlimit) = @_;
263             my @rows;
264              
265             $daylimit ||= 0;
266             $numlimit ||= 0;
267              
268             my $timer = timelocal(0,0,0,$day,$month-1,$year);
269             my $limit = $timer + ($daylimit * $ADAY);
270              
271             my @where = ("listdate>=$timer");
272             push @where, "eventtypeid=$cgiparams{'eventtypeid'}" if($cgiparams{'eventtypeid'});
273             push @where, "publish=$cgiparams{'publish'}" if($cgiparams{'publish'});
274             my $where = @where ? join(' AND ',@where) : '';
275              
276             my $num = 0;
277             my $next = $dbi->Iterator('hash','GetEventsByDate',{where=>$where});
278             while(my $row = $next->()) {
279             last if($daylimit && $row->{listdate} > $limit);
280             last if($numlimit && $num > $numlimit);
281              
282             $row->{snippet} = $row->{body};
283             $row->{snippet} =~ s!^(?:.*?)?

(.*?)

.*$!

$1...

!si if($row->{snippet});
284             $row->{shortdate} = $row->{eventdate};
285             $row->{shortdate} =~ s/([A-Za-z]{3}).*/$1/ if($row->{shortdate});
286             $row->{links} =~ s!\*!
!g if($row->{links});
287             push @rows, $row;
288             $num++;
289             }
290              
291             return unless(@rows);
292             return \@rows;
293             }
294              
295             sub _startdate {
296             my %base = (
297             day => 1,
298             month => isMonth(),
299             year => formatDate(1)
300             );
301             my $base = sprintf "%04d%02d%02d", $base{year},$base{month},$base{day};
302              
303             my @time = localtime(time);
304             my $time = sprintf "%04d%02d%02d", $time[5]+1900,$time[4]+1,$time[3];
305              
306             my @date = map {$cgiparams{$_} || $base{$_}} qw(year month day);
307             my $date = sprintf "%04d%02d%02d", @date;
308              
309             #use Labyrinth::Audit;
310             #LogDebug("base=$base");
311             #LogDebug("time=$time");
312             #LogDebug("date=$date");
313              
314             if($date < $time) {
315             return ($time[3],$time[4]+1,$time[5]+1900);
316             }
317              
318             return reverse @date;
319             }
320              
321             sub Item {
322             return unless($cgiparams{'eventid'});
323              
324             my @rows = $dbi->GetQuery('hash','GetEventByID',$cgiparams{'eventid'});
325             $tvars{event} = $rows[0] if(@rows);
326              
327             my @talks = $dbi->GetQuery('hash','GetEventTechTalks',$cgiparams{eventid});
328             $tvars{event}{talks} = @talks ? \@talks : undef;
329             }
330              
331             =head1 ADMIN INTERFACE METHODS
332              
333             =head2 Events
334              
335             =over 4
336              
337             =item Admin
338              
339             Provides list of the events currently available.
340              
341             =item Add
342              
343             Add a new event.
344              
345             =item Edit
346              
347             Edit an existing event.
348              
349             =item Copy
350              
351             Copy an existing event, creating a new event.
352              
353             =item Save
354              
355             Save the current event.
356              
357             =item Promote
358              
359             Promote the published status of the specified event by one level.
360              
361             =item Delete
362              
363             Delete the specified events.
364              
365             =back
366              
367             =cut
368              
369             sub Admin {
370             return unless AccessUser(EDITOR);
371              
372             if($cgiparams{doaction}) {
373             if($cgiparams{doaction} eq 'Delete' ) { Delete(); }
374             elsif($cgiparams{doaction} eq 'Copy' ) { Copy(); }
375             elsif($cgiparams{doaction} eq 'Promote') { Promote(); }
376             }
377              
378             my $month = $cgiparams{'month'};
379             my $year = $cgiparams{'year'};
380              
381             my @where;
382             push @where, "userid=$tvars{'loginid'}" unless(Authorised(PUBLISHER));
383             if($cgiparams{'publish'}) {
384             push @where, "publish=$cgiparams{'publish'}";
385             } else {
386             push @where, "publish<4";
387             }
388             push @where, "eventtype=$cgiparams{'eventtype'}" if($cgiparams{'eventtype'});
389             my $where = @where ? 'WHERE '.join(' AND ',@where) : '';
390              
391             my $eventtypes = Labyrinth::Plugin::Event::Types->new();
392              
393             my @rows = $dbi->GetQuery('hash','AllEvents',{where=>$where});
394             foreach my $row (@rows) {
395             $row->{publishstate} = PublishState($row->{publish});
396             $row->{createdate} = formatDate(3,$row->{listdate});
397             $row->{eventtype} = $eventtypes->EventType($row->{eventtypeid});
398             $row->{name} = UserName($row->{userid});
399             }
400             $tvars{data} = \@rows if(@rows);
401              
402             $tvars{ddpublish} = PublishSelect($cgiparams{'publish'},1);
403             $tvars{ddtypes} = $eventtypes->EventTypeSelect($cgiparams{'eventtype'},1);
404             }
405              
406             sub Add {
407             return unless AccessUser(EDITOR);
408              
409             my $eventtypes = Labyrinth::Plugin::Event::Types->new();
410             my $sponsors = Labyrinth::Plugin::Event::Sponsors->new();
411              
412             my %data = (
413             folderid => 1,
414             title => '',
415             userid => $tvars{loginid},
416             name => $tvars{user}->{name},
417             createdate => formatDate(4),
418             body => '',
419             imageid => 1,
420             ddalign => AlignSelect(1),
421             ddtype => $eventtypes->EventTypeSelect(0,1),
422             link => 'images/blank.png',
423             ddpublish => PublishAction(1,1),
424             );
425              
426             $tvars{data} = \%data;
427              
428             my $promote = 0;
429             $promote = 1 if(Authorised(EDITOR));
430             $tvars{data}{ddpublish} = PublishAction(1,$promote);
431             $tvars{data}{ddpublish} = PublishSelect(1) if(Authorised(ADMIN));
432             $tvars{data}{ddvenue} = VenueSelect($tvars{data}{venueid},1);
433             $tvars{data}{ddsponsor} = $sponsors->SponsorSelect($tvars{data}{sponsorid},1);
434             }
435              
436             sub Edit {
437             return unless AccessUser(EDITOR);
438             return unless AuthorCheck('GetEventByID','eventid',EDITOR);
439             return unless($tvars{data}); # no data, no event
440              
441             if($tvars{data}{publish} == 4 && $tvars{command} ne 'view') {
442             $tvars{errcode} = 'FAILURE';
443             return;
444             }
445              
446             my $eventtypes = Labyrinth::Plugin::Event::Types->new();
447             my $sponsors = Labyrinth::Plugin::Event::Sponsors->new();
448              
449             $tvars{data}{align} = $cgiparams{ALIGN0};
450             $tvars{data}{alignment} = AlignClass($tvars{data}{align});
451             $tvars{data}{ddalign} = AlignSelect($tvars{data}{align});
452             $tvars{data}{name} = UserName($tvars{data}{userid});
453             $tvars{data}{ddtype} = $eventtypes->EventTypeSelect($tvars{data}{eventtypeid},1);
454             $tvars{data}{createdate} = formatDate(4,$tvars{data}{createdate});
455             $tvars{data}{ddvenue} = VenueSelect($tvars{data}{venueid},1);
456             $tvars{data}{ddsponsor} = $sponsors->SponsorSelect($tvars{data}{sponsorid},1);
457              
458             my $promote = 0;
459             $promote = 1 if($tvars{data}{publish} == 1 && Authorised(EDITOR));
460             $promote = 1 if($tvars{data}{publish} == 2 && Authorised(PUBLISHER));
461             $promote = 1 if($tvars{data}{publish} == 3 && Authorised(PUBLISHER));
462             $tvars{data}{ddpublish} = PublishAction($tvars{data}{publish},$promote);
463             $tvars{data}{ddpublish} = PublishSelect($tvars{data}{publish}) if(Authorised(ADMIN));
464              
465             my @rows = $dbi->GetQuery('hash','GetEventTechTalks',$tvars{data}{eventid});
466             $tvars{data}{talks} = @rows ? \@rows : undef;
467             $tvars{preview} = clone($tvars{data}); # data fields need to be editable
468              
469             for(keys %fields) {
470             if($fields{$_}->{html} == 1) { $tvars{data}{$_} = CleanHTML($tvars{data}{$_}) }
471             elsif($fields{$_}->{html} == 2) { $tvars{data}{$_} = SafeHTML($tvars{data}{$_});
472             $tvars{preview}{$_} = CleanTags($tvars{preview}{$_}) }
473             elsif($fields{$_}->{html} == 3) { $tvars{data}{$_} = SafeHTML($tvars{data}{$_});
474             $tvars{preview}{$_} = CleanTags($tvars{preview}{$_}) }
475             }
476              
477             $tvars{data}{listeddate} = formatDate(3,$tvars{data}{listdate});
478             }
479              
480             sub Copy {
481             return unless AccessUser(EDITOR);
482             $cgiparams{'eventid'} = $cgiparams{'LISTED'};
483             return unless AuthorCheck('GetEventByID','eventid',EDITOR);
484              
485             my @fields = ( $tvars{data}{folderid},
486             $tvars{data}{title},
487             $tvars{data}{eventdate},
488             $tvars{data}{eventtime},
489             $tvars{data}{eventtypeid},
490             $tvars{data}{venueid},
491             $tvars{data}{imageid},
492             $tvars{data}{align},
493             1,
494             $tvars{data}{sponsorid} || 0,
495             $tvars{data}{listdate},
496             $tvars{data}{body},
497             $tvars{data}{links},
498             $tvars{loginid});
499              
500             $cgiparams{eventid} = $dbi->IDQuery('AddEvent',@fields);
501              
502             $tvars{errcode} = 'NEXT';
503             $tvars{command} = 'event-edit';
504             }
505              
506             sub Save {
507             return unless AccessUser(EDITOR);
508             return unless AuthorCheck('GetEventByID','eventid',EDITOR);
509              
510             $tvars{data}{align} = $cgiparams{ALIGN0};
511              
512             for(keys %fields) {
513             next unless($fields{$_});
514             if($fields{$_}->{html} == 1) { $cgiparams{$_} = CleanHTML($cgiparams{$_}) }
515             elsif($fields{$_}->{html} == 2) { $cgiparams{$_} = CleanTags($cgiparams{$_}) }
516             }
517              
518             return if FieldCheck(\@allfields,\@mandatory);
519              
520             # check whether listing date has changed
521             my $listeddate = formatDate(3,$tvars{data}{listdate});
522             $tvars{data}{listdate} = unformatDate(3,$tvars{data}{listeddate})
523             unless($listeddate eq $tvars{data}{listeddate});
524              
525             my $imageid = 1;
526             # withdrawn, may be reintroduced later.
527             #my $imageid = $tvars{data}{'imageid'} || 1;
528             #($imageid) = Images::SaveImageFile(
529             # param => 'image',
530             # stock => 4) if($cgiparams{image});
531              
532             my %fields = map {$_ => 1} @allfields;
533             delete $fields{$_} for @mandatory;
534             for(keys %fields) {
535             if(/align|id/) { $tvars{data}{$_} ||= 0; }
536             else { $tvars{data}{$_} ||= undef; }
537             }
538              
539             my @fields = ( $tvars{data}{folderid},
540             $tvars{data}{title},
541             $tvars{data}{eventdate},
542             $tvars{data}{eventtime},
543             $tvars{data}{eventtypeid},
544             $tvars{data}{venueid},
545             $imageid,
546             $tvars{data}{align},
547             $tvars{data}{publish},
548             $tvars{data}{sponsorid} || 0,
549             $tvars{data}{listdate},
550             $tvars{data}{body},
551             $tvars{data}{links}
552             );
553              
554             if($cgiparams{eventid})
555             { $dbi->DoQuery('SaveEvent',@fields,$cgiparams{eventid}); }
556             else { $cgiparams{eventid} = $dbi->IDQuery('AddEvent',@fields,$tvars{loginid}); }
557              
558             $tvars{thanks} = 1;
559             }
560              
561             sub Promote {
562             return unless AccessUser(PUBLISHER);
563             my @ids = CGIArray('LISTED');
564             return unless @ids;
565              
566             for my $id (@ids) {
567             $cgiparams{'eventid'} = $id;
568             next unless AuthorCheck('GetEventByID','eventid');
569              
570             my $publish = $tvars{data}{publish} + 1;
571             next unless($publish < 5);
572             $dbi->DoQuery('PromoteEvent',$publish,$cgiparams{'eventid'});
573             }
574             }
575              
576             sub Delete {
577             return unless AccessUser(ADMIN);
578             my @ids = CGIArray('LISTED');
579             return unless @ids;
580              
581             for my $id (@ids) {
582             $cgiparams{'eventid'} = $id;
583             next unless AuthorCheck('GetEventByID','eventid',EDITOR);
584             $dbi->DoQuery('DeleteEvent',$cgiparams{'eventid'});
585             }
586             }
587              
588             =head2 Event Attributes
589              
590             =over 4
591              
592             =item VenueSelect
593              
594             Provides a dropdown list of venues available.
595              
596             =back
597              
598             =cut
599              
600             sub VenueSelect {
601             my ($opt,$blank) = @_;
602             $blank ||= 0;
603              
604             my @list = $dbi->GetQuery('hash','AllVenues');
605             unshift @list, { venueid => 0, venue => 'Select A Venue' } if($blank == 1);
606             DropDownRows($opt,'venueid','venueid','venue',@list);
607             }
608              
609             # withdrawn, may be reintroduced later.
610             #sub ImageCheck {
611             # my @rows = $dbi->GetQuery('array','EventsImageCheck',$_[0]);
612             # @rows ? 1 : 0;
613             #}
614              
615              
616             1;
617              
618             __END__