diff --git a/docs/migration.txt b/docs/migration.txt index da7f36653..7b88ba481 100644 --- a/docs/migration.txt +++ b/docs/migration.txt @@ -39,6 +39,10 @@ You must migrate your asset to use the new WebGUI::Definition::Asset class inste 9) You no longer have the "visible" element. It was a duplicate of "noFormPost", so use "noFormPost" instead. +10) You no longer have the "displayOnly" element. Make a custom form control instead. + +11) You no longer have the "allowEmpty" element. However, you can now specify an initial value in the "value" element, and set "defaultValue" to undef if you want to have an initial value but allow the field to become empty or undef. + Here's an example. use WebGUI::Definition::Asset ( diff --git a/lib/WebGUI/Asset.pm b/lib/WebGUI/Asset.pm index 609b71a96..277cdcfd7 100644 --- a/lib/WebGUI/Asset.pm +++ b/lib/WebGUI/Asset.pm @@ -908,7 +908,7 @@ sub getEditForm { $params{value} = [$params{value}]; } - %params = (%params, %fieldHash); + %params = (%fieldHash, %params); delete $params{tab}; delete $params{tableName}; @@ -1586,11 +1586,19 @@ sub new { my $sql = "select * from asset"; my $where = " where asset.assetId=?"; my $placeHolders = [$assetId]; - - foreach my $definition (@{$class->definition($session)}) { + + # join all the tables + my %tables; + foreach my $property ($class->getProperties) { + my $definition = $class->getProperty($property); + %tables{$definition->{tableName}} = 1; + } + foreach my $table (keys %tables) { $sql .= ",".$definition->{tableName}; $where .= " and (asset.assetId=".$definition->{tableName}.".assetId and ".$definition->{tableName}.".revisionDate=".$revisionDate.")"; } + + # fetch properties $properties = $session->db->quickHashRef($sql.$where, $placeHolders); unless (exists $properties->{assetId}) { $session->errorHandler->error("Asset $assetId $class $revisionDate is missing properties. Consult your database tables for corruption. "); @@ -1602,11 +1610,10 @@ sub new { if (defined $properties) { my $object = { _session=>$session, _properties => $properties }; bless $object, $class; - foreach my $definition (@{ $object->definition($session) }) { - foreach my $property (keys %{ $definition->{properties} }) { - if ($definition->{properties}->{$property}->{serialize} && $object->{_properties}->{$property} ne '') { - $object->{_properties}->{$property} = JSON->new->canonical->decode($object->{_properties}->{$property}); - } + foreach my $property ($object->getProperties) { + my $definition = $object->getProperty($property); + if ($definition->{serialize} && $object->{_properties}->{$property} ne '') { + $object->{_properties}->{$property} = JSON->new->canonical->decode($object->{_properties}->{$property}); } } return $object; @@ -2000,33 +2007,31 @@ sub processPropertiesFromFormPost { my $form = $self->session->form; my $overrides = $self->session->config->get("assets/".$self->get("className")."/fields"); - foreach my $definition (@{$self->definition($self->session)}) { - foreach my $property (keys %{$definition->{properties}}) { - my %params = %{$definition->{properties}{$property}}; + foreach my $property ($self->getProperties) { + my %params = %{$self->getProperty($property)}; - # apply config file changes - foreach my $key (keys %{$overrides->{$property}}) { - $params{$key} = $overrides->{$property}{$key}; - } - - # deal with properties that can't be posted through the form - if ($params{noFormPost}) { - if ($form->process("assetId") eq "new" && $self->get($property) eq "") { - $data{$property} = $params{defaultValue}; - } - next; - } - - # process the form element - $params{name} = $property; - $params{value} = $self->get($property); - $data{$property} = $form->process( - $property, - $params{fieldType}, - $params{defaultValue}, - \%params - ); + # apply config file changes + foreach my $key (keys %{$overrides->{$property}}) { + $params{$key} = $overrides->{$property}{$key}; } + + # deal with properties that can't be posted through the form + if ($params{noFormPost}) { + if ($form->process("assetId") eq "new" && $self->get($property) eq "") { + $data{$property} = $params{defaultValue}; + } + next; + } + + # process the form element + $params{name} = $property; + $params{value} = $self->get($property); + $data{$property} = $form->process( + $property, + $params{fieldType}, + $params{defaultValue}, + \%params + ); } $data{keywords} = $form->process("keywords"); if ($self->session->setting->get("metaDataEnabled")) { @@ -2283,76 +2288,59 @@ sub update { } # check the definition of all properties against what was given to us - foreach my $definition (reverse @{$self->definition($self->session)}) { - my %setPairs = (); + my %setPairs = (); + my %tableFields = (); + foreach my $property ($self->getProperties) { + + # skip a property unless it was passed in to update + next unless (exists $properties->{$property}); + + # get the property definition + my $propertyDefinition = $self->getProperty($property); # get a list of the fields available in this table so we don't try to insert # something for a field that doesn't exist - my %tableFields = (); - my $sth = $self->session->db->read('DESCRIBE `'.$definition->{tableName}.'`'); - while (my ($col) = $sth->array) { - $tableFields{$col} = 1; - } + my $table = $propertyDefinition->{tableName}; + unless (exists $tableFields{$table}) { + my $sth = $self->session->db->read('DESCRIBE `'.$table.'`'); + while (my ($col) = $sth->array) { + $tableFields{$table}{$col} = 1; + } + } - # deal with all the properties in this part of the definition - foreach my $property (keys %{$definition->{properties}}) { + # skip properties that aren't yet in the table + if (!exists $tableFields{$table}{$property}) { + $self->session->log->error("update() tried to set field named '".$property."' which doesn't exist in table '".$table."'"); + next; + } -# # skip a property unless it was specified to be set by the properties field or has a default value -# next unless (exists $properties->{$property} || exists $definition->{properties}{$property}{defaultValue}); - # skip a property unless it was specified to be set by the properties field - next unless (exists $properties->{$property}); - my $propertyDefinition = $definition->{properties}{$property}; - # skip a property if it has the display only flag set - next if ($propertyDefinition->{displayOnly}); + # use the update value + my $value = $properties->{$property}; + # use the current value because the update value was undef + unless (defined $value) { + $value = $self->get($property); + } - # skip properties that aren't yet in the table - if (!exists $tableFields{$property}) { - $self->session->log->error("update() tried to set field named '".$property."' which doesn't exist in table '".$definition->{tableName}."'"); - next; - } - - # use the update value - my $value = $properties->{$property}; - # use the current value because the update value was undef - unless (defined $value) { - $value = $self->get($property); - } - - # apply filter logic on a property to validate or fix it's value - if (exists $propertyDefinition->{filter}) { - my $filter = $propertyDefinition->{filter}; - $value = $self->$filter($value, $property); - } - - # if the value is undefined, use the default if possible - # unless allowEmpty has been set, do this for empty strings as well - if ( ( !defined $value || ( $value eq q{} && ! $propertyDefinition->{allowEmpty} ) ) - && exists $propertyDefinition->{defaultValue} ) { - $value = $propertyDefinition->{defaultValue}; - if (ref($value) eq 'ARRAY') { - $value = $value->[0]; - } - } - - # set the property - if ($propertyDefinition->{serialize}) { - $setPairs{$property} = JSON->new->canonical->encode($value); - } - else { - $setPairs{$property} = $value; - } - $self->{_properties}{$property} = $value; - } - - # if there's anything to update, then do so - if (scalar(keys %setPairs) > 0) { - my @values = values %setPairs; - my @columnNames = map { $_.'=?' } keys %setPairs; - push(@values, $self->getId, $self->get("revisionDate")); - $self->session->db->write("update ".$definition->{tableName}." set ".join(",",@columnNames)." where assetId=? and revisionDate=?",\@values); + # set the property + if ($propertyDefinition->{serialize}) { + $setPairs{$table}{$property} = JSON->new->canonical->encode($value); + } + else { + $setPairs{$table}{$property} = $value; + } + $self->{_properties}{$property} = $value; } } + # if there's anything to update, then do so + my $db = $self->session->db; + foreach my $table (keys %setPairs) { + my @values = values %{$setPairs{$table}}; + my @columnNames = map { $_.'=?' } keys %{$setPairs{$table}}; + push(@values, $self->getId, $self->get("revisionDate")); + $db->write("update ".$table." set ".join(",",@columnNames)." where assetId=? and revisionDate=?",\@values); + } + # we've changed something so we need to update our size $self->setSize(); diff --git a/lib/WebGUI/AssetAspect/RssFeed.pm b/lib/WebGUI/AssetAspect/RssFeed.pm index b1caab66f..87c58777d 100644 --- a/lib/WebGUI/AssetAspect/RssFeed.pm +++ b/lib/WebGUI/AssetAspect/RssFeed.pm @@ -115,8 +115,8 @@ sub definition { }, feedHeaderLinks => { fieldType => "checkList", - allowEmpty => 1, - defaultValue => "rss\natom", + value => "rss\natom", + defaultValue => undef, tab => "rss", options => do { my %headerLinksOptions; diff --git a/lib/WebGUI/Form/Control.pm b/lib/WebGUI/Form/Control.pm index b0b02d1a7..82f36231d 100644 --- a/lib/WebGUI/Form/Control.pm +++ b/lib/WebGUI/Form/Control.pm @@ -403,6 +403,20 @@ sub getValue { return $self->getValueFromPost; } +#------------------------------------------------------------------- + +=head2 getValueAsScalar + +Returns the value as a scalar, which means for complex types it's returned as a serialized string of some sort. + +=cut + +sub getValueAsScalar { + my $self = shift; + return $self->getValue; +} + + #------------------------------------------------------------------- =head2 getOriginalValue ( ) diff --git a/lib/WebGUI/i18n/English/WebGUI.pm b/lib/WebGUI/i18n/English/WebGUI.pm index f8947e664..9dff73b0e 100644 --- a/lib/WebGUI/i18n/English/WebGUI.pm +++ b/lib/WebGUI/i18n/English/WebGUI.pm @@ -2,6 +2,12 @@ package WebGUI::i18n::English::WebGUI; use strict; our $I18N = { + 'JSON Blob' => { + message => q|JSON Blob|, + context => q|The name of hte JSON Blob form control.|, + lastUpdated => 0, + }, + 'ok' => { message => q|OK|, context => q|used by database link and other things to give a message to the user that a test passed|,