diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index 1d856cd88..400d90dcb 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -27,6 +27,18 @@ the user is redirected to http. (Martin Kamerbeek / Procolix) - fix: RSS From Parent assets should always be hidden from navigation - fix: profile field i18ned possibleValues with apostrophes failing + - Added a new DateTime subclass, WebGUI::DateTime, with convenience methods to + convert to and from MySQL Date/Time strings. Moving forward, this method + should be used in place of the existing WebGUI::Session::DateTime, which can + create problems when handling time zones. + - Form elements Date, DateTime, and TimeField now return MySQL Date/Time + strings when given a MySQL Date/Time string as a default value. This is now + the recommended method of storing date/time in the database. + - WebGUI::Search now accepts more rules, "where" for specifying an additional + where clause, "join" for making join clauses, and "columns" for adding more + columns to return. + - WebGUI::TabForm->addTab now returns the WebGUI::HTMLForm created. + - WebGUI::AssetLineage::getLineage can now limit the number of records returned 7.2.3 - fix: minor bug with new template vars in Auth::createAccount diff --git a/lib/WebGUI/AssetLineage.pm b/lib/WebGUI/AssetLineage.pm index 10cf5b89d..f0d4f4b88 100644 --- a/lib/WebGUI/AssetLineage.pm +++ b/lib/WebGUI/AssetLineage.pm @@ -299,6 +299,10 @@ A string containing extra where clause information for the query. A string containing an order by clause (without the "order by"). +=head4 limit + +The maximum amount of entries to return + =cut sub getLineage { @@ -408,6 +412,12 @@ sub getLineage { $sortOrder = $rules->{orderByClause}; } my $sql = "select $columns from $tables where $where group by assetData.assetId order by $sortOrder"; + + # Add limit if necessary + if ($rules->{limit}) { + $sql .= " limit ".$rules->{limit}; + } + my @lineage; my %relativeCache; my $sth = $self->session->db->read($sql); diff --git a/lib/WebGUI/DateTime.pm b/lib/WebGUI/DateTime.pm new file mode 100755 index 000000000..19d034aa8 --- /dev/null +++ b/lib/WebGUI/DateTime.pm @@ -0,0 +1,254 @@ +package WebGUI::DateTime; + +=head1 LEGAL + + ------------------------------------------------------------------- + WebGUI is Copyright 2001-2006 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 + ------------------------------------------------------------------- + +=cut + +use strict; +use base 'DateTime'; + + +=head1 NAME + +WebGUI::Session::Date - DateTime subclass with additional WebGUI methods + +=head1 SYNOPSIS + + my $dt = $session->date->new("2006-11-06 21:12:45"); + my $dt = $session->date->new(time); + my $dt = $session->date->new({ year => 2006, month => 11, day => 6 }); + + my $mysql = $dt->toMysql; # Make a MySQL date/time string + my $mysqlDate = $dt->toMysqlDate; # Make a MySQL date string + my $mysqlTime = $dt->toMysqlTime; # Make a MySQL time string + + ### See perldoc DateTime for additional methods ### + +=head1 DESCRIPTION + +This module is intended as a drop-in replacement for Perl's DateTime module, +with additional methods for translating to and from MySQL Date/Time field +strings. + +NOTE: This module replaces WebGUI::Session::DateTime, which has a problem +dealing with time zones. + +=head1 METHODS + +=cut + +####################################################################### + +=head2 new ( string ) + +Creates a new object from a MySQL Date/Time string with the UTC time zone. + +=head2 new ( integer ) + +Creates a new object from an epoch time. + +=head2 new ( "mysql" => string, "time_zone" => string) + +Creates a new object from a MySQL Date/Time string with the specified time zone + +=head2 new ( hash ) + +Creates a new object from a hash of data passed directly to DateTime. + +=cut + +sub new +{ + # Drop-in replacement for Perl's DateTime.pm + my $class = shift; + my $self; + + #use Data::Dumper; + #warn "Args to DateTime->new: ".Dumper \@_; + + if (@_ > 1 && grep /^mysql$/, @_) + { + my %hash = @_; + $hash{time_zone} ||= "UTC"; + my $string = delete $hash{mysql}; + my %mysql = _splitMysql($string); + $hash{$_} = $mysql{$_} + for keys %mysql; + + $self = $class->SUPER::new(%hash); + } + elsif (@_ > 1) + { + $self = $class->SUPER::new(@_); + } + elsif ($_[0] =~ /^\d+$/) + { + $self = DateTime->from_epoch(epoch=>$_[0], time_zone=>"UTC"); + } + else + { + $self = $class->SUPER::new( + (_splitMysql($_[0])), + time_zone => "UTC", + ); + } + + # If no DateTime object created yet, I don't know how + unless ($self) + { + return; + } + + return bless $self, $class; +} + + + + +####################################################################### + +=head2 toIcal + +Returns a Date/Time string in the UTC time zone in the iCalendar format. + + 20061124T120000Z + +=cut + +sub toIcal +{ + my $self = shift; + + if ($self->time_zone->is_utc) + { + return $self->strftime('%Y%m%dT%H%M%SZ'); + } + else + { + return $self->clone->set_time_zone("UTC")->strftime('%Y%m%dT%H%M%SZ'); + } +} + + + + +####################################################################### + +=head2 toIcalDate + +Returns only the date portion in the format suitable for iCal. Does not adjust +time zone. + +=cut + +sub toIcalDate +{ + return $_[0]->strftime('%Y%m%d'); +} + + + + +####################################################################### + +=head2 toMysql + +Returns a MySQL Date/Time string. + +=cut + +sub toMysql +{ + return $_[0]->strftime("%Y-%m-%d %H:%M:%S"); +} + + + + +####################################################################### + +=head2 toMysqlDate + +Returns a MySQL Date string. Any time data stored by this object will be +ignored. + +=cut + +sub toMysqlDate +{ + return $_[0]->strftime("%Y-%m-%d"); +} + + + + +####################################################################### + +=head2 toMysqlTime + +Returns a MySQL Time string. Any date data stored by this object will be +ignored. + +=cut + +sub toMysqlTime +{ + return $_[0]->strftime("%H:%M:%S"); +} + + + + +####################################################################### + +=head2 _splitMysql ( string ) + +Class method that splits a MySQL Date/Time string into a hash to be passed into +DateTime + +=cut + +sub _splitMysql +{ + my $string = shift; + my ($y,$m,$d,$h,$n,$s) = split /\D+/,$string; + my %hash = ( + year => $y, + month => $m, + day => $d, + hour => $h, + minute => $n, + second => $s, + ); + + return %hash; +} + + + + +=head1 SEE ALSO + +=over 8 + +=item * + +perldoc DateTime + +=back + + + +=cut + +1; diff --git a/lib/WebGUI/Form/Date.pm b/lib/WebGUI/Form/Date.pm index aacc36766..c4b4c7b5f 100644 --- a/lib/WebGUI/Form/Date.pm +++ b/lib/WebGUI/Form/Date.pm @@ -17,7 +17,6 @@ package WebGUI::Form::Date; use strict; use base 'WebGUI::Form::Text'; use WebGUI::Form::Hidden; -use WebGUI::Form::Text; use WebGUI::International; =head1 NAME @@ -28,6 +27,10 @@ Package WebGUI::Form::Date Accepts and returns and epoch date and creates a date picker control. +If the current or default value is a MySQL date string, accepts and returns +a MySQL date string. Note: Cannot do time zone conversion since it is not a +complete date/time string. + =head1 SEE ALSO This is a subclass of WebGUI::Form::Text. @@ -64,6 +67,9 @@ A default date is placed in the value field. Set this to "1" to leave it empty. If no value is specified, this will be used. Defaults to today and now. +If the defaultValue is a MySQL date string, this form control will return MySQL +date strings instead of epoch times. + =head4 profileEnabled Flag that tells the User Profile system that this is a valid form element in a User Profile @@ -108,20 +114,38 @@ Return the date in a human readable format for the Profile system. sub displayValue { my ($self) = @_; - return $self->session->datetime->epochToHuman($self->get("value"),"%z"); + if (!$self->get("defaultValue") || $self->get("defaultValue") =~ m/^\d+$/) { + return $self->session->datetime->epochToHuman($self->get("value"),"%z"); + } else { + # MySQL format + my $value = $self->get("value"); + } } #------------------------------------------------------------------- =head2 getValueFromPost ( ) -Returns a validated form post result. If the result does not pass validation, it returns undef instead. +Returns a validated form post result. If the result does not pass validation, +it returns undef instead. =cut sub getValueFromPost { my $self = shift; - return $self->session->datetime->setToEpoch($self->session->form->param($self->get("name"))); + if (!$self->get("defaultValue") || $self->get("defaultValue") =~ m/^\d+$/) { + # Epoch format + return $self->session->datetime->setToEpoch($self->session->form->param($self->get("name"))); + } else { + # MySQL format + # YY(YY)?-MM-DD + my $value = $self->session->form->param($self->get("name")); + + # NOTE: Cannot fix time zone since we don't have a complete date/time + + return $1 + if ($value =~ m/((?:\d{2}|\d{4})\D\d{2}\D\d{2})/); + } } #------------------------------------------------------------------- @@ -134,11 +158,17 @@ Renders a date picker control. sub toHtml { my $self = shift; + my $value; if ($self->get("_defaulted") && $self->get("noDate") ) { - $self->set("value",''); - } - else { - $self->set("value",$self->session->datetime->epochToSet($self->get("value"))); + # No default date + $value = $self->set("value",''); + } elsif (!$self->get("defaultValue") || $self->get("defaultValue") =~ m/^\d+$/) { + # Epoch format + $value = $self->set("value",$self->session->datetime->epochToSet($self->get("value"))); + } else { + # MySQL format + $value = $self->get("value"); + # NOTE: Cannot fix time zone since we don't have a complete date/time } my $language = WebGUI::International->new($self->session)->getLanguage($self->session->user->profileField("language"),"languageAbbreviation"); @@ -150,7 +180,14 @@ sub toHtml { $self->session->style->setScript($self->session->url->extras('calendar/calendar-setup.js'),{ type=>'text/javascript' }); $self->session->style->setLink($self->session->url->extras('calendar/calendar-win2k-1.css'), { rel=>"stylesheet", type=>"text/css", media=>"all" }); my $mondayFirst = $self->session->user->profileField("firstDayOfWeek") ? "1" : "0"; - return $self->SUPER::toHtml. '