package WebGUI::Asset::Wobject::EventsCalendar; #------------------------------------------------------------------- # WebGUI is Copyright 2001-2005 Plain Black Corporation. #------------------------------------------------------------------- # Please read the legal notices (docs/legal.txt) and the license # (docs/license.txt) that came with this distribution before using # this software. #------------------------------------------------------------------- # http://www.plainblack.com info@plainblack.com #------------------------------------------------------------------- use strict; use Tie::CPHash; use WebGUI::DateTime; use WebGUI::ErrorHandler; use WebGUI::International; use WebGUI::Macro; use WebGUI::Privilege; use WebGUI::Session; use WebGUI::SQL; use WebGUI::URL; use WebGUI::Utility; use WebGUI::Asset::Wobject; use WebGUI::Asset::Event; our @ISA = qw(WebGUI::Asset::Wobject); #------------------------------------------------------------------- #sub canManage { # my $self = shift; # my $userId = shift || $session{user}{userId}; # if ($userId eq $self->getValue("ownerUserId")) { # return 1; # } # return 0 unless $self->canView($userId); # return WebGUI::Grouping::isInGroup($self->getValue("groupIdManage"),$userId); #} #------------------------------------------------------------------- sub definition { my $class = shift; my $definition = shift; push(@{$definition}, { tableName=>'eventscalendar', className=>'WebGUI::Asset::Wobject::EventsCalendar', properties=>{ templateId =>{ fieldType=>"template", defaultValue=>'PBtmpl0000000000000022' }, eventTemplateId =>{ fieldType=>"template", defaultValue=>'PBtmpl0000000000000023' }, scope =>{ fieldType=>"selectList", defaultValue=>'0' }, # type =>{ # fieldType=>"selectList", # defaultValue=>'0' # }, # groupIdManage =>{ # fieldType=>"group", # defaultValue=>'4' # }, startMonth=>{ fieldType=>"selectList", defaultValue=>"current" }, endMonth=>{ fieldType=>"selectList", defaultValue=>"after12" }, defaultMonth=>{ fieldType=>"selectList", defaultValue=>"current" }, paginateAfter=>{ fieldType=>"integer", defaultValue=>1 } } }); return $class->SUPER::definition($definition); } #------------------------------------------------------------------- sub duplicate { my $self = shift; return $self->getParent->duplicateTree($self); } #------------------------------------------------------------------- sub getEditForm { my $self = shift; my $tabform = $self->SUPER::getEditForm(); # $tabform->getTab("properties")->selectList( # -name=>"type", # -label=>WebGUI::International::get(501,"EventsCalendar"), # -value=>[$self->getValue("type")], # -options=>{ # 0=>WebGUI::International::get(502,"EventsCalendar"), # 1=>WebGUI::International::get(503,"EventsCalendar"), # 2=>WebGUI::International::get(504,"EventsCalendar"), # 3=>WebGUI::International::get(505,"EventsCalendar"), # 4=>WebGUI::International::get(506,"EventsCalendar") # }, # ); $tabform->getTab("properties")->selectList( -name=>"scope", -label=>WebGUI::International::get(507,"EventsCalendar"), -value=>[$self->getValue("scope")], -options=>{ 0=>WebGUI::International::get(508,"EventsCalendar"), 1=>WebGUI::International::get(509,"EventsCalendar"), 2=>WebGUI::International::get(510,"EventsCalendar"), } ); $tabform->getTab("display")->template( -name=>"templateId", -label=>WebGUI::International::get(94,"EventsCalendar"), -value=>$self->getValue('templateId'), -namespace=>"EventsCalendar" ); $tabform->getTab("display")->template( -name=>"eventTemplateId", -label=>WebGUI::International::get(80,"EventsCalendar"), -value=>$self->getValue('eventTemplateId'), -namespace=>"EventsCalendar/Event", -afterEdit=>'func=edit&wid='.$self->get("wobjectId") ); $tabform->getTab("display")->selectList( -name=>"startMonth", -options=>{ "january"=>WebGUI::International::get(15), "now"=>WebGUI::International::get(98,"EventsCalendar"), "current"=>WebGUI::International::get(82,"EventsCalendar"), "first"=>WebGUI::International::get(83,"EventsCalendar") }, -label=>WebGUI::International::get(81,"EventsCalendar"), -value=>[$self->getValue("startMonth")] ); my %options; tie %options, 'Tie::IxHash'; %options = ( "last"=>WebGUI::International::get(85,"EventsCalendar"), "after12"=>WebGUI::International::get(86,"EventsCalendar"), "after9"=>WebGUI::International::get(87,"EventsCalendar"), "after6"=>WebGUI::International::get(88,"EventsCalendar"), "after3"=>WebGUI::International::get(89,"EventsCalendar"), "current"=>WebGUI::International::get(82,"EventsCalendar") ); $tabform->getTab("display")->selectList( -name=>"endMonth", -options=>\%options, -label=>WebGUI::International::get(84,"EventsCalendar"), -value=>[$self->getValue("endMonth")] ); $tabform->getTab("display")->selectList( -name=>"defaultMonth", -options=>{ "current"=>WebGUI::International::get(82,"EventsCalendar"), "last"=>WebGUI::International::get(85,"EventsCalendar"), "first"=>WebGUI::International::get(83,"EventsCalendar") }, -label=>WebGUI::International::get(90,"EventsCalendar"), -value=>[$self->getValue("defaultMonth")] ); $tabform->getTab("display")->integer( -name=>"paginateAfter", -label=>WebGUI::International::get(19,"EventsCalendar"), -value=>$self->getValue("paginateAfter") ); # $tabform->getTab("security")->group( # -name=>"groupIdManage", # -label=>WebGUI::International::get(500,"EventsCalendar"), # -value=>[$self->getValue("groupIdManage")], # -uiLevel=>6 # ); return $tabform; } #------------------------------------------------------------------- sub getIcon { my $self = shift; my $small = shift; return $session{config}{extrasURL}.'/assets/small/calendar.gif' if ($small); return $session{config}{extrasURL}.'/assets/calendar.gif'; } #------------------------------------------------------------------- sub getName { return WebGUI::International::get(2,"EventsCalendar"); } #------------------------------------------------------------------- sub getUiLevel { return 9; } #------------------------------------------------------------------- sub view { # All of this really needs to be redone like the old # EventsCalendar... except this time using getLineageWhere to # filter instead of doing all sorts of pruning. Also, caching # needs to be re-enabled. Also, see the note below at line # 407 - each dayloop event array needs to be sorted by startTime. my $self = shift; return WebGUI::Privilege::noAccess() unless $self->canView; #define default view month range. Note that this could be different from #the range a user is allowed to view - set by the events calendar limitations. my $monthRangeLength = int($self->getValue("paginateAfter")); # Let's limit the range to 72 for now; later we can make it definable in the calendar itself. $monthRangeLength = 1 if ($monthRangeLength < 0); $monthRangeLength = 72 if ($monthRangeLength > 72); #monthRangeLength is the number of months the user wishes to view # or the default number of the months per page the wobject is set to display. my $calMonthStart = $session{form}{calMonthStart} || 1; $calMonthStart = int($calMonthStart); my $calMonthEnd = $session{form}{calMonthEnd} || ($calMonthStart + $monthRangeLength - 1); $calMonthEnd = int($calMonthEnd); $calMonthStart = 1 if (($calMonthStart < 1) || ($calMonthStart > 72)); $calMonthEnd = 1 if (($calMonthEnd < 1) || ($calMonthEnd > 72)); $calMonthEnd = $calMonthStart if ($calMonthEnd < $calMonthStart); my ( $junk, $sameDate, $p, @list, $date, $flag, %previous, $maxDate, $minDate); my $monthloop; #had to disable caching because each event can have its own security. # It can be re-added, of course. my $scope = $self->getValue("scope"); my $children; # get All My Children. if ($scope == 0) { #calendar's scope is regular (immediate descendants) $children = $self->getLineage(["children"],{returnObjects=>1, includeOnlyClasses=>["WebGUI::Asset::Event","WebGUI::Asset::Relation"]}); } elsif ($scope == 1) { #calendar is master $children = $self->getLineage(["descendants"],{returnObjects=>1, includeOnlyClasses=>["WebGUI::Asset::Event","WebGUI::Asset::Relation"]}); } elsif ($scope == 2) { #calendar is global $children = WebGUI::Asset::getRoot()->getLineage(["descendants"],{returnObjects=>1, includeOnlyClasses=>["WebGUI::Asset::Event","WebGUI::Asset::Relation"]}); } # get Type of Calendar # my $calType = $self->getValue("type"); my $startMonth = $self->getValue("startMonth"); #define range of allowed months from the wobject settings. if ($startMonth eq "first") { #Don't really do anything - leading months will not be pushed if there are no events. $minDate = WebGUI::DateTime::time(); } elsif ($startMonth eq "january") { $minDate = WebGUI::DateTime::humanToEpoch(WebGUI::DateTime::epochToHuman("","%y")."-01-01 00:00:00"); } else { $minDate = WebGUI::DateTime::time(); } my $startsNow = 0; unless ($self->get("startMonth") eq "now") { ($minDate,$junk) = WebGUI::DateTime::monthStartEnd($minDate); } else { $startsNow = 1;} tie %previous, 'Tie::CPHash'; #This merely limits the months to publish. Month's processing is skipped if #the month is after the maxDate. my $endMonth = $self->getValue("endMonth"); if ($endMonth eq "last") { $maxDate = WebGUI::DateTime::addToDate($minDate,99,0,0); } elsif ($endMonth eq "after12") { $maxDate = WebGUI::DateTime::addToDate($minDate,1,0,0); } elsif ($endMonth eq "after9") { $maxDate = WebGUI::DateTime::addToDate($minDate,0,9,0); } elsif ($endMonth eq "after6") { $maxDate = WebGUI::DateTime::addToDate($minDate,0,6,0); } elsif ($endMonth eq "after3") { $maxDate = WebGUI::DateTime::addToDate($minDate,0,3,0); } elsif ($endMonth eq "current") { $maxDate = WebGUI::DateTime::addToDate($minDate,0,1,0); } my @now = WebGUI::DateTime::epochToArray(WebGUI::DateTime::time()); my $calHasEvent = 0; #monthcount minus i is the number of months remaining to be processed. for (my $i=$calMonthStart;$i<=$calMonthEnd;$i++) { #for each month, do the following.... my $monthHasEvent = 0; my $thisMonth = WebGUI::DateTime::addToDate($minDate,0,($i-1),0); my ($monthStart, $monthEnd) = WebGUI::DateTime::monthStartEnd($thisMonth); my @thisMonthDate = WebGUI::DateTime::epochToArray($thisMonth); #Check month to see if it is in the allowed month range. End loop if it's not. if ($thisMonth > $maxDate) { $i = $calMonthEnd; next; } my %events; my %previous; foreach my $event (@{$children}) { if (ref $event eq "WebGUI::Asset::Event") { my $eventStartDate = $event->getValue("eventStartDate"); my $eventEndDate = $event->getValue("eventEndDate"); if ($eventStartDate > $eventEndDate) { #Fix bad data. Everything that has a beginning must have an end [no earlier than its beginning]. $event->update({ "eventEndDate"=>$eventStartDate }); } #Prune events that don't appear in this month. next if (($eventStartDate > $monthEnd) || ($eventEndDate < $monthStart)); #Prune events that have already ended if $startsNow next if (($eventEndDate < $minDate) && $startsNow); #Hide this event unless we are allowed to see it. Funny that each event has 4 date/time pairs. next unless $event->canView; # only display events for this person's Personal Calendar, if it's so set. # next unless (($calType != 1) || ($event->isMyEvent())); my $eventLength = WebGUI::DateTime::getDaysInInterval($eventStartDate,$eventEndDate); my ($startYear, $startMonth, $startDay, $startDate, $startTime) = split " ", WebGUI::DateTime::epochToHuman($eventStartDate, "%y %c %D %z %Z"); my ($endYear, $endMonth, $endDay, $endDate, $endTime) = split " ", WebGUI::DateTime::epochToHuman($eventEndDate, "%y %c %D %z %Z"); my $eventCycleStart = 0; # Fast-Forward Event Cycle to this month (for events spanning multiple months) $eventCycleStart = (WebGUI::DateTime::getDaysInInterval($eventStartDate,$monthStart) - 1) if ($eventStartDate < $monthStart); # also, skip leading days of this event if $startsNow is true. Doesn't work in Events List. Oh well. # $eventCycleStart = (WebGUI::DateTime::getDaysInInterval($eventStartDate,time)) if (($eventStartDate < time) && ($startsNow)); # by default, stop processing this event at the end of its length. my $eventCycleStop = ($eventLength); #cycle through each day in the event, pushing the event's day listing into the proper day. for (my $i=$eventCycleStart; $i<=$eventCycleStop; $i++) { #create an array for the specific day in the event. my @date = WebGUI::DateTime::epochToArray(WebGUI::DateTime::addToDate($eventStartDate,0,0,$i)); # if the event goes past the end of this month, halt the loop. # No need to continue processing days that aren't in this month. if ($monthEnd < (WebGUI::DateTime::addToDate($eventStartDate,0,0,$i) - 1)) { $i = ($eventCycleStop + 2); next; } #this conditional used to only test if we are in the proper month... #Now also test to see if we're at the maxDate yet and after the minDate. if (($date[1] == $thisMonthDate[1]) && (WebGUI::DateTime::addToDate($eventStartDate,0,0,$i) <= ($maxDate + 2678400))){ push(@{$events{$date[2]}}, { description=>$event->getValue("description"), name=>$event->getValue("title"), 'start.date.human'=>$startDate, 'start.time.human'=>$startTime, 'start.date.epoch'=>$eventStartDate, 'start.year'=>$startYear, 'start.month'=>$startMonth, 'start.day'=>$startDay, 'end.date.human'=>$endDate, 'end.time.human'=>$endTime, 'end.date.epoch'=>$eventEndDate, 'end.year'=>$endYear, 'end.month'=>$endMonth, 'end.day'=>$endDay, 'startEndYearMatch'=>($startYear eq $endYear), 'startEndMonthMatch'=>($startMonth eq $endMonth), 'startEndDayMatch'=>($startDay eq $endDay), isFirstDayOfEvent=>($i == 0), dateIsSameAsPrevious=>($startYear."-".$startMonth."-".$startDay eq $previous{start} && $endYear."-".$endMonth."-".$endDay eq $previous{end}), daysInEvent=>($eventLength+1), url=>$event->getUrl() }); $monthHasEvent = 1; $calHasEvent = 1; } } $previous{start} = $startYear."-".$startMonth."-".$startDay; $previous{end} = $endYear."-".$endMonth."-".$endDay; } elsif (ref $event eq "WebGUI::Asset::Relation") { print "\n"; } } if (($startsNow || ($startMonth eq "first")) && ($calHasEvent == 0)) { #Let's process an extra month if this month had no events, #and if we're at the beginning of the calendar, and if #the calendar is supposed to start with the first event or now. $calMonthEnd++ unless $monthHasEvent; next unless $monthHasEvent; } my $dayOfWeekCounter = 1; my $firstDayInFirstWeek = WebGUI::DateTime::getFirstDayInMonthPosition($thisMonth); my $daysInMonth = WebGUI::DateTime::getDaysInMonth($thisMonth); my @prepad; while ($dayOfWeekCounter < $firstDayInFirstWeek) { push(@prepad,{ count => $dayOfWeekCounter }); $dayOfWeekCounter++; } my @date = WebGUI::DateTime::epochToArray($thisMonth); my @dayloop; for (my $dayCounter=1; $dayCounter <= $daysInMonth; $dayCounter++) { #---------------------------------------------------------------------------- #sort each day's events here - still needs to be done! #---------------------------------------------------------------------------- push(@dayloop, { dayOfWeek => $dayOfWeekCounter, day=>$dayCounter, isStartOfWeek=>($dayOfWeekCounter==1), isEndOfWeek=>($dayOfWeekCounter==7), isToday=>($date[0]."-".$date[1]."-".$dayCounter eq $now[0]."-".$now[1]."-".$now[2]), event_loop=>\@{$events{$dayCounter}}, url=>$events{$dayCounter}->[0]->{url} }); if ($dayOfWeekCounter == 7) { $dayOfWeekCounter = 1; } else { $dayOfWeekCounter++; } } my @postpad; while ($dayOfWeekCounter <= 7 && $dayOfWeekCounter > 1) { push(@postpad,{ count => $dayOfWeekCounter }); $dayOfWeekCounter++; } push(@$monthloop, { 'daysInMonth'=>$daysInMonth, 'day_loop'=>\@dayloop, 'prepad_loop'=>\@prepad, 'postpad_loop'=>\@postpad, 'month'=>WebGUI::DateTime::getMonthName($date[1]), 'year'=>$date[0] }); } my %var; $var{month_loop} = \@$monthloop; # $var{"canManage"} = $self->canManage; $var{"addevent.url"} = $self->getUrl().'?func=addStyledEvent&class=WebGUI::Asset::Event'; $var{"addevent.label"} = WebGUI::International::get(20,"EventsCalendar"); $var{'sunday.label'} = WebGUI::DateTime::getDayName(7); $var{'monday.label'} = WebGUI::DateTime::getDayName(1); $var{'tuesday.label'} = WebGUI::DateTime::getDayName(2); $var{'wednesday.label'} = WebGUI::DateTime::getDayName(3); $var{'thursday.label'} = WebGUI::DateTime::getDayName(4); $var{'friday.label'} = WebGUI::DateTime::getDayName(5); $var{'saturday.label'} = WebGUI::DateTime::getDayName(6); $var{'sunday.label.short'} = substr(WebGUI::DateTime::getDayName(7),0,1); $var{'monday.label.short'} = substr(WebGUI::DateTime::getDayName(1),0,1); $var{'tuesday.label.short'} = substr(WebGUI::DateTime::getDayName(2),0,1); $var{'wednesday.label.short'} = substr(WebGUI::DateTime::getDayName(3),0,1); $var{'thursday.label.short'} = substr(WebGUI::DateTime::getDayName(4),0,1); $var{'friday.label.short'} = substr(WebGUI::DateTime::getDayName(5),0,1); $var{'saturday.label.short'} = substr(WebGUI::DateTime::getDayName(6),0,1); #use Data::Dumper; return '
'.Dumper(\%var).''; my $vars = \%var; return $self->processTemplate($vars,$self->get("templateId")); } #------------------------------------------------------------------- =head2 www_addStyledEvent ( ) Adds an event. =cut sub www_addStyledEvent { my $self = shift; my %properties = ( groupIdView => $self->get("groupIdView"), groupIdEdit => $self->get("groupIdEdit"), ownerUserId => $self->get("ownerUserId"), encryptPage => $self->get("encryptPage"), templateId => $self->get("eventTemplateId"), styleTemplateId => $self->get("styleTemplateId"), printableStyleTemplateId => $self->get("printableStyleTemplateId"), isHidden => $self->get("isHidden"), startDate => $self->get("startDate"), endDate => $self->get("endDate") ); $properties{isHidden} = 1 unless (WebGUI::Utility::isIn(ref $session{form}{class}, @{$session{config}{assetContainers}})); my $newAsset = WebGUI::Asset->newByDynamicClass("new","WebGUI::Asset::Event",\%properties); $newAsset->{_parent} = $self; #get parent so we can get the parent's style. Hopefully the parent is an EventsCalendar. If not, oh well. # return "You must add an Event as a child of an EventsCalendar." unless ($self->getValue("className") = "WebGUI::Asset::Wobject::EventsCalendar"); return WebGUI::Privilege::noAccess() unless ($self->canEdit); return WebGUI::Style::process($newAsset->getEditForm->print,$self->getValue("styleTemplateId")); } #------------------------------------------------------------------- sub www_edit { my $self = shift; return $self->getAdminConsole->render(WebGUI::Privilege::insufficient()) unless $self->canEdit; $self->getAdminConsole->setHelp("events calendar add/edit"); return $self->getAdminConsole->render($self->getEditForm->print,WebGUI::International::get("12","EventsCalendar")); } 1;