diff --git a/docs/upgrades/upgrade_6.1.1-6.2.0.sql b/docs/upgrades/upgrade_6.1.1-6.2.0.sql index b8e77f1b5..16f64d33d 100644 --- a/docs/upgrades/upgrade_6.1.1-6.2.0.sql +++ b/docs/upgrades/upgrade_6.1.1-6.2.0.sql @@ -53,3 +53,6 @@ alter table WobjectProxy add proxyByCriteria int default 0; alter table WobjectProxy add resolveMultiples varchar(30) default "mostRecent"; alter table WobjectProxy add proxyCriteria text default NULL; +alter table IndexedSearch add column (forceSearchRoots smallint(1) default 1); +alter table DataForm_field add column (vertical smallint(1) default 1); +alter table DataForm_field add column (extras varchar(128)); diff --git a/lib/WebGUI/Wobject/DataForm.pm b/lib/WebGUI/Wobject/DataForm.pm index bd7761cd7..b9e803969 100644 --- a/lib/WebGUI/Wobject/DataForm.pm +++ b/lib/WebGUI/Wobject/DataForm.pm @@ -44,7 +44,9 @@ sub _createField { $param{size} = $data->{width}; $param{rows} = $data->{rows} || 5; $param{columns} = $data->{width}; - $param{vertical} = 1; + $param{vertical} = $data->{vertical}; + $param{extras} = $data->{extras}; + if ($data->{type} eq "checkbox") { $param{value} = ($data->{defaultValue} =~ /checked/i) ? 1 : ""; } @@ -261,7 +263,7 @@ sub getRecordTemplateVars { .WebGUI::Form::hidden({name=>"wid",value=>$self->get("wobjectId")}) .WebGUI::Form::hidden({name=>"func",value=>"process"}); my @tabs; - my $select = "select a.name, a.DataForm_fieldId, a.DataForm_tabId,a.label, a.status, a.isMailField, a.subtext, a.type, a.defaultValue, a.possibleValues, a.width, a.rows"; + my $select = "select a.name, a.DataForm_fieldId, a.DataForm_tabId,a.label, a.status, a.isMailField, a.subtext, a.type, a.defaultValue, a.possibleValues, a.width, a.rows, a.extras, a.vertical"; my $join; my $where = "where a.wobjectId=".$self->get("wobjectId"); if ($var->{entryId}) { @@ -298,7 +300,7 @@ sub getRecordTemplateVars { my $value = $data{value}; $value = WebGUI::DateTime::epochToHuman($value,"%z") if ($data{type} eq "date"); $value = WebGUI::DateTime::epochToHuman($value,"%z %Z") if ($data{type} eq "dateTime"); - push(@fields,{ + push(@fields, { "tab.field.form" => _createField(\%data), "tab.field.name" => $data{name}, "tab.field.tid" => $data{DataForm_tabId}, @@ -313,7 +315,7 @@ sub getRecordTemplateVars { }); } $sth->finish; - push(@tabs,{ + push(@tabs, { "tab.start" => '
', "tab.end" =>'
', "tab.sequence" => $tab{sequenceNumber}, @@ -321,7 +323,7 @@ sub getRecordTemplateVars { "tab.tid" => $tab{DataForm_tabId}, "tab.subtext" => $tab{subtext}, "tab.controls" => $self->_tabAdminIcons($tab{DataForm_tabId}), - "tab.field_loop" => \@fields + "tab.field_loop" => \@fields, }); } @@ -340,19 +342,24 @@ sub getRecordTemplateVars { my $value = $data{value}; $value = WebGUI::DateTime::epochToHuman($value,"%z") if ($data{type} eq "date"); $value = WebGUI::DateTime::epochToHuman($value) if ($data{type} eq "dateTime"); - push(@fields,{ - "field.form" => _createField(\%data), - "field.name" => $data{name}, - "field.tid" => $data{DataForm_tabId}, - "field.value" => $value, - "field.label" => $data{label}, - "field.isMailField" => $data{isMailField}, - "field.isHidden" => $hidden, - "field.isDisplayed" => ($data{status} eq "visible" && !$hidden), - "field.isRequired" => ($data{status} eq "required" && !$hidden), - "field.subtext" => $data{subtext}, - "field.controls" => $self->_fieldAdminIcons($data{DataForm_fieldId},$data{DataForm_tabId},$data{isMailField}) - }); + my %fieldProperties = ( + "form" => _createField(\%data), + "name" => $data{name}, + "tid" => $data{DataForm_tabId}, + "inTab".$data{DataForm_tabId} => 1, + "value" => $value, + "label" => $data{label}, + "isMailField" => $data{isMailField}, + "isHidden" => $hidden, + "isDisplayed" => ($data{status} eq "visible" && !$hidden), + "isRequired" => ($data{status} eq "required" && !$hidden), + "subtext" => $data{subtext}, + "controls" => $self->_fieldAdminIcons($data{DataForm_fieldId},$data{DataForm_tabId},$data{isMailField}) + ); + push(@fields, { map {("field.".$_ => $fieldProperties{$_})} keys(%fieldProperties) }); + foreach (keys(%fieldProperties)) { + $var->{"field.noloop.".$data{name}.".$_"} = $fieldProperties{$_}; + } } $sth->finish; $var->{field_loop} = \@fields; @@ -360,7 +367,7 @@ sub getRecordTemplateVars { $var->{tab_loop} = \@tabs; $var->{"form.send"} = WebGUI::Form::submit({value=>WebGUI::International::get(73, $self->get("namespace"))}); $var->{"form.save"} = WebGUI::Form::submit(); - $var->{"form.end"} = WebGUI::Form::formFooter(); + $var->{"form.end"} = WebGUI::Form::formFooter(); return $var; } @@ -670,6 +677,17 @@ sub www_editField { -label=>WebGUI::International::get(27, $_[0]->get("namespace")), -subtext=>WebGUI::International::get(28, $_[0]->get("namespace")), ); + $f->yesNo( + -name=>"vertical", + -value=>$field{vertical}, + -label=>WebGUI::International::get('editField-vertical-label', $_[0]->get("namespace")), + -subtext=>WebGUI::International::get('editField-vertical-subtext', $_[0]->get("namespace")) + ); + $f->text( + -name=>"extras", + -value=>$field{extras}, + -label=>WebGUI::International::get('editField-extras-label', $_[0]->get("namespace")) + ); $f->textarea( -name=>"possibleValues", -label=>WebGUI::International::get(24,$_[0]->get("namespace")), @@ -715,7 +733,9 @@ sub www_editFieldSave { possibleValues=>$session{form}{possibleValues}, defaultValue=>$session{form}{defaultValue}, subtext=>$session{form}{subtext}, - rows=>$session{form}{rows} + rows=>$session{form}{rows}, + vertical=>$session{form}{vertical}, + extras=>$session{form}{extras}, }, "1","1", "DataForm_tabId",$session{form}{tid}); $_[0]->reorderCollateral("DataForm_field","DataForm_fieldId", "DataForm_tabId",$session{form}{tid}) if ($session{form}{fid} ne "new"); if ($session{form}{proceed} eq "addField") { diff --git a/lib/WebGUI/Wobject/IndexedSearch.pm b/lib/WebGUI/Wobject/IndexedSearch.pm index c2f4c4a53..c21693244 100644 --- a/lib/WebGUI/Wobject/IndexedSearch.pm +++ b/lib/WebGUI/Wobject/IndexedSearch.pm @@ -16,6 +16,7 @@ use WebGUI::Wobject; use Tie::IxHash; use WebGUI::Utility; use WebGUI::Paginator; +use WebGUI::Page; our @ISA = qw(WebGUI::Wobject); @@ -37,9 +38,13 @@ sub new { defaultValue=>'default' }, searchRoot=>{ - fieldType=>'selectList', + fieldType=>'checkList', defaultValue=>'any' }, + forceSearchRoots=>{ + fieldType=>'yesNo', + defaultValue=>1 + }, users=>{ fieldType=>'selectList', defaultValue=>'any' @@ -140,7 +145,11 @@ sub www_edit { -multiple=>1, -vertical=>1, ); - + $properties->yesNo( + -name=>'forceSearchRoots', + -label=>WebGUI::International::get('edit-forceSearchRoots-label',$self->get("namespace")), + -value=>$self->getValue("forceSearchRoots") + ); # Content of specific user $properties->selectList ( -name=>'users', -options=>$self->_getUsers(), @@ -219,26 +228,6 @@ sub www_edit { } -#------------------------------------------------------------------- -sub www_editSave { - # default editSave overruled to build & save the pageList for faster retrieval. - my $self = shift; - return WebGUI::Privilege::insufficient() unless ($self->canEdit); - $self->SUPER::www_editSave(); - my (%pages, $pageList); - my $searchRoot = $self->get("searchRoot"); - if ($searchRoot =~ /any/i) { - $pageList = 'any'; - } else { - foreach my $pageId (split(/\n+/,$searchRoot)) { - %pages = (%pages, _getSearchablePages($pageId), $pageId => defined); - } - $pageList = join(" , ", keys %pages); - } - WebGUI::SQL->write("update IndexedSearch set pageList = ".quote($pageList)." where wobjectId = ".$self->get("wobjectId")); - return ''; -} - #------------------------------------------------------------------- sub www_view { my $self = shift; @@ -263,17 +252,18 @@ sub www_view { $var{submit} = WebGUI::Form::submit({value=>WebGUI::International::get(16, $self->get("namespace"))}); $var{"int.search"} = WebGUI::International::get(16,$self->get("namespace")); $var{wid} = $self->get("wobjectId"); - $var{numberOfResults} = '0'; - $var{"select_".$self->getValue("paginateAfter")} = "selected"; + $var{numberOfResults} = '0'; + $var{"select_".$self->getValue("paginateAfter")} = "selected"; # Do the search my $startTime = ($hasTimeHiRes) ? Time::HiRes::time() : time(); - my $filter = $self->_buildFilter; - my $search = WebGUI::Wobject::IndexedSearch::Search->new($self->getValue('indexName')); - $search->open; - my $results = $search->search($var{query},$filter); - $var{duration} = (($hasTimeHiRes) ? Time::HiRes::time() : time()) - $startTime; - $var{duration} = sprintf("%.3f", $var{duration}) if $hasTimeHiRes; # Duration rounded to 3 decimal places + my $filter = $self->_buildFilter; + + my $search = WebGUI::Wobject::IndexedSearch::Search->new($self->getValue('indexName')); + $search->open; + my $results = $search->search($var{query},$filter); + $var{duration} = (($hasTimeHiRes) ? Time::HiRes::time() : time()) - $startTime; + $var{duration} = sprintf("%.3f", $var{duration}) if $hasTimeHiRes; # Duration rounded to 3 decimal places # Let's see if the search returned any results if (defined ($results)) { @@ -379,21 +369,83 @@ sub www_view { } push(@{$var{languages}}, { value => $_, name => $languages->{$_}, selected => $selected }); } - + + # Create a loop with searchable page roots + my $rootData; + my @roots = split(/\n/, $self->get('searchRoot')); + my %checked = map {$_=>1} $session{cgi}->param("searchRoot"); + if (isIn('any', @roots)) { + foreach $rootData (WebGUI::Page->getAnonymousRoot->daughters) { + push (@{$var{searchRoots}}, { + value => $rootData->{'pageId'}, + menuTitle => $rootData->{'menuTitle'}, + title => $rootData->{'title'}, + urlizedTitle => $rootData->{'urlizedTitle'}, + checked => $checked{$rootData->{'pageId'}}, + }); + $var{"rootPage.".$rootData->{'urlizedTitle'}.".id"} = $rootData->{'pageId'}; + $var{"rootPage.".$rootData->{'urlizedTitle'}.".checked"} = $checked{$rootData->{'pageId'}}; + } + } else { + foreach (@roots) { + $rootData = WebGUI::Page->new($_); + push (@{$var{searchRoots}}, { + value => $rootData->get('pageId'), + menuTitle => $rootData->get('menuTitle'), + title => $rootData->get('title'), + urlizedTitle => $rootData->get('urlizedTitle'), + checked => $checked{$rootData->get('pageId')}, + }); + $var{"rootPage.".$rootData->get('urlizedTitle').".id"} = $rootData->get('pageId'); + $var{"rootPage.".$rootData->get('urlizedTitle').".checked"} = $checked{$rootData->get('pageId')}; + } + } + $var{"anyRootPage.checked"} = $checked{'any'}; # close the search $search->close; return $self->processTemplate($self->get("templateId"),\%var); } +#------------------------------------------------------------------- +sub _buildPageList { + my ($self, @userSpecifiedRoots, @roots, @allowedRoots, $pageId, @pages); + $self = shift; + + @userSpecifiedRoots = $session{cgi}->param("searchRoot"); + + if ((scalar(@userSpecifiedRoots) == 0) + || ($self->getValue("forceSearchRoots")) + || (isIn('any', @userSpecifiedRoots)) + ) { + @roots = split(/\n+/i, $self->get("searchRoot")); + } else { + @allowedRoots = split(/\n+/, $self->get("searchRoot")); + + foreach (@userSpecifiedRoots) { + push (@roots, $_) if (isIn($_, @allowedRoots)); + } + } + + foreach $pageId (@roots) { + WebGUI::Page->new($pageId)->traversePreOrder( + sub { + push(@pages, $_[0]->get('pageId')); + } + ); + } + + return [ @pages ]; +} + #------------------------------------------------------------------- sub _buildFilter { my $self = shift; my %filter = (); # pages - if($self->getValue('pageList') ne 'any') { - $filter{pageId} = [ split(/\n+/, $self->getValue('pageList')) ]; + if($self->get('searchRoot') !~ /any/i) { + $filter{pageId} = $self->_buildPageList; } # languages diff --git a/lib/WebGUI/i18n/English/DataForm.pm b/lib/WebGUI/i18n/English/DataForm.pm index 5b9bf0d80..de0be9bdd 100644 --- a/lib/WebGUI/i18n/English/DataForm.pm +++ b/lib/WebGUI/i18n/English/DataForm.pm @@ -299,12 +299,16 @@ WebGUI's administrative controls for this field.

+ +field.noloop.fieldName.property
+Except from within the field_loop it's also possible to access all formfields directly. To accomplish this you should use these variables. Call them with field.noloop.fieldName.property, where fieldName is the name of the field (not the label) and property is anyone of the properties supplied by the field_loop. If you want the form tag of field 'name' you should use anywhere in your template. If you want to know if the field is required use field.noloop.name.isRequired. +

form.send
A form button with the word "send" printed on it.

-form.save/b>
+form.save
A form button with the word "save" printed on it.

@@ -313,7 +317,7 @@ The end of the form.

*Only available if the user has already submitted the form.|, - lastUpdated => 1053948922 + lastUpdated => 1090575731 }, '72' => { @@ -348,6 +352,14 @@ Set the number of characters wide this field will be. Height
Set the number of characters tall this field will be. Only used on textarea and HTMLArea.

+ +Align vertical
+This property controls wheter radio- and checklists are layouted horizontally or vertically. +

+ +Extras
+Here you can enter additional tag properties for the field tag. For instance 'class="myClass"'. +

Possible Values
This field is used for the list types (like Checkbox List and Select List). Enter the values you wish to appear, one per line. @@ -358,7 +370,7 @@ Enter the default value (if any) for the field. For Yes/No fields, enter "yes"

|, - lastUpdated => 1053855075 + lastUpdated => 1090575731 }, '80' => { @@ -592,6 +604,21 @@ A conditional indicating whether this field exists for the mail subsystem of the lastUpdated => 1057208065 }, + 'editField-vertical-label' => { + message => q|Align vertical|, + lastUpdated => 1090575731 + }, + + 'editField-vertical-subtext' => { + message => q|This property only affects radio- and checklists.|, + lastUpdated => 1090575731 + }, + + 'editField-extras-label' => { + message => q|Extras|, + lastUpdated => 1090575731 + }, + }; 1; diff --git a/lib/WebGUI/i18n/English/IndexedSearch.pm b/lib/WebGUI/i18n/English/IndexedSearch.pm index 4b92e5a24..2de5b3a89 100644 --- a/lib/WebGUI/i18n/English/IndexedSearch.pm +++ b/lib/WebGUI/i18n/English/IndexedSearch.pm @@ -62,6 +62,16 @@ refine their search.

option.

value
The value of the option.

selected
A conditional indicating whether this option is selected or not.

+

searchRoots
A loop containing the available roots to search through. +

+title
The title of the pageroot.

+urlizedTitle
The urlizedTitle of the pageroot.

+menuTitle
The menu title of the pageroot.

+value
The value you should pass as a form param.

+checked
True if this pageroot is selected.

+

+

rootPage.urlizedTitle.id
This is a direct link to the value property of the rootpage identified with urlizedTitle that is also given by the value property of the searchRoots loop.

+

rootPage.urlizedTitle.checked
This is a direct link to the checked property of the rootpage identified with urlizedTitle that is also given by the checked property of the searchRoots loop.

firstPage
A link to the first page in the paginator.

lastPage
A link to the last page in the paginator.

nextPage
A link to the next page forward in the paginator. @@ -73,7 +83,7 @@ one page in the paginator. the first page.

isLastPage
A conditional indicating whether the visitor is viewing the last page.

|, - lastUpdated => 1070202325 + lastUpdated => 1090580644 }, '2' => { @@ -235,6 +245,7 @@ system
Page: Page title and synopsis
Profile: User Profiles
Wobject: Wobject Title and Description
Wobject details: All other wobject data. For example FAQ question, Calendar item, etc.

+

Force users to use selected roots
Enabling this option will cause the search to be over all of the selected page roots regardless of what the user entered via the search form.

Template
Select a template to layout your Search. The different templates have different functionality.

Paginate after
The number of results @@ -247,7 +258,12 @@ no preview.

highlight the search results in the preview you'll want to check this box.

Highlight color n
The colors that are used to highlight the corresponding words in the query. 

|, - lastUpdated => 1070195783 + lastUpdated => 1090580644 + }, + + 'edit-forceSearchRoots-label' => { + message => q|Force users to use the selected roots|, + lastUpdated => 1090580644 }, };