diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index dc27fd1ad..55ba36a70 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -1,5 +1,7 @@ 7.3.10 - + - fix: Calendar Update Feeds now handles iCalendar "DURATION" field + - fix: Various potential bugs in WebGUI::DateTime due to inheritence from + DateTime. 7.3.9 - fix: SQL Form and big table imports diff --git a/lib/WebGUI/DateTime.pm b/lib/WebGUI/DateTime.pm index bf4dd6bec..5c55b8478 100755 --- a/lib/WebGUI/DateTime.pm +++ b/lib/WebGUI/DateTime.pm @@ -127,14 +127,14 @@ sub new my $locale = 'en_US'; my $session; - if(ref $param0 eq "WebGUI::Session") { + if (ref $param0 eq "WebGUI::Session") { $session = shift; my $i18n = WebGUI::International->new($session); my $language = $i18n->getLanguage($session->user->profileField('language')); $locale = $language->{languageAbbreviation} || 'en'; $locale .= "_".$language->{locale} if ($language->{locale}); } - + #use Data::Dumper; #warn "Args to DateTime->new: ".Dumper \@_; @@ -236,6 +236,28 @@ sub from_object { ####################################################################### +=head2 set + +Handle copying all WebGUI::DateTime specific data. This is an object method. + +This method overrides the set in DateTime to keep WebGUI::DateTime specific +information being passed between object instances. Some DateTime operations +create a new object. + +=cut + +sub set { + my $self = shift; + my $session = $self->session; + + my $copy = $self->SUPER::set(@_); + + $copy->session($session); + return $copy; +} + +####################################################################### + =head2 toDatabase Returns a MySQL Date/Time string in the UTC time zone @@ -419,6 +441,52 @@ sub toUserTimeZoneTime { return $copy->strftime($MYSQL_TIME); } +####################################################################### + +=head2 truncate + +Handle copying all WebGUI::DateTime specific data. This is an object method. + +This method overrides the set in DateTime to keep WebGUI::DateTime specific +information being passed between object instances. Some DateTime operations +create a new object. + +=cut + +sub truncate { + my $self = shift; + my $session = $self->session; + + my $copy = $self->SUPER::truncate(@_); + + $copy->session($session); + return $copy; +} + + +####################################################################### + +=head2 set + +Handle copying all WebGUI::DateTime specific data. This is an object method. + +This method overrides the set in DateTime to keep WebGUI::DateTime specific +information being passed between object instances. Some DateTime operations +create a new object. + +=cut + +sub set { + my $self = shift; + my $session = $self->session; + + my $copy = $self->SUPER::set(@_); + + $copy->session($session); + return $copy; +} + + ####################################################################### =head2 session diff --git a/lib/WebGUI/Workflow/Activity/CalendarUpdateFeeds.pm b/lib/WebGUI/Workflow/Activity/CalendarUpdateFeeds.pm index d7b755b83..051b030f3 100755 --- a/lib/WebGUI/Workflow/Activity/CalendarUpdateFeeds.pm +++ b/lib/WebGUI/Workflow/Activity/CalendarUpdateFeeds.pm @@ -187,7 +187,8 @@ sub execute { my $added = 0; my $updated = 0; - for my $id (keys %events) + my $errored = 0; + EVENT: for my $id (keys %events) { #use Data::Dumper; #warn "EVENT: $id; ".Dumper $events{$id}; @@ -226,11 +227,19 @@ sub execute { elsif ($dtstart =~ /(\d{4})(\d{2})(\d{2})/) { my ($year, $month, $day) = $dtstart =~ /(\d{4})(\d{2})(\d{2})/; - $properties->{startDate} = join "-",$year,$month,$day; } + elsif ($dtstart) { + $session->errorHandler->warn( + "Workflow::Activity::CalendarUpdateFeeds" + . " -- '$dtstart' does not appear to be a valid date" + ); + $errored++; + next EVENT; + } - my $dtend = $events{$id}->{dtend}->[1]; + my $dtend = $events{$id}->{dtend}->[1]; + my $duration = $events{$id}->{duration}->[1]; if ($dtend =~ /T/) { my ($date, $time) = split /T/, $dtend; @@ -242,7 +251,7 @@ sub execute { split / /, WebGUI::DateTime->new( year => $year, month => $month, - day => $day, + day => $day, hour => $hour, minute => $minute, second => $second, @@ -255,7 +264,51 @@ sub execute { $properties->{endDate} = join "-",$year,$month,$day; } - + # If we can't parse it, forget the whole event + elsif ($dtend) { + $session->errorHandler->warn( + "Workflow::Activity::CalendarUpdateFeeds" + . " -- '$dtend' does not appear to be a valid date" + ); + $errored++; + next EVENT; + } + # No dtend, but we have duration! + elsif ($duration) { + my ($days, $hours, $minutes, $seconds) + = $duration =~ m{ + P + (?:(\d+)D)? # Days + T + (?:(\d+)H)? # Hours + (?:(\d+)M)? # Minutes + (?:(\d+)S)? # Seconds + }ix; + my $startDate = $properties->{startDate}; + # Fill in bogus value to get a WebGUI::DateTime object, + # we'll figure out what we actually need later + my $startTime = $properties->{startTime} || "00:00:00"; + + my $datetime = WebGUI::DateTime->new($session,$startDate." ".$startTime); + + $datetime->add( + days => $days || 0, + hours => $hours || 0, + minutes => $minutes || 0, + seconds => $seconds || 0, + ); + + $properties->{endDate} = $datetime->toDatabaseDate; + # If it not an all-day event, set the end time too + if ($properties->{startTime}) { + $properties->{endTime} = $datetime->toDatabaseTime; + } + } + # No dtend, no duration, just copy the start + else { + $properties->{endDate} = $properties->{startDate}; + $properties->{endTime} = $properties->{startTime}; + } # If there are X-WebGUI-* fields @@ -296,6 +349,7 @@ sub execute { if ($event) { $event->update($properties); + $event->requestAutoCommit; $updated++; } } @@ -303,7 +357,7 @@ sub execute { { my $calendar = WebGUI::Asset->newByDynamicClass($self->session,$feed->{assetId}); if (!defined $calendar) { - $self->session->errorHandler->error("CalendarUpdateFeeds Activity: Calendar object failed to instanciate at line 304. Did you commit the calendar wobject?"); + $self->session->errorHandler->error("CalendarUpdateFeeds Activity: Calendar object failed to instanciate. Did you commit the calendar wobject?"); return $self->ERROR; } my $event = $calendar->addChild($properties); @@ -317,7 +371,7 @@ sub execute { # Update the result and last updated fields $self->session->db->write("update Calendar_feeds set lastResult=?,lastUpdated=? where feedId=?", - ["Success! $added added, $updated updated",$dt,$feed->{feedId}]); + ["Success! $added added, $updated updated, $errored parsing errors",$dt,$feed->{feedId}]); } else {