Merge branch 'master' into survey
* master: (36 commits) Add a mutator for questionsAnswered, with tests. Fix i18n file namespace. Flesh out the recordResponses POD. Almost ready for more in depth testing. recordResponse tests (just a few) goto tests. Add POD stubs, fully document goto. Fix my stupid typo in the Shelf template with div. nextQuestions tests. Add section separator comments between the subroutines. Remove old discussion related items from the Article templates. matrix compare screen bugfix matrix bug fixes Add more AdminBar tests. Add tests for nextSectionid, nextSection, currentSection. Tests for createSurveyOrder and shuffle. Change ResponseJSON to use a proper mutator for startTime. Forward porting site starter css fix for clears and page content positioning. forward porting quotes in asset title fixTitle test forward port syndicated articles i18n template fix Forward port templated ITransact edit credentials screen. ...
This commit is contained in:
commit
7a42b4b241
49 changed files with 1659 additions and 280 deletions
|
|
@ -1,3 +1,13 @@
|
|||
7.6.7
|
||||
- fixed #9263: Thingy possibleValues processing, and List type autodetection.
|
||||
- fixed: Alter WebGUI::Asset::Template's update method so that it can import packages that use the old, deprecated headBlock property. The update method change is deprecatd.
|
||||
- fixed #9266: controls missing on product asset
|
||||
- fixed #9150: Edit Data Table - Cannot add column (David Delikat)
|
||||
- fixed #9261: Cart Payment Screen not templated
|
||||
- fixed #4124: Site starter uses floats in ways that cause problems
|
||||
- fixed #9274: AdminBar errors and fails when an asset class cannot be loaded
|
||||
- fixed #9301: Error in Shelf Template
|
||||
|
||||
7.6.6
|
||||
- fixed #8792: Image Preview gives ERROR in Collateral Manager
|
||||
- fixed #8774: Forum Rich Edit no longer supports indent/outdent
|
||||
|
|
@ -7,6 +17,13 @@
|
|||
- fixed #9219: Thingy After Save Search This Thing not showing all rows (SDH Consulting Group)
|
||||
- fixed #9231: Singleton workflows should not report an error when an attempt is made to run them again
|
||||
- fixed #9244: i18n for colin
|
||||
- fixed #9252: Thingy defaultValue length causes input to be truncated (SDH Consulting Group)
|
||||
- fixed #8937: Feeds in Calendar strip information
|
||||
- fixed #9063: Thingy - Time Field editing errors
|
||||
- fixed #9237: Payment Gateways all display "cash"
|
||||
- fixed #8816: PayDriver "Label" of the instance of the driver should be used instead of the generic name
|
||||
- fixed #4220: testEnvironment.pl unable to find WebGUI modules...
|
||||
- fixed #9279: "Read more" text in Syndicated Articles is not a label
|
||||
|
||||
7.6.5
|
||||
- security: A problem was discovered and fixed in which users could email executable attachments to a collaboration system and then when viewed online, could execute them.
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
docs/upgrades/packages-7.6.6/syndicated_articles.wgpkg
Normal file
BIN
docs/upgrades/packages-7.6.6/syndicated_articles.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.6.7/article-with-files.wgpkg
Normal file
BIN
docs/upgrades/packages-7.6.7/article-with-files.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.6.7/center_image.wgpkg
Normal file
BIN
docs/upgrades/packages-7.6.7/center_image.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.6.7/default_product.wgpkg
Normal file
BIN
docs/upgrades/packages-7.6.7/default_product.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.6.7/left_align_image.wgpkg
Normal file
BIN
docs/upgrades/packages-7.6.7/left_align_image.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.6.7/linked_image_with_caption.wgpkg
Normal file
BIN
docs/upgrades/packages-7.6.7/linked_image_with_caption.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.6.7/root_import_shelf-default.wgpkg
Normal file
BIN
docs/upgrades/packages-7.6.7/root_import_shelf-default.wgpkg
Normal file
Binary file not shown.
|
|
@ -29,6 +29,8 @@ my $quiet; # this line required
|
|||
my $session = start(); # this line required
|
||||
|
||||
# upgrade functions go here
|
||||
addMatrixEditListingTemplate( $session );
|
||||
lengthenThingyDefaultValues($session);
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
|
|
@ -42,6 +44,24 @@ finish($session); # this line required
|
|||
# print "DONE!\n" unless $quiet;
|
||||
#}
|
||||
|
||||
# Add editListingTemplate property to Matrix
|
||||
sub addMatrixEditListingTemplate {
|
||||
my $session = shift;
|
||||
print "Add editListingTemplate property to Matrix\t... " unless $quiet;
|
||||
$session->db->write("alter table Matrix add editListingTemplateId char(22)");
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
sub lengthenThingyDefaultValues {
|
||||
my $session = shift;
|
||||
print "\tMake sure that Thingy fields can have a default value size appropriate to their field type... " unless $quiet;
|
||||
# and here's our code
|
||||
$session->db->write('alter table Thingy_fields modify defaultValue longtext');
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
|
|
|
|||
123
docs/upgrades/upgrade_7.6.6-7.6.7.pl
Normal file
123
docs/upgrades/upgrade_7.6.6-7.6.7.pl
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2008 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
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
our ($webguiRoot);
|
||||
|
||||
BEGIN {
|
||||
$webguiRoot = "../..";
|
||||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Storage;
|
||||
use WebGUI::Asset;
|
||||
|
||||
|
||||
my $toVersion = '7.6.7';
|
||||
my $quiet; # this line required
|
||||
|
||||
|
||||
my $session = start(); # this line required
|
||||
|
||||
# upgrade functions go here
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
#sub exampleFunction {
|
||||
# my $session = shift;
|
||||
# print "\tWe're doing some stuff here that you should know about... " unless $quiet;
|
||||
# # and here's our code
|
||||
# print "DONE!\n" unless $quiet;
|
||||
#}
|
||||
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add a package to the import node
|
||||
sub addPackage {
|
||||
my $session = shift;
|
||||
my $file = shift;
|
||||
|
||||
# Make a storage location for the package
|
||||
my $storage = WebGUI::Storage->createTemp( $session );
|
||||
$storage->addFileFromFilesystem( $file );
|
||||
|
||||
# Import the package into the import node
|
||||
my $package = WebGUI::Asset->getImportNode($session)->importPackage( $storage );
|
||||
|
||||
# Make the package not a package anymore
|
||||
$package->update({ isPackage => 0 });
|
||||
|
||||
# Set the default flag for templates added
|
||||
my $assetIds
|
||||
= $package->getLineage( ['self','descendants'], {
|
||||
includeOnlyClasses => [ 'WebGUI::Asset::Template' ],
|
||||
} );
|
||||
for my $assetId ( @{ $assetIds } ) {
|
||||
my $asset = WebGUI::Asset->newByDynamicClass( $session, $assetId );
|
||||
if ( !$asset ) {
|
||||
print "Couldn't instantiate asset with ID '$assetId'. Please check package '$file' for corruption.\n";
|
||||
next;
|
||||
}
|
||||
$asset->update( { isDefault => 1 } );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub start {
|
||||
my $configFile;
|
||||
$|=1; #disable output buffering
|
||||
GetOptions(
|
||||
'configFile=s'=>\$configFile,
|
||||
'quiet'=>\$quiet
|
||||
);
|
||||
my $session = WebGUI::Session->open($webguiRoot,$configFile);
|
||||
$session->user({userId=>3});
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Upgrade to ".$toVersion});
|
||||
return $session;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub finish {
|
||||
my $session = shift;
|
||||
updateTemplates($session);
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->commit;
|
||||
$session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".$session->datetime->time().")");
|
||||
$session->close();
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub updateTemplates {
|
||||
my $session = shift;
|
||||
return undef unless (-d "packages-".$toVersion);
|
||||
print "\tUpdating packages.\n" unless ($quiet);
|
||||
opendir(DIR,"packages-".$toVersion);
|
||||
my @files = readdir(DIR);
|
||||
closedir(DIR);
|
||||
my $newFolder = undef;
|
||||
foreach my $file (@files) {
|
||||
next unless ($file =~ /\.wgpkg$/);
|
||||
# Fix the filename to include a path
|
||||
$file = "packages-" . $toVersion . "/" . $file;
|
||||
addPackage( $session, $file );
|
||||
}
|
||||
}
|
||||
|
||||
#vim:ft=perl
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package WebGUI;
|
||||
|
||||
|
||||
our $VERSION = '7.6.6';
|
||||
our $VERSION = '7.6.7';
|
||||
our $STATUS = "beta";
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -226,11 +226,78 @@ sub getEditForm {
|
|||
my $session = $self->session;
|
||||
my $db = $session->db;
|
||||
my $matrixId = $self->getParent->getId;
|
||||
my $tabform = $self->next::method();
|
||||
my $i18n = WebGUI::International->new($session, 'Asset_MatrixListing');
|
||||
my $func = $session->form->process("func");
|
||||
|
||||
my $form = WebGUI::HTMLForm->new($session);
|
||||
|
||||
if ($func eq "add" || ( $func eq "editSave" && $session->form->process("assetId") eq "new")) {
|
||||
$form->hidden(
|
||||
-name =>'assetId',
|
||||
-value =>'new',
|
||||
);
|
||||
$form->hidden(
|
||||
-name =>'class',
|
||||
-value =>'WebGUI::Asset::MatrixListing',
|
||||
);
|
||||
}
|
||||
$form->hidden(
|
||||
-name =>'func',
|
||||
-value =>'editSave',
|
||||
);
|
||||
$form->text(
|
||||
-name =>'title',
|
||||
-defaultValue =>'Untitled',
|
||||
-label =>$i18n->get("product name label"),
|
||||
-hoverHelp =>$i18n->get('product name description'),
|
||||
-value =>$self->getValue('title'),
|
||||
);
|
||||
$form->image(
|
||||
-name =>'screenshots',
|
||||
-defaultValue =>undef,
|
||||
-maxAttachments =>20,
|
||||
-label =>$i18n->get("screenshots label"),
|
||||
-hoverHelp =>$i18n->get("screenshots description"),,
|
||||
-value =>$self->getValue('screenshots'),
|
||||
);
|
||||
$form->HTMLArea(
|
||||
-name =>'description',
|
||||
-defaultValue =>undef,
|
||||
-label =>$i18n->get("description label"),
|
||||
-hoverHelp =>$i18n->get("description description"),
|
||||
-value =>$self->getValue('description'),
|
||||
);
|
||||
$form->text(
|
||||
-name =>'version',
|
||||
-defaultValue =>undef,
|
||||
-label =>$i18n->get("version label"),
|
||||
-hoverHelp =>$i18n->get("version description"),
|
||||
-value =>$self->getValue('version'),
|
||||
);
|
||||
$form->text(
|
||||
-name =>'manufacturerName',
|
||||
-defaultValue =>undef,
|
||||
-label =>$i18n->get("manufacturerName label"),
|
||||
-hoverHelp =>$i18n->get("manufacturerName description"),
|
||||
-value =>$self->getValue('manufacturerName'),
|
||||
);
|
||||
$form->url(
|
||||
-name =>'manufacturerURL',
|
||||
-defaultValue =>undef,
|
||||
-label =>$i18n->get("manufacturerURL label"),
|
||||
-hoverHelp =>$i18n->get("manufacturerURL description"),
|
||||
-value =>$self->getValue('manufacturerURL'),
|
||||
);
|
||||
$form->url(
|
||||
-name =>'productURL',
|
||||
-defaultValue =>undef,
|
||||
-label =>$i18n->get("productURL label"),
|
||||
-hoverHelp =>$i18n->get("productURL description"),
|
||||
-value =>$self->getValue('productURL'),
|
||||
);
|
||||
|
||||
foreach my $category (keys %{$self->getParent->getCategories}) {
|
||||
$tabform->getTab('properties')->raw('<tr><td colspan="2"><b>'.$category.'</b></td></tr>');
|
||||
$form->raw('<tr><td colspan="2"><b>'.$category.'</b></td></tr>');
|
||||
my $attributes;
|
||||
if ($session->form->process('func') eq 'add'){
|
||||
$attributes = $db->read("select * from Matrix_attribute where category = ? and assetId = ?",
|
||||
|
|
@ -246,10 +313,13 @@ sub getEditForm {
|
|||
$attribute->{label} = $attribute->{name};
|
||||
$attribute->{subtext} = $attribute->{description};
|
||||
$attribute->{name} = 'attribute_'.$attribute->{attributeId};
|
||||
$tabform->getTab("properties")->dynamicField(%{$attribute});
|
||||
$form->dynamicField(%{$attribute});
|
||||
}
|
||||
}
|
||||
return $tabform;
|
||||
|
||||
$form->submit();
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -777,7 +847,12 @@ sub www_edit {
|
|||
my $i18n = WebGUI::International->new($self->session, "Asset_MatrixListing");
|
||||
return $self->session->privilege->insufficient() unless $self->canEdit;
|
||||
return $self->session->privilege->locked() unless $self->canEditIfLocked;
|
||||
return $self->getAdminConsole->render($self->getEditForm->print,$i18n->get('edit matrix listing title'));
|
||||
|
||||
my $var = $self->get;
|
||||
my $matrix = $self->getParent;
|
||||
$var->{form} = $self->getEditForm->print;
|
||||
|
||||
return $matrix->processStyle($self->processTemplate($var,$matrix->get("editListingTemplateId")));
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -812,6 +887,7 @@ sub www_getAttributes {
|
|||
$attribute->{label} = $attribute->{name};
|
||||
$attribute->{attributeId} =~ s/-/_____/g;
|
||||
if ($attribute->{fieldType} eq 'MatrixCompare'){
|
||||
$attribute->{compareColor} = $self->getParent->getCompareColor($attribute->{value});
|
||||
$attribute->{value} = WebGUI::Form::MatrixCompare->new($self->session,$attribute)->getValueAsHtml;
|
||||
}
|
||||
if($session->scratch->get('stickied_'.$attribute->{attributeId})){
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ use base 'WebGUI::Asset';
|
|||
use WebGUI::International;
|
||||
use WebGUI::Asset::Template::HTMLTemplate;
|
||||
use WebGUI::Utility;
|
||||
use Clone qw/clone/;
|
||||
|
||||
|
||||
=head1 NAME
|
||||
|
|
@ -401,6 +402,30 @@ sub processRaw {
|
|||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 update
|
||||
|
||||
Override update from Asset.pm to handle backwards compatibility with the old
|
||||
packages that contain headBlocks.
|
||||
|
||||
This method is deprecated and will be removed in the future. Don't plan
|
||||
on this being here.
|
||||
|
||||
=cut
|
||||
|
||||
sub update {
|
||||
my $self = shift;
|
||||
my $requestedProperties = shift;
|
||||
my $properties = clone($requestedProperties);
|
||||
if (exists $properties->{headBlock}) {
|
||||
$properties->{extraHeadTags} .= $properties->{headBlock};
|
||||
delete $properties->{headBlock};
|
||||
}
|
||||
$self->SUPER::update($properties);
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
sub www_edit {
|
||||
my $self = shift;
|
||||
|
|
|
|||
|
|
@ -1877,13 +1877,15 @@ sub www_ical {
|
|||
# Summary (the title)
|
||||
# Wrapped at 75 columns
|
||||
$ical .= $self->wrapIcal("SUMMARY:".$event->get("title"))."\r\n";
|
||||
|
||||
|
||||
# Description (the text)
|
||||
# Wrapped at 75 columns
|
||||
$ical .= $self->wrapIcal("DESCRIPTION:".$event->get("description"))."\r\n";
|
||||
|
||||
|
||||
|
||||
|
||||
# Location (the text)
|
||||
# Wrapped at 75 columns
|
||||
$ical .= $self->wrapIcal("LOCATION:".$event->get("location"))."\r\n";
|
||||
|
||||
# X-WEBGUI lines
|
||||
if ($event->get("groupIdView")) {
|
||||
$ical .= "X-WEBGUI-GROUPIDVIEW:".$event->get("groupIdView")."\r\n";
|
||||
|
|
@ -1893,11 +1895,11 @@ sub www_ical {
|
|||
}
|
||||
$ical .= "X-WEBGUI-URL:".$event->get("url")."\r\n";
|
||||
$ical .= "X-WEBGUI-MENUTITLE:".$event->get("menuTitle")."\r\n";
|
||||
|
||||
|
||||
$ical .= qq{END:VEVENT\r\n};
|
||||
}
|
||||
# ENDVEVENT
|
||||
|
||||
|
||||
$ical .= qq{END:VCALENDAR\r\n};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,14 @@ sub definition {
|
|||
hoverHelp =>$i18n->get('compare template description'),
|
||||
label =>$i18n->get('compare template label'),
|
||||
},
|
||||
editListingTemplateId=>{
|
||||
defaultValue =>"matrixtmpl000000000004",
|
||||
fieldType =>"template",
|
||||
tab =>"display",
|
||||
namespace =>"Matrix/EditListing",
|
||||
hoverHelp =>$i18n->get('edit listing template description'),
|
||||
label =>$i18n->get('edit listing template label'),
|
||||
},
|
||||
defaultSort=>{
|
||||
fieldType =>"selectBox",
|
||||
tab =>"display",
|
||||
|
|
@ -326,7 +334,7 @@ sub getCompareColor {
|
|||
elsif($value == 3){
|
||||
return $self->get('compareColorFreeAddOn');
|
||||
}
|
||||
elsif($value == 3){
|
||||
elsif($value == 4){
|
||||
return $self->get('compareColorYes');
|
||||
}
|
||||
|
||||
|
|
@ -656,6 +664,10 @@ sub www_compare {
|
|||
'text/javascript'});
|
||||
$self->session->style->setLink($self->session->url->extras('yui/build/datatable/assets/skins/sam/datatable.css'),
|
||||
{type =>'text/css', rel=>'stylesheet'});
|
||||
$self->session->style->setScript($self->session->url->extras('hoverhelp.js'), {type =>
|
||||
'text/javascript'});
|
||||
$self->session->style->setLink($self->session->url->extras('hoverhelp.css'),
|
||||
{type =>'text/css', rel=>'stylesheet'});
|
||||
|
||||
my $maxComparisons;
|
||||
if($self->session->user->isVisitor){
|
||||
|
|
@ -673,7 +685,7 @@ sub www_compare {
|
|||
|
||||
$var->{javascript} = "<script type='text/javascript'>\n".
|
||||
'var listingIds = new Array('.join(", ",map {'"'.$_.'"'} @listingIds).");\n".
|
||||
'var responseFields = new Array("attributeId", "name", "fieldType", "checked", '.join(", ",map {'"'.$_.'"'} @responseFields).");\n".
|
||||
'var responseFields = new Array("attributeId", "name", "description","fieldType", "checked", '.join(", ",map {'"'.$_.'"'} @responseFields).");\n".
|
||||
"var maxComparisons = ".$maxComparisons.";\n".
|
||||
"var matrixUrl = '".$self->getUrl."';\n".
|
||||
"</script>";
|
||||
|
|
@ -906,11 +918,9 @@ sub www_getCompareFormData {
|
|||
my $form = $session->form;
|
||||
my $sort = shift || $session->scratch->get('matrixSort') || $self->get('defaultSort');
|
||||
my $sortDirection = ' desc';
|
||||
=cut
|
||||
if ( WebGUI::Utility::isIn($sort, qw(revisionDate score)) ) {
|
||||
$sortDirection = " desc";
|
||||
}
|
||||
=cut
|
||||
# if ( WebGUI::Utility::isIn($sort, qw(revisionDate score)) ) {
|
||||
# $sortDirection = " desc";
|
||||
# }
|
||||
my @results;
|
||||
my @listingIds = $self->session->form->checkList("listingId");
|
||||
|
||||
|
|
@ -1024,7 +1034,8 @@ sub www_getCompareListData {
|
|||
$listing->incrementCounter("compares");
|
||||
my $listingId_safe = $listingId;
|
||||
$listingId_safe =~ s/-/_____/g;
|
||||
push(@columnDefs,{key=>$listingId_safe,label=>$listing->get('title'),formatter=>"formatColors"});
|
||||
push(@columnDefs,{key=>$listingId_safe,label=>$listing->get('title'),formatter=>"formatColors",
|
||||
url=>$listing->getUrl});
|
||||
}
|
||||
|
||||
my $jsonOutput;
|
||||
|
|
@ -1032,7 +1043,7 @@ sub www_getCompareListData {
|
|||
|
||||
foreach my $category (keys %{$self->getCategories}) {
|
||||
push(@results,{name=>$category,fieldType=>'category'});
|
||||
my $fields = " a.name, a.fieldType, a.attributeId ";
|
||||
my $fields = " a.name, a.fieldType, a.attributeId, a.description ";
|
||||
my $from = "from Matrix_attribute a";
|
||||
my $tableCount = "b";
|
||||
foreach my $listingId (@listingIds) {
|
||||
|
|
@ -1049,7 +1060,12 @@ sub www_getCompareListData {
|
|||
) });
|
||||
}
|
||||
foreach my $result (@results){
|
||||
unless($result->{fieldType} eq 'category'){
|
||||
if($result->{fieldType} eq 'category'){
|
||||
foreach my $columnDef (@columnDefs) {
|
||||
$result->{$columnDef->{key}} = $columnDef->{label};
|
||||
}
|
||||
}
|
||||
else{
|
||||
foreach my $listingId (@listingIds) {
|
||||
$result->{attributeId} =~ s/-/_____/g;
|
||||
my $listingId_safe = $listingId;
|
||||
|
|
|
|||
|
|
@ -820,7 +820,7 @@ sub prepareShowSurveyTemplate {
|
|||
$section->{'totalQuestions'} = @{$self->response->surveyOrder};
|
||||
$section->{'showProgress'} = $self->get('showProgress');
|
||||
$section->{'showTimeLimit'} = $self->get('showTimeLimit');
|
||||
$section->{'minutesLeft'} = int((($self->response->{startTime} + (60 * $self->get('timeLimit'))) - time())/60);
|
||||
$section->{'minutesLeft'} = int((($self->response->startTime() + (60 * $self->get('timeLimit'))) - time())/60);
|
||||
|
||||
my $out = $self->processTemplate( $section, $self->get("surveyQuestionsId") );
|
||||
|
||||
|
|
@ -953,7 +953,6 @@ sub getResponseId {
|
|||
$self->loadBothJSON($responseId);
|
||||
$self->response->createSurveyOrder();
|
||||
$self->{responseId} = $responseId;
|
||||
$self->response->{startTime} = $time;
|
||||
$self->saveResponseJSON();
|
||||
|
||||
} ## end if ( $haveTaken < $allowedTakes)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ use strict;
|
|||
use JSON;
|
||||
use Data::Dumper;
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 new ( $json, $log, $survey )
|
||||
|
||||
Object constructor.
|
||||
|
|
@ -63,13 +65,12 @@ sub new {
|
|||
my $self = defined $temp ? $temp : {};
|
||||
$self->{survey} = $survey;
|
||||
$self->{log} = $log;
|
||||
$self->{surveyOrder}
|
||||
= defined $temp->{surveyOrder}
|
||||
? $temp->{surveyOrder}
|
||||
: []; #an array of question addresses, with the third member being an array of answers
|
||||
$self->{responses} = defined $temp->{responses} ? $temp->{responses} : {};
|
||||
$self->{lastResponse} = defined $temp->{lastResponse} ? $temp->{lastResponse} : -1;
|
||||
$self->{responses} = defined $temp->{responses} ? $temp->{responses} : {};
|
||||
$self->{lastResponse} = defined $temp->{lastResponse} ? $temp->{lastResponse} : -1;
|
||||
$self->{questionsAnswered} = defined $temp->{questionsAnswered} ? $temp->{questionsAnswered} : 0;
|
||||
$self->{startTime} = defined $temp->{startTime} ? $temp->{startTime} : time();
|
||||
#an array of question addresses, with the third member being an array of answers
|
||||
$self->{surveyOrder} = defined $temp->{surveyOrder} ? $temp->{surveyOrder} : [];
|
||||
bless( $self, $class );
|
||||
return $self;
|
||||
} ## end sub new
|
||||
|
|
@ -122,6 +123,14 @@ sub createSurveyOrder {
|
|||
$self->{surveyOrder} = $order;
|
||||
} ## end sub createSurveyOrder
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 shuffle ( @array )
|
||||
|
||||
Returns the contents of @array in a random order.
|
||||
|
||||
=cut
|
||||
|
||||
sub shuffle {
|
||||
my @a = splice @_;
|
||||
for my $i ( 0 .. $#a ) {
|
||||
|
|
@ -131,6 +140,14 @@ sub shuffle {
|
|||
return @a;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 freeze
|
||||
|
||||
Serializes the object to JSON, after deleting the log and survey objects stored in it.
|
||||
|
||||
=cut
|
||||
|
||||
sub freeze {
|
||||
my $self = shift;
|
||||
my %temp = %{$self};
|
||||
|
|
@ -139,16 +156,43 @@ sub freeze {
|
|||
return to_json( \%temp );
|
||||
}
|
||||
|
||||
#Hash the survey timed out?
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#Has the survey timed out?
|
||||
|
||||
=head2 hasTimedOut ( $limit )
|
||||
|
||||
Checks to see whether this survey has timed out, based on the internally stored starting
|
||||
time, and $limit.
|
||||
|
||||
=head3 $limit
|
||||
|
||||
How long the user has to take the survey, in minutes.
|
||||
|
||||
=cut
|
||||
|
||||
sub hasTimedOut{
|
||||
my $self=shift;
|
||||
my $limit = shift;
|
||||
return 1 if($self->{startTime} + ($limit * 60) < time() and $limit > 0);
|
||||
return 1 if($self->startTime() + ($limit * 60) < time() and $limit > 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#the index of the last surveyOrder entry shown
|
||||
|
||||
=head2 lastResponse ([ $responseIndex ])
|
||||
|
||||
Mutator for the index of the last surveyOrder entry shown. With no arguments,
|
||||
returns the lastResponse index.
|
||||
|
||||
=head3 $responseIndex
|
||||
|
||||
If defined, sets the lastResponse to $responseIndex.
|
||||
|
||||
=cut
|
||||
|
||||
sub lastResponse {
|
||||
my $self = shift;
|
||||
my $res = shift;
|
||||
|
|
@ -160,27 +204,177 @@ sub lastResponse {
|
|||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 questionsAnswered ([ $questionsAnswered ])
|
||||
|
||||
Mutator for the number of questions answered. With no arguments,
|
||||
does a set.
|
||||
|
||||
=head3 $questionsAnswered.
|
||||
|
||||
If defined, increments the number of questions by $questionsAnswered
|
||||
|
||||
=cut
|
||||
|
||||
sub questionsAnswered {
|
||||
my $self = shift;
|
||||
my $answered = shift;
|
||||
if ( defined $answered ) {
|
||||
$self->{questionsAnswered} += $answered;
|
||||
}
|
||||
else {
|
||||
return $self->{questionsAnswered};
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 startTime ([ $newStartTime ])
|
||||
|
||||
Mutator for the time the user began the survey. With no arguments,
|
||||
returns the startTime.
|
||||
|
||||
=head3 $newStarttime
|
||||
|
||||
If defined, sets the starting time to $newStartTime.
|
||||
|
||||
=cut
|
||||
|
||||
sub startTime {
|
||||
my $self = shift;
|
||||
my $newTime = shift;
|
||||
if ( defined $newTime ) {
|
||||
$self->{startTime} = $newTime;
|
||||
}
|
||||
else {
|
||||
return $self->{startTime};
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#array of addresses in which the survey should be presented
|
||||
|
||||
=head2 surveyOrder
|
||||
|
||||
Accessor for the survey order data structure. It is a deep set of arrays, similar in
|
||||
structure to a WebGUI::Asset::Wobject::Survey::SurveyJSON address.
|
||||
|
||||
[ $sectionIndex, $questionIndex, [ $answerIndex1, $answerIndex2, ....]
|
||||
|
||||
There is one array element for every section and address in the survey.
|
||||
|
||||
If there are no questions, or no addresses, those array elements will not be present.
|
||||
|
||||
=cut
|
||||
|
||||
sub surveyOrder {
|
||||
my $self = shift;
|
||||
return $self->{surveyOrder};
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 nextSectionId
|
||||
|
||||
Relative to the surveyOrder and the lastResponse index, get the index of the
|
||||
next section. Note, based on the number of questions in an section, this can
|
||||
be the same as the current section index.
|
||||
|
||||
=cut
|
||||
|
||||
sub nextSectionId {
|
||||
my $self = shift;
|
||||
return undef if $self->surveyEnd();
|
||||
return $self->surveyOrder->[ $self->lastResponse + 1 ]->[0];
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 nextSection
|
||||
|
||||
Relative to the surveyOrder and the lastResponse index, gets the next section.
|
||||
Note, based on the number of questions in a section, this can be the same as
|
||||
the current section.
|
||||
|
||||
=cut
|
||||
|
||||
sub nextSection {
|
||||
my $self = shift;
|
||||
return {} if $self->surveyEnd();
|
||||
return $self->survey->section( [ $self->surveyOrder->[ $self->lastResponse + 1 ]->[0] ] );
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 currentSection
|
||||
|
||||
Relative to the surveyOrder and the lastResponse index, get the current section.
|
||||
|
||||
=cut
|
||||
|
||||
sub currentSection {
|
||||
my $self = shift;
|
||||
return $self->survey->section( [ $self->surveyOrder->[ $self->lastResponse ]->[0] ] );
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 recordResponses ($session, $responses)
|
||||
|
||||
Takes survey responses and puts them into the response hash of this object. Does terminal
|
||||
handling for sections and questions, and goto processing. Advances the survey page if
|
||||
all required questions have been answered.
|
||||
|
||||
=head3 $session
|
||||
|
||||
A WebGUI session object
|
||||
|
||||
=head3 $responses
|
||||
|
||||
A hash ref of form param data. Each element will look like:
|
||||
|
||||
{
|
||||
"__qid__comment" => "question comment",
|
||||
"__aid__" => "answer",
|
||||
"__aid__comment" => "answer comment",
|
||||
}
|
||||
|
||||
where __qid__ is a question id, as described in L<nextQuestions>, and __aid__ is an
|
||||
answer id, also described there.
|
||||
|
||||
=head3 terminal processing
|
||||
|
||||
Terminal processing for a section and its questions and answers are handled in
|
||||
order. The terminalUrl setting in a question overrides the terminalUrl setting
|
||||
for its section. Similarly, with questions and answers, the last terminalUrl
|
||||
setting of the set of questions is what is returned for the page, with the questions
|
||||
and answers being answered in surveyOrder.
|
||||
|
||||
=head3 goto processing
|
||||
|
||||
gotos are handled similarly as with terminalUrls. The last goto in the set of questions
|
||||
wins.
|
||||
|
||||
=head3 responses data structure
|
||||
|
||||
This method also builds an internal data structure with the users' responses. It
|
||||
is set up like this:
|
||||
|
||||
responses => {
|
||||
__qid__ => {
|
||||
comment => "question comment",
|
||||
},
|
||||
__aid__ => {
|
||||
time => time(),
|
||||
comment => "answer comment",
|
||||
value => "answer value",
|
||||
},
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
sub recordResponses {
|
||||
my $self = shift;
|
||||
my $session = shift;
|
||||
|
|
@ -217,7 +411,7 @@ sub recordResponses {
|
|||
#There were no questions in the section just displayed, so increment the lastResponse by one
|
||||
if ( ref $questions ne 'ARRAY' ) {
|
||||
$self->lastResponse( $self->lastResponse + 1 );
|
||||
return [ $terminal, $terminalUrl ];
|
||||
return [ $sterminal, $terminalUrl ];
|
||||
}
|
||||
|
||||
for my $question (@$questions) {
|
||||
|
|
@ -234,7 +428,7 @@ sub recordResponses {
|
|||
{
|
||||
|
||||
$aAnswered = 1;
|
||||
if ( $mcTypes{ $question->{questionType} } ) {
|
||||
if ( exists $mcTypes{ $question->{questionType} } ) {
|
||||
$self->responses->{ $answer->{id} }->{value} = $answer->{recordedAnswer};
|
||||
}
|
||||
else {
|
||||
|
|
@ -253,7 +447,9 @@ sub recordResponses {
|
|||
} ## end if ( defined( $responses...
|
||||
} ## end for my $answer ( @{ $question...
|
||||
$qAnswered = 0 if ( !$aAnswered and $question->{required} );
|
||||
$self->{questionsAnswered}++ if($aAnswered);
|
||||
if ($aAnswered) {
|
||||
$self->questionsAnswered( +1 );
|
||||
}
|
||||
} ## end for my $question (@$questions)
|
||||
|
||||
#if all responses completed, move the lastResponse index to the last question shown
|
||||
|
|
@ -272,6 +468,20 @@ sub recordResponses {
|
|||
return [ $terminal, $terminalUrl ];
|
||||
} ## end sub recordResponses
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 goto ( $variable )
|
||||
|
||||
Looks through all sections and questions for their variable key, in order. If the requested
|
||||
$variable matches a variable, then the lastResponse is set so that that section or question
|
||||
is the next displayed. If more than one section or question matches, then the first is used.
|
||||
|
||||
=head3 $variable
|
||||
|
||||
The variable to look for in all sections and questions.
|
||||
|
||||
=cut
|
||||
|
||||
sub goto {
|
||||
my $self = shift;
|
||||
my $goto = shift;
|
||||
|
|
@ -289,6 +499,12 @@ sub goto {
|
|||
}
|
||||
} ## end sub goto
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getPreviousAnswer
|
||||
|
||||
=cut
|
||||
|
||||
sub getPreviousAnswer {
|
||||
my $self = shift;
|
||||
my $questionParam = shift;
|
||||
|
|
@ -304,12 +520,33 @@ sub getPreviousAnswer {
|
|||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 nextQuestions
|
||||
|
||||
Returns an array ref of the next questions in the survey. The number of questions
|
||||
returned is set by the questionsPerPage property of the next section, as determined
|
||||
by nextSectionId rather than logical section ordering.
|
||||
|
||||
If no questions are available, then it returns an empty array ref.
|
||||
|
||||
Each element of the array ref is a question data structure, from the
|
||||
WebGUI::Asset::Wobject::Survey::SurveyJSON class, with a section sid field (index of
|
||||
the containing section) and question id (section and question id concatenated with a
|
||||
'-') added. The answers array of the question contains answer data structures, also
|
||||
from WebGUI::Asset::Wobject::Survey::SurveyJSON, with an id field which is the section,
|
||||
question and answer indexes concatentated together with dashes.
|
||||
|
||||
Section and question [[var]] replacements in text fields.
|
||||
|
||||
All questions and answers are safe copies of the survey data.
|
||||
|
||||
=cut
|
||||
|
||||
sub nextQuestions {
|
||||
my $self = shift;
|
||||
|
||||
if ( $self->lastResponse >= $#{ $self->surveyOrder } ) {
|
||||
return [];
|
||||
}
|
||||
return [] if $self->surveyEnd;
|
||||
|
||||
my $nextSectionId = $self->nextSectionId;
|
||||
|
||||
|
|
@ -334,22 +571,37 @@ sub nextQuestions {
|
|||
$question{id} = "$$qAddy[0]-$$qAddy[1]";
|
||||
$question{sid} = "$$qAddy[0]";
|
||||
for ( @{ $$qAddy[2] } ) {
|
||||
my $ans = $self->survey->answer( [ $$qAddy[0], $$qAddy[1], $_ ] );
|
||||
$ans->{'text'} =~ s/\[\[([^\%]*?)\]\]/$self->getPreviousAnswer($1)/eg;
|
||||
$ans->{id} = "$$qAddy[0]-$$qAddy[1]-$_";
|
||||
push( @{ $question{answers} }, $ans );
|
||||
my %ans = %{ $self->survey->answer( [ $$qAddy[0], $$qAddy[1], $_ ] ) };
|
||||
$ans{'text'} =~ s/\[\[([^\%]*?)\]\]/$self->getPreviousAnswer($1)/eg;
|
||||
$ans{id} = "$$qAddy[0]-$$qAddy[1]-$_";
|
||||
push( @{ $question{answers} }, \%ans );
|
||||
}
|
||||
push( @$questions, \%question );
|
||||
} ## end for ( my $i = 1; $i <= ...
|
||||
return $questions;
|
||||
} ## end sub nextQuestions
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 surveyEnd
|
||||
|
||||
Returns true if the current index stored in lastResponse is greater than or
|
||||
equal to the number of sections in the survey order.
|
||||
|
||||
=cut
|
||||
|
||||
sub surveyEnd {
|
||||
my $self = shift;
|
||||
return 1 if ( $self->lastResponse >= $#{ $self->surveyOrder } );
|
||||
return 0;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 returnResponsesForReporting
|
||||
|
||||
=cut
|
||||
|
||||
sub returnResponseForReporting {
|
||||
my $self = shift;
|
||||
my @responses = ();
|
||||
|
|
@ -393,19 +645,51 @@ sub returnResponseForReporting {
|
|||
return \@responses;
|
||||
} ## end sub returnResponseForReporting
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
#the actual responses to the survey. A response is for a question and is accessed by the exact same address as a survey member.
|
||||
#Questions only contain the comment and an array of answer Responses.
|
||||
#Answers only contain, entered text, entered verbatim, their index in the Survey Question Answer array, and the assetId to the uploaded file.
|
||||
|
||||
=head2 responses
|
||||
|
||||
Returns a reference to the actual responses to the survey. A response is for a question and
|
||||
is accessed by the exact same address as a survey member. Questions only contain the comment
|
||||
and an array of answer Responses. Answers only contain, entered text, entered verbatim,
|
||||
their index in the Survey Question Answer array, and the assetId to the uploaded file.
|
||||
|
||||
Note, this is an unsafe reference.
|
||||
|
||||
=cut
|
||||
|
||||
sub responses {
|
||||
my $self = shift;
|
||||
return $self->{responses};
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 responses
|
||||
|
||||
Returns a referece to the SurveyJSON object that this object was created with.
|
||||
|
||||
Note, this is an unsafe reference.
|
||||
|
||||
=cut
|
||||
|
||||
sub survey {
|
||||
my $self = shift;
|
||||
return $self->{survey};
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 log
|
||||
|
||||
Logs an error to the webgui log file, using the session logger.
|
||||
|
||||
=cut
|
||||
|
||||
sub log {
|
||||
my ( $self, $message ) = @_;
|
||||
if ( defined $self->{log} ) {
|
||||
|
|
|
|||
|
|
@ -862,7 +862,7 @@ sub getFormElement {
|
|||
}
|
||||
}
|
||||
|
||||
if (WebGUI::Utility::isIn($data->{fieldType},qw(SelectList CheckList SelectBox Attachments Combo))) {
|
||||
if (WebGUI::Utility::isIn($data->{fieldType},qw(SelectList CheckList SelectBox Attachments))) {
|
||||
my @defaultValues;
|
||||
if ($self->session->form->param($name)) {
|
||||
@defaultValues = $self->session->form->selectList($name);
|
||||
|
|
@ -876,7 +876,9 @@ sub getFormElement {
|
|||
$param{value} = \@defaultValues;
|
||||
}
|
||||
|
||||
if (WebGUI::Utility::isIn($data->{fieldType},qw(SelectList SelectBox CheckList RadioList SelectSlider Combo))) {
|
||||
my $class = 'WebGUI::Form::'. ucfirst $data->{fieldType};
|
||||
eval { WebGUI::Pluggable::load($class) };
|
||||
if ($class->isa('WebGUI::Form::List')) {
|
||||
delete $param{size};
|
||||
|
||||
my $values = WebGUI::Operation::Shared::secureEval($self->session,$data->{possibleValues});
|
||||
|
|
@ -930,7 +932,7 @@ sub getFormElement {
|
|||
$param{value} = $data->{value} || $data->{defaultValue};
|
||||
}
|
||||
|
||||
my $formElement = eval { WebGUI::Pluggable::instanciate("WebGUI::Form::". ucfirst $param{fieldType}, "new", [$self->session, \%param ])};
|
||||
my $formElement = eval { WebGUI::Pluggable::instanciate($class, "new", [$self->session, \%param ])};
|
||||
return $formElement->toHtml();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ a:visited { color: '.$form->get("visitedLinkColor").'; }
|
|||
#pageBodyContainer { background-color: '.$form->get("contentBackgroundColor").'; color: '.$form->get("contentTextColor").'; }
|
||||
#mainNavigationContainer { min-height: 300px; padding: 5px; float: left; width: 180px; font-size: 10pt; background-color: '.$form->get("navigationBackgroundColor").'; }
|
||||
#mainNavigationContainer A, #mainNavigationContainer A:link { color: '.$form->get("navigationTextColor").'; }
|
||||
#mainBodyContentContainer { padding: 5px; margin-left: 200px; font-family: serif, times new roman; font-size: 12pt; }
|
||||
#mainBodyContentContainer { padding: 5px; margin-left: 200px; font-family: serif, times new roman; font-size: 12pt; overflow: auto; }
|
||||
#pageFooterContainer { text-align: center; background-color: '.$form->get("footerBackgroundColor").'; color: '.$form->get("footerTextColor").'; }
|
||||
#copyrightContainer { font-size: 8pt; }
|
||||
#pageWidthContainer { width: 80%; margin-left: auto; margin-right: auto; font-family: sans-serif, helvetica, arial; border: 3px solid black; }
|
||||
|
|
|
|||
|
|
@ -115,51 +115,44 @@ sub getName {
|
|||
|
||||
=head2 getValue ( [ value ] )
|
||||
|
||||
If the defaultValue is a MySQL time, the value returned by this form element
|
||||
will be a MySQL time. Note: Will not be adjusted for the user's time zone.
|
||||
If the defaultValue is a MySQL time, or the format property = 'mysql',
|
||||
the value returned by this form element will be a MySQL time.
|
||||
Note: Will not be adjusted for the user's time zone.
|
||||
|
||||
Otherwise, the value returned by this form element will be a number of seconds,
|
||||
adjusted for the user's time zone..
|
||||
Otherwise, the value returned by this form element will be a number of seconds.
|
||||
|
||||
=head3 value
|
||||
|
||||
An optional value to process, instead of POST input. This should be in the form of an integer of seconds, 'HH:MM', or 'HH:MM:SS'.
|
||||
An optional value to process, instead of POST input. This should be
|
||||
in the form of an integer of seconds, 'HH:MM', or 'HH:MM:SS'.
|
||||
|
||||
=cut
|
||||
|
||||
my $mysqlFormattedDate = qr/^\d{2}\D\d{2}(?:\D\d{2})?$/;
|
||||
|
||||
sub getValue {
|
||||
my $self = shift;
|
||||
my $value = $self->SUPER::getValue(@_);
|
||||
if (@_) {
|
||||
if ($self->get('format') ne 'mysql' && (
|
||||
!$self->get("defaultValue")
|
||||
|| $self->get("defaultValue") =~ m/^\d+$/
|
||||
|| !$value
|
||||
|| $value =~ m/^\d+$/)) {
|
||||
return $self->session->datetime->timeToSeconds($value)-($self->session->user->profileField("timeOffset")*3600);
|
||||
}
|
||||
elsif ($value =~ /^\d{2}\D\d{2}(\D\d{2})?$/) {
|
||||
return $value
|
||||
}
|
||||
else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
# This should probably be rewritten as a cascading ternary
|
||||
if ($self->get('format') ne 'mysql' && (
|
||||
!$self->get("defaultValue")
|
||||
|| $self->get("defaultValue") =~ m/^\d+$/
|
||||
|| !$self->get("value")
|
||||
|| $self->get("value") =~ m/^\d+$/)) {
|
||||
# epoch format
|
||||
return $self->session->datetime->timeToSeconds($value)-($self->session->user->profileField("timeOffset")*3600);
|
||||
}
|
||||
else {
|
||||
# Mysql format
|
||||
return undef unless $value =~ /^\d{2}\D\d{2}(\D\d{2})?$/;
|
||||
return $value;
|
||||
}
|
||||
my $mysqlMode = $self->get('format') eq 'mysql'
|
||||
|| $self->getDefaultValue =~ $mysqlFormattedDate;
|
||||
my $mysqlDate = ($value =~ $mysqlFormattedDate);
|
||||
my $digits = ($value =~ /^\d+/);
|
||||
##Format is fine
|
||||
if ( ( $mysqlMode && $mysqlDate)
|
||||
||(!$mysqlMode && !$mysqlDate) && $digits) {
|
||||
return $value;
|
||||
}
|
||||
##Convert to mysql format
|
||||
elsif ($mysqlMode && $digits) {
|
||||
return $self->session->datetime->secondsToTime($value);
|
||||
}
|
||||
##Convert to seconds.
|
||||
elsif ($mysqlDate) {
|
||||
return $self->session->datetime->timeToSeconds($value);
|
||||
}
|
||||
else { ##Bad stuff, maynard
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
104
lib/WebGUI/Help/PayDriver_ITransact.pm
Normal file
104
lib/WebGUI/Help/PayDriver_ITransact.pm
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
package WebGUI::Help::Shop::PayDriver::ITransact;
|
||||
|
||||
use strict;
|
||||
|
||||
|
||||
our $HELP = {
|
||||
|
||||
'edit credentials template' => {
|
||||
title => 'edit credentials template',
|
||||
body => 'edit credentials template help',
|
||||
isa => [],
|
||||
fields => [],
|
||||
variables => [
|
||||
{
|
||||
name => "errors",
|
||||
description => "errors help",
|
||||
required => 1,
|
||||
},
|
||||
{
|
||||
name => "error",
|
||||
description => "error help",
|
||||
required => 1,
|
||||
},
|
||||
{
|
||||
name => "formHeader",
|
||||
description => "formHeader help",
|
||||
required => 1,
|
||||
namespace => 'Shop',
|
||||
},
|
||||
{
|
||||
name => "formFooter",
|
||||
description => "formFooter help",
|
||||
required => 1,
|
||||
namespace => 'Shop',
|
||||
},
|
||||
{
|
||||
name => "addressField",
|
||||
description => "addressField help",
|
||||
required => 1,
|
||||
},
|
||||
{
|
||||
name => "cityField",
|
||||
description => "cityField help",
|
||||
required => 1,
|
||||
namespace => 'Shop',
|
||||
},
|
||||
{
|
||||
name => "stateField",
|
||||
description => "stateField help",
|
||||
required => 1,
|
||||
namespace => 'Shop',
|
||||
},
|
||||
{
|
||||
name => "countryField",
|
||||
description => "countryField help",
|
||||
required => 1,
|
||||
namespace => 'Shop',
|
||||
},
|
||||
{
|
||||
name => "codeField",
|
||||
description => "codeField help",
|
||||
required => 1,
|
||||
namespace => 'Shop',
|
||||
},
|
||||
{
|
||||
name => "phoneField",
|
||||
description => "phoneNumberField help",
|
||||
required => 1,
|
||||
namespace => 'Shop',
|
||||
},
|
||||
{
|
||||
name => "emailField",
|
||||
description => "emailNumberField help",
|
||||
required => 1,
|
||||
},
|
||||
{
|
||||
name => "cardNumberField",
|
||||
description => "cardNumberField help",
|
||||
required => 1,
|
||||
},
|
||||
{
|
||||
name => "monthYearField",
|
||||
description => "monthYearNumberField help",
|
||||
required => 1,
|
||||
},
|
||||
{
|
||||
name => "cvv2Field",
|
||||
description => "cvv2NumberField help",
|
||||
required => 1,
|
||||
},
|
||||
{
|
||||
name => "checkoutButton",
|
||||
description => "checkoutButton help",
|
||||
required => 1,
|
||||
namespace => 'Shop',
|
||||
},
|
||||
],
|
||||
related => [
|
||||
],
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
@ -120,6 +120,7 @@ sub process {
|
|||
my %assetList = %{$config->get('assets')};
|
||||
foreach my $assetClass (keys %assetList) {
|
||||
my $dummy = WebGUI::Asset->newByPropertyHashRef($session,{dummy=>1, className=>$assetClass});
|
||||
next unless defined $dummy;
|
||||
next if $dummy->getUiLevel($assetList{$assetClass}{uiLevel}) > $userUiLevel;
|
||||
next unless ($dummy->canAdd($session));
|
||||
next unless exists $categories{$assetList{$assetClass}{category}};
|
||||
|
|
|
|||
|
|
@ -337,7 +337,7 @@ sub www_manage {
|
|||
.WebGUI::Form::formFooter($session)
|
||||
|
||||
# Append payment gateway label
|
||||
.' '. $paymentGateway->label()
|
||||
.' '. $paymentGateway->get('label')
|
||||
.'</div>';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,11 +62,10 @@ this plugin.
|
|||
sub getButton {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $i18n = WebGUI::International->new($session, 'PayDriver_Cash');
|
||||
|
||||
my $payForm = WebGUI::Form::formHeader($session)
|
||||
. $self->getDoFormTags('getCredentials')
|
||||
. WebGUI::Form::submit($session, {value => $i18n->get('cash') })
|
||||
. WebGUI::Form::submit($session, {value => $self->get('label') })
|
||||
. WebGUI::Form::formFooter($session);
|
||||
|
||||
return $payForm;
|
||||
|
|
|
|||
|
|
@ -367,6 +367,12 @@ sub definition {
|
|||
label => $i18n->get('use cvv2'),
|
||||
hoverHelp => $i18n->get('use cvv2 help'),
|
||||
},
|
||||
credentialsTemplateId => {
|
||||
fieldType => 'template',
|
||||
label => $i18n->get('credentials template'),
|
||||
hoverHelp => $i18n->get('credentials template help'),
|
||||
namespace => 'Shop/Credentials',
|
||||
},
|
||||
emailMessage => {
|
||||
fieldType => 'textarea',
|
||||
label => $i18n->get('emailMessage'),
|
||||
|
|
@ -430,11 +436,10 @@ sub doXmlRequest {
|
|||
sub getButton {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $i18n = WebGUI::International->new($session, 'PayDriver');
|
||||
|
||||
my $payForm = WebGUI::Form::formHeader($session)
|
||||
. $self->getDoFormTags('getCredentials')
|
||||
. WebGUI::Form::submit($session, {value => $i18n->get('credit card') })
|
||||
. WebGUI::Form::submit($session, {value => $self->get('label') })
|
||||
. WebGUI::Form::formFooter($session);
|
||||
|
||||
return $payForm;
|
||||
|
|
@ -618,91 +623,90 @@ sub www_getCredentials {
|
|||
}
|
||||
|
||||
my $output;
|
||||
my $var = {};
|
||||
|
||||
# Process form errors
|
||||
if ( $errors ) {
|
||||
$var->{errors} = [];
|
||||
#### TODO: i18n
|
||||
$output .= $i18n->get('error occurred message')
|
||||
. '<ul><li>' . join( '</li><li>', @{ $errors } ) . '</li></ul>';
|
||||
if ($errors) {
|
||||
$var->{error_message} = $i18n->get('error occurred message');
|
||||
foreach my $error (@{ $errors} ) {
|
||||
push @{ $var->{errors} }, { error => $error };
|
||||
}
|
||||
}
|
||||
|
||||
$output .= $self->getSelectAddressButton( 'getCredentials' );
|
||||
$var->{getSelectAddressButton} = $self->getSelectAddressButton( 'getCredentials' );
|
||||
$self->session->log->warn("selectAddressButton: ".$var->{getSelectAddressButton});
|
||||
|
||||
$var->{formHeader} = WebGUI::Form::formHeader($session)
|
||||
. $self->getDoFormTags('pay');
|
||||
|
||||
if ($var->{formHeader}) {
|
||||
$var->{formHeader} .= WebGUI::Form::hidden($session, {name => 'addressId', value => $addressId});
|
||||
}
|
||||
|
||||
$var->{formFooter} = WebGUI::Form::formFooter();
|
||||
$self->session->log->warn("formHeader: ".$var->{formHeader});
|
||||
|
||||
my $f = WebGUI::HTMLForm->new( $session );
|
||||
$self->getDoFormTags( 'pay', $f );
|
||||
$f->hidden(
|
||||
-name => 'addressId',
|
||||
-value => $addressId,
|
||||
) if $addressId;
|
||||
|
||||
# Address data form
|
||||
$f->text(
|
||||
-name => 'firstName',
|
||||
-label => $i18n->get('firstName'),
|
||||
-value => $form->process("firstName") || $addressData->{ "firstName" } || $u->profileField('firstName'),
|
||||
);
|
||||
$f->text(
|
||||
-name => 'lastName',
|
||||
-label => $i18n->get('lastName'),
|
||||
-value => $form->process("lastName") || $addressData->{ "lastName" } || $u->profileField('lastName'),
|
||||
);
|
||||
$f->text(
|
||||
-name => 'address',
|
||||
-label => $i18n->get('address'),
|
||||
-value => $form->process("address") || $addressData->{ address1 } || $u->profileField('homeAddress'),
|
||||
);
|
||||
$f->text(
|
||||
-name => 'city',
|
||||
-label => $i18n->get('city'),
|
||||
-value => $form->process("city") || $addressData->{ city } || $u->profileField('homeCity'),
|
||||
);
|
||||
$f->text(
|
||||
-name => 'state',
|
||||
-label => $i18n->get('state'),
|
||||
-value => $form->process("state") || $addressData->{ state } || $u->profileField('homeState'),
|
||||
);
|
||||
$f->zipcode(
|
||||
-name => 'zipcode',
|
||||
-label => $i18n->get('zipcode'),
|
||||
-value => $form->process("zipcode") || $addressData->{ code } || $u->profileField('homeZip'),
|
||||
);
|
||||
$f->country(
|
||||
-name => "country",
|
||||
-label => $i18n->get("country"),
|
||||
-value => ($form->process("country",'country') || $addressData->{ country } || $u->profileField("homeCountry") || 'United States'),
|
||||
);
|
||||
$f->phone(
|
||||
-name => "phone",
|
||||
-label => $i18n->get("phone"),
|
||||
-value => $form->process("phone",'phone') || $addressData->{ phoneNumber } || $u->profileField("homePhone"),
|
||||
);
|
||||
$f->email(
|
||||
-name => 'email',
|
||||
-label => $i18n->get('email'),
|
||||
-value => $self->session->form->process("email") || $u->profileField('email'),
|
||||
);
|
||||
$var->{firstNameField} = WebGUI::Form::text($session, {
|
||||
name => 'firstName',
|
||||
value => $form->process("firstName") || $addressData->{ "firstName" } || $u->profileField('firstName'),
|
||||
});
|
||||
$var->{lastNameField} = WebGUI::Form::text($session, {
|
||||
name => 'lastName',
|
||||
value => $form->process("lastName") || $addressData->{ "lastName" } || $u->profileField('lastName'),
|
||||
});
|
||||
$var->{addressField} = WebGUI::Form::text($session, {
|
||||
name => 'address',
|
||||
value => $form->process("address") || $addressData->{ address1 } || $u->profileField('homeAddress'),
|
||||
});
|
||||
$var->{cityField} = WebGUI::Form::text($session, {
|
||||
name => 'city',
|
||||
value => $form->process("city") || $addressData->{ city } || $u->profileField('homeCity'),
|
||||
});
|
||||
$var->{stateField} = WebGUI::Form::text($session, {
|
||||
name => 'state',
|
||||
value => $form->process("state") || $addressData->{ state } || $u->profileField('homeState'),
|
||||
});
|
||||
$var->{codeField} = WebGUI::Form::zipcode($session, {
|
||||
name => 'zipcode',
|
||||
value => $form->process("zipcode") || $addressData->{ code } || $u->profileField('homeZip'),
|
||||
});
|
||||
$var->{countryField} = WebGUI::Form::country($session, {
|
||||
name => 'country',
|
||||
value => ($form->process("country",'country') || $addressData->{ country } || $u->profileField("homeCountry") || 'United States'),
|
||||
});
|
||||
$var->{phoneField} = WebGUI::Form::phone($session, {
|
||||
name => 'phone',
|
||||
value => $form->process("phone",'phone') || $addressData->{ phoneNumber } || $u->profileField("homePhone"),
|
||||
});
|
||||
$var->{emailField} = WebGUI::Form::email($session, {
|
||||
name => 'email',
|
||||
value => $self->session->form->process("email") || $u->profileField('email'),
|
||||
});
|
||||
|
||||
# Credit card information
|
||||
$f->text(
|
||||
-name => 'cardNumber',
|
||||
-label => $i18n->get('cardNumber'),
|
||||
-value => $self->session->form->process("cardNumber"),
|
||||
);
|
||||
$f->readOnly(
|
||||
-label => $i18n->get('expiration date'),
|
||||
-value => _monthYear( $session ),
|
||||
);
|
||||
$f->integer(
|
||||
-name => 'cvv2',
|
||||
-label => $i18n->get('cvv2'),
|
||||
-value => $self->session->form->process("cvv2")
|
||||
) if ($self->get('useCVV2'));
|
||||
$f->submit(
|
||||
-value => 'Checkout',
|
||||
);
|
||||
|
||||
$output .= $f->print;
|
||||
return $session->style->userStyle( $output );
|
||||
$var->{cardNumberField} = WebGUI::Form::text($session, {
|
||||
name => 'cardNumber',
|
||||
value => $self->session->form->process("cardNumber"),
|
||||
});
|
||||
$var->{monthYearField} = WebGUI::Form::readOnly($session, {
|
||||
value => _monthYear( $session ),
|
||||
});
|
||||
$var->{cvv2Field} = WebGUI::Form::integer($session, {
|
||||
name => 'cvv2',
|
||||
value => $self->session->form->process("cvv2"),
|
||||
}) if $self->get('useCVV2');
|
||||
|
||||
$var->{checkoutButton} = WebGUI::Form::submit($session, {
|
||||
value => $i18n->get('checkout button', 'Shop'),
|
||||
});
|
||||
|
||||
my $template = WebGUI::Asset::Template->new($session, $self->get("credentialsTemplateId"));
|
||||
$template->prepare;
|
||||
return $session->style->userStyle($template->process($var));
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -212,6 +212,7 @@ sub execute {
|
|||
feedId => $feed->{feedId},
|
||||
description => _unwrapIcalText($events{$id}->{description}->[1]),
|
||||
title => _unwrapIcalText($events{$id}->{summary}->[1]),
|
||||
location => _unwrapIcalText($events{$id}->{location}->[1]),
|
||||
menuTitle => substr($events{$id}->{summary}->[1],0,15),
|
||||
className => 'WebGUI::Asset::Event',
|
||||
isHidden => 1,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package WebGUI::i18n::English::Account_Profile;
|
||||
package WebGUI::i18n::English::Account;
|
||||
use strict;
|
||||
|
||||
our $I18N = {
|
||||
|
|
|
|||
|
|
@ -619,6 +619,11 @@ listing,|,
|
|||
message => q|Select a template to be used to show the listing comparison data.|,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'edit listing template description' => {
|
||||
message => q|Select a template to be used to show the listing edit screen.|,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'categories label' => {
|
||||
message => q|Categories|,
|
||||
|
|
@ -745,6 +750,11 @@ listing,|,
|
|||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'edit listing template label' => {
|
||||
message => q|Edit Listing Template|,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'product name' => {
|
||||
message => q|Product Name|,
|
||||
lastUpdated => 1133758944,
|
||||
|
|
|
|||
|
|
@ -113,6 +113,17 @@ this listing.|,
|
|||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'product name label' => {
|
||||
message => q|Product Name|,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'product name description' => {
|
||||
message => q|Enter the name of the product. If there are entries for the product with different revisions,
|
||||
it would be best to make sure the names are the same.|,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'productURL description' => {
|
||||
message => q|If the product has its own website, enter the complete URL for it here.|,
|
||||
lastUpdated => 0,
|
||||
|
|
|
|||
|
|
@ -112,6 +112,109 @@ our $I18N = {
|
|||
},
|
||||
|
||||
|
||||
'credentials template' => {
|
||||
message => q|Credentials Template|,
|
||||
lastUpdated => 0,
|
||||
context => q|Form label in the configuration form of the iTransact module.|
|
||||
},
|
||||
'credentials template help' => {
|
||||
message => q|Pick a template to display the form where the user will enter in their billing information and credit card information.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Hover help for the credentials template field in the configuration form of the iTransact module.|
|
||||
},
|
||||
|
||||
'edit credentials template' => {
|
||||
message => q|Edit Credentials Template|,
|
||||
lastUpdated => 0,
|
||||
context => q|Title of the help page.|
|
||||
},
|
||||
'edit credentials template help' => {
|
||||
message => q|This template is used to display a form to the user where they can enter in contact and credit card billing information.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Title of the help page.|
|
||||
},
|
||||
|
||||
'errors help' => {
|
||||
message => q|A template loop containing a list of errors from processing the form.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Template variable help.|
|
||||
},
|
||||
|
||||
'error help' => {
|
||||
message => q|One error from the errors loop. It will have minimal markup.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Template variable help.|
|
||||
},
|
||||
|
||||
'checkoutButton help' => {
|
||||
message => q|A button with an internationalized label to submit the form and continue the checkout process.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Template variable help.|
|
||||
},
|
||||
|
||||
'addressField help' => {
|
||||
message => q|A single text field for the user to enter in their street address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Template variable help.|
|
||||
},
|
||||
|
||||
'emailField help' => {
|
||||
message => q|A single text field for the user to enter in their street address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Template variable help.|
|
||||
},
|
||||
|
||||
'cardNumberField help' => {
|
||||
message => q|A single text field for the user to enter in their credit card number.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Template variable help.|
|
||||
},
|
||||
|
||||
'monthYearField help' => {
|
||||
message => q|A combination form field for the user to enter in the month and year of the expiration date for the credit card.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Template variable help.|
|
||||
},
|
||||
|
||||
'cvv2Field help' => {
|
||||
message => q|A single text field for the user to enter in their credit card verification number. If the PayDriver is not configured to use CVV2, then this field will be empty.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Template variable help.|
|
||||
},
|
||||
|
||||
'password' => {
|
||||
message => q|Password|,
|
||||
lastUpdated => 0,
|
||||
context => q|Form label in the configuration form of the iTransact module.|
|
||||
},
|
||||
'password help' => {
|
||||
message => q|The password for your ITransact account.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Hover help for the password field in the configuration form of the iTransact module.|
|
||||
},
|
||||
|
||||
'password' => {
|
||||
message => q|Password|,
|
||||
lastUpdated => 0,
|
||||
context => q|Form label in the configuration form of the iTransact module.|
|
||||
},
|
||||
'password help' => {
|
||||
message => q|The password for your ITransact account.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Hover help for the password field in the configuration form of the iTransact module.|
|
||||
},
|
||||
|
||||
'credentials template' => {
|
||||
message => q|Credentials Template|,
|
||||
lastUpdated => 0,
|
||||
context => q|Form label in the configuration form of the iTransact module.|
|
||||
},
|
||||
'credentials template help' => {
|
||||
message => q|Pick a template to display the form where the user will enter in their billing information and credit card information.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Hover help for the credentials template field in the configuration form of the iTransact module.|
|
||||
},
|
||||
|
||||
'password' => {
|
||||
message => q|Password|,
|
||||
lastUpdated => 0,
|
||||
|
|
|
|||
|
|
@ -4326,6 +4326,12 @@ Users may override this setting in their profile.
|
|||
context => q{i18n label for time duration in WebGUI::DateTime},
|
||||
},
|
||||
|
||||
'read more' => {
|
||||
message => q|Read More|,
|
||||
lastUpdated => 1229013268,
|
||||
context => q|Template label. Used to indicate that a shortened version of the content is currently displayed and that more can be read by clicking a link.|
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ if ($] >= 5.008) {
|
|||
failAndExit("Please upgrade to 5.8 or later! Cannot continue without Perl 5.8 or higher.");
|
||||
}
|
||||
|
||||
##Doing this as a global is not nice, but it works
|
||||
my $missingModule = 0;
|
||||
|
||||
checkModule("LWP", 5.80 );
|
||||
checkModule("HTTP::Request", 1.40 );
|
||||
|
|
@ -117,6 +119,7 @@ checkModule("File::Path", "2.04" );
|
|||
checkModule("Module::Find", "0.06" );
|
||||
checkModule("Class::C3", "0.19" );
|
||||
|
||||
failAndExit("Required modules are missing, running no more checks.") if $missingModule;
|
||||
|
||||
###################################
|
||||
# Checking WebGUI
|
||||
|
|
@ -267,6 +270,7 @@ sub checkModule {
|
|||
# skip
|
||||
elsif ($simpleReport) {
|
||||
printResult("Not Installed");
|
||||
$missingModule = 1;
|
||||
}
|
||||
|
||||
# if we're root lets try and install it
|
||||
|
|
@ -282,12 +286,14 @@ sub checkModule {
|
|||
# install aborted by user
|
||||
else {
|
||||
printResult("Install aborted by user input.");
|
||||
$missingModule = 1;
|
||||
}
|
||||
}
|
||||
|
||||
# can't install, not root
|
||||
else {
|
||||
printResult("Not installed, but you're not root, so you need to ask your administrator to install it.");
|
||||
$missingModule = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -896,44 +896,49 @@ sub getFixTitleTests {
|
|||
},
|
||||
{
|
||||
title => '',
|
||||
fixed => undef,
|
||||
fixed => undef,
|
||||
comment => "null string returns the Asset's title",
|
||||
},
|
||||
{
|
||||
title => 'untitled',
|
||||
fixed => undef,
|
||||
fixed => undef,
|
||||
comment => "'untitled' returns the Asset's title",
|
||||
},
|
||||
{
|
||||
title => 'UnTiTlEd',
|
||||
fixed => undef,
|
||||
fixed => undef,
|
||||
comment => "'untitled' in any case returns the Asset's title",
|
||||
},
|
||||
{
|
||||
title => 'Username: ^@;',
|
||||
fixed => 'Username: ^@;',
|
||||
fixed => 'Username: ^@;',
|
||||
comment => "Macros are negated",
|
||||
},
|
||||
{
|
||||
title => '<b>A bold title</b>',
|
||||
fixed => 'A bold title',
|
||||
fixed => 'A bold title',
|
||||
comment => "Markup is stripped out",
|
||||
},
|
||||
{
|
||||
title => 'Javascript: <script>Evil code goes in here</script>',
|
||||
fixed => 'Javascript: ',
|
||||
fixed => 'Javascript: ',
|
||||
comment => "javascript removed",
|
||||
},
|
||||
{
|
||||
title => 'This is a good Title',
|
||||
fixed => 'This is a good Title',
|
||||
fixed => 'This is a good Title',
|
||||
comment => "Good titles are passed",
|
||||
},
|
||||
{
|
||||
title => '<b></b>',
|
||||
fixed => '',
|
||||
fixed => '',
|
||||
comment => "If there is no title left after processing, then it is set to untitled.",
|
||||
},
|
||||
{
|
||||
title => q|Quotes '"|,
|
||||
fixed => q|Quotes '"|,
|
||||
comment => "Quotes are not processed.",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use lib "$FindBin::Bin/../lib";
|
|||
use WebGUI::Test;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Asset::Template;
|
||||
use Test::More tests => 13; # increment this value for each test you create
|
||||
use Test::More tests => 15; # increment this value for each test you create
|
||||
use Test::Deep;
|
||||
|
||||
my $session = WebGUI::Test->session;
|
||||
|
|
@ -23,19 +23,19 @@ my $session = WebGUI::Test->session;
|
|||
my $list = WebGUI::Asset::Template->getList($session);
|
||||
cmp_deeply($list, {}, 'getList with no classname returns an empty hashref');
|
||||
|
||||
my $template = " <tmpl_var variable> <tmpl_if conditional>true</tmpl_if> <tmpl_loop loop>XY</tmpl_loop> ";
|
||||
my $tmplText = " <tmpl_var variable> <tmpl_if conditional>true</tmpl_if> <tmpl_loop loop>XY</tmpl_loop> ";
|
||||
my %var = (
|
||||
variable=>"AAAAA",
|
||||
conditional=>1,
|
||||
loop=>[{},{},{},{},{}]
|
||||
);
|
||||
my $output = WebGUI::Asset::Template->processRaw($session,$template,\%var);
|
||||
my $output = WebGUI::Asset::Template->processRaw($session,$tmplText,\%var);
|
||||
ok($output =~ m/\bAAAAA\b/, "processRaw() - variables");
|
||||
ok($output =~ m/true/, "processRaw() - conditionals");
|
||||
ok($output =~ m/\s(?:XY){5}\s/, "processRaw() - loops");
|
||||
|
||||
my $importNode = WebGUI::Asset::Template->getImportNode($session);
|
||||
my $template = $importNode->addChild({className=>"WebGUI::Asset::Template", title=>"test", url=>"testingtemplates", template=>$template, namespace=>'WebGUI Test Template'});
|
||||
my $template = $importNode->addChild({className=>"WebGUI::Asset::Template", title=>"test", url=>"testingtemplates", template=>$tmplText, namespace=>'WebGUI Test Template'});
|
||||
isa_ok($template, 'WebGUI::Asset::Template', "creating a template");
|
||||
|
||||
is($template->get('parser'), 'WebGUI::Asset::Template::HTMLTemplate', 'default parser is HTMLTemplate');
|
||||
|
|
@ -57,6 +57,18 @@ is($template->get('isDefault'), 1, 'isDefault set to 1');
|
|||
my $templateCopy = $template->duplicate();
|
||||
is($templateCopy->get('isDefault'), 0, 'isDefault set to 0 on copy');
|
||||
|
||||
my $template3 = $importNode->addChild({
|
||||
className => "WebGUI::Asset::Template",
|
||||
title => 'headBlock test',
|
||||
headBlock => "tag1 tag2 tag3",
|
||||
template => "this is a template",
|
||||
});
|
||||
|
||||
ok(!$template3->get('headBlock'), 'headBlock is empty');
|
||||
is($template3->get('extraHeadTags'), 'tag1 tag2 tag3', 'extraHeadTags contains headBlock info');
|
||||
|
||||
$template->purge;
|
||||
$templateCopy->purge;
|
||||
$template3->purge;
|
||||
WebGUI::VersionTag->getWorking($session)->rollback;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,11 @@ use FindBin;
|
|||
use lib "$FindBin::Bin/../../../lib";
|
||||
use Test::More;
|
||||
use Test::Deep;
|
||||
use Test::MockObject::Extends;
|
||||
use Data::Dumper;
|
||||
use WebGUI::Test; # Must use this before any other WebGUI modules
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Asset::Wobject::Survey::SurveyJSON;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Init
|
||||
|
|
@ -18,7 +20,7 @@ my $session = WebGUI::Test->session;
|
|||
|
||||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
my $tests = 1;
|
||||
my $tests = 52;
|
||||
plan tests => $tests + 1;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
|
@ -37,9 +39,424 @@ skip $tests, "Unable to load ResponseJSON" unless $usedOk;
|
|||
#
|
||||
####################################################
|
||||
|
||||
my $newTime = time();
|
||||
$responseJSON = WebGUI::Asset::Wobject::Survey::ResponseJSON->new('{}', $session->log);
|
||||
isa_ok($responseJSON , 'WebGUI::Asset::Wobject::Survey::ResponseJSON');
|
||||
|
||||
is($responseJSON->lastResponse(), -1, 'new: default lastResponse is -1');
|
||||
is($responseJSON->{questionsAnswered}, 0, 'new: questionsAnswered is 0 by default');
|
||||
cmp_ok((abs$responseJSON->{startTime} - $newTime), '<=', 2, 'new: by default startTime set to time');
|
||||
is_deeply( $responseJSON->responses, {}, 'new: by default, responses is an empty hashref');
|
||||
is_deeply( $responseJSON->surveyOrder, [], 'new: by default, responses is an empty arrayref');
|
||||
|
||||
my $now = time();
|
||||
my $rJSON = WebGUI::Asset::Wobject::Survey::ResponseJSON->new(qq!{ "startTime": $now }!, $session->log);
|
||||
cmp_ok(abs($rJSON->startTime() - $now), '<=', 2, 'new: startTime set using JSON');
|
||||
|
||||
####################################################
|
||||
#
|
||||
# startTime
|
||||
#
|
||||
####################################################
|
||||
|
||||
$rJSON->startTime(780321600);
|
||||
is($rJSON->startTime, 780321600, 'startTime: set and get');
|
||||
|
||||
####################################################
|
||||
#
|
||||
# hasTimedOut
|
||||
#
|
||||
####################################################
|
||||
|
||||
##Reset for next set of tests
|
||||
$rJSON->startTime(time());
|
||||
|
||||
ok( ! $rJSON->hasTimedOut(1), 'hasTimedOut, not timed out, checked with 1 minute timeout');
|
||||
ok( ! $rJSON->hasTimedOut(0), 'hasTimedOut, not timed out, checked with 0 minute timeout');
|
||||
|
||||
$rJSON->startTime(time()-7200);
|
||||
ok( $rJSON->hasTimedOut(1), 'hasTimedOut, timed out');
|
||||
ok( ! $rJSON->hasTimedOut(0), 'hasTimedOut, bad limit');
|
||||
ok( ! $rJSON->hasTimedOut(4*60), 'hasTimedOut, limit check');
|
||||
|
||||
####################################################
|
||||
#
|
||||
# createSurveyOrder
|
||||
#
|
||||
####################################################
|
||||
|
||||
$rJSON = WebGUI::Asset::Wobject::Survey::ResponseJSON->new(q!{}!, $session->log, buildSurveyJSON($session));
|
||||
|
||||
$rJSON->createSurveyOrder();
|
||||
cmp_deeply(
|
||||
$rJSON->surveyOrder,
|
||||
[
|
||||
[ 0, 0, [0] ],
|
||||
[ 0, 1, [0] ],
|
||||
[ 0, 2, [0, 1] ],
|
||||
[ 1, 0, [0, 1] ],
|
||||
[ 1, 1, [0, 1] ],
|
||||
[ 2 ],
|
||||
[ 3, 0, [0, 1] ],
|
||||
[ 3, 1, [0, 1, 2, 3, 4, 5, 6] ],
|
||||
[ 3, 2, [0] ],
|
||||
],
|
||||
'createSurveyOrder, enumerated all sections, questions and answers'
|
||||
);
|
||||
|
||||
####################################################
|
||||
#
|
||||
# shuffle
|
||||
#
|
||||
####################################################
|
||||
|
||||
{
|
||||
my @dataToRandomize = 0..49;
|
||||
my @randomizedData = WebGUI::Asset::Wobject::Survey::ResponseJSON::shuffle(@dataToRandomize);
|
||||
cmp_bag(\@dataToRandomize, \@randomizedData, 'shuffle: No data lost during shuffling');
|
||||
}
|
||||
|
||||
####################################################
|
||||
#
|
||||
# createSurveyOrder, part 2
|
||||
#
|
||||
####################################################
|
||||
|
||||
{
|
||||
no strict "refs";
|
||||
no warnings;
|
||||
my $rJSON = WebGUI::Asset::Wobject::Survey::ResponseJSON->new(q!{}!, $session->log, buildSurveyJSON($session));
|
||||
$rJSON->survey->section([0])->{randomizeQuestions} = 0;
|
||||
my $shuffleName = "WebGUI::Asset::Wobject::Survey::ResponseJSON::shuffle";
|
||||
my $shuffleCalled = 0;
|
||||
my $shuffleRef = \&$shuffleName;
|
||||
*$shuffleName = sub {
|
||||
$shuffleCalled = 1;
|
||||
goto &$shuffleRef;
|
||||
};
|
||||
$rJSON->createSurveyOrder();
|
||||
is($shuffleCalled, 0, 'createSurveyOrder did not call shuffle on a section');
|
||||
|
||||
$shuffleCalled = 0;
|
||||
$rJSON->survey->section([0])->{randomizeQuestions} = 1;
|
||||
$rJSON->createSurveyOrder();
|
||||
is($shuffleCalled, 1, 'createSurveyOrder called shuffle on a section');
|
||||
|
||||
$shuffleCalled = 0;
|
||||
$rJSON->survey->section([0])->{randomizeQuestions} = 0;
|
||||
$rJSON->survey->question([0,0])->{randomizeAnswers} = 1;
|
||||
$rJSON->createSurveyOrder();
|
||||
is($shuffleCalled, 1, 'createSurveyOrder called shuffle on a question');
|
||||
|
||||
##Restore the subroutine to the original
|
||||
*$shuffleName = &$shuffleRef;
|
||||
}
|
||||
|
||||
####################################################
|
||||
#
|
||||
# surveyEnd
|
||||
#
|
||||
####################################################
|
||||
|
||||
$rJSON->lastResponse(2);
|
||||
ok( ! $rJSON->surveyEnd(), 'surveyEnd, with 9 elements, 2 != end of survey');
|
||||
$rJSON->lastResponse(7);
|
||||
ok( ! $rJSON->surveyEnd(), 'surveyEnd, with 9 elements, 7 != end of survey');
|
||||
$rJSON->lastResponse(8);
|
||||
ok( $rJSON->surveyEnd(), 'surveyEnd, with 9 elements, 8 == end of survey');
|
||||
$rJSON->lastResponse(20);
|
||||
ok( $rJSON->surveyEnd(), 'surveyEnd, with 9 elements, 20 >= end of survey');
|
||||
|
||||
####################################################
|
||||
#
|
||||
# nextSectionId, nextSection, currentSection
|
||||
#
|
||||
####################################################
|
||||
|
||||
$rJSON->lastResponse(0);
|
||||
is($rJSON->nextSectionId(), 0, 'nextSectionId, lastResponse=0, nextSectionId=0');
|
||||
cmp_deeply(
|
||||
$rJSON->nextSection,
|
||||
$rJSON->survey->section([0]),
|
||||
'lastResponse=0, nextSection = section 0'
|
||||
);
|
||||
cmp_deeply(
|
||||
$rJSON->currentSection,
|
||||
$rJSON->survey->section([0]),
|
||||
'lastResponse=0, currentSection = section 0'
|
||||
);
|
||||
|
||||
$rJSON->lastResponse(2);
|
||||
is($rJSON->nextSectionId(), 1, 'nextSectionId, lastResponse=2, nextSectionId=1');
|
||||
cmp_deeply(
|
||||
$rJSON->nextSection,
|
||||
$rJSON->survey->section([1]),
|
||||
'lastResponse=2, nextSection = section 1'
|
||||
);
|
||||
cmp_deeply(
|
||||
$rJSON->currentSection,
|
||||
$rJSON->survey->section([0]),
|
||||
'lastResponse=2, currentSection = section 0'
|
||||
);
|
||||
|
||||
$rJSON->lastResponse(6);
|
||||
is($rJSON->nextSectionId(), 3, 'nextSectionId, lastResponse=6, nextSectionId=3');
|
||||
cmp_deeply(
|
||||
$rJSON->nextSection,
|
||||
$rJSON->survey->section([3]),
|
||||
'lastResponse=0, nextSection = section 3'
|
||||
);
|
||||
cmp_deeply(
|
||||
$rJSON->currentSection,
|
||||
$rJSON->survey->section([3]),
|
||||
'lastResponse=6, currentSection = section 3'
|
||||
);
|
||||
|
||||
$rJSON->lastResponse(20);
|
||||
is($rJSON->nextSectionId(), undef, 'nextSectionId, lastResponse > surveyEnd, nextSectionId=undef');
|
||||
|
||||
####################################################
|
||||
#
|
||||
# nextQuestions
|
||||
#
|
||||
####################################################
|
||||
|
||||
$rJSON->lastResponse(20);
|
||||
ok($rJSON->surveyEnd, 'nextQuestions: lastResponse indicates end of survey');
|
||||
is_deeply($rJSON->nextQuestions, [], 'nextQuestions returns an empty array ref if there are no questions available');
|
||||
$rJSON->survey->section([0])->{questionsPerPage} = 2;
|
||||
$rJSON->survey->section([1])->{questionsPerPage} = 2;
|
||||
$rJSON->survey->section([2])->{questionsPerPage} = 2;
|
||||
$rJSON->survey->section([3])->{questionsPerPage} = 2;
|
||||
$rJSON->lastResponse(-1);
|
||||
cmp_deeply(
|
||||
$rJSON->nextQuestions(),
|
||||
[
|
||||
superhashof({
|
||||
sid => 0,
|
||||
id => '0-0',
|
||||
text => 'Question 0-0',
|
||||
type => 'question',
|
||||
answers => [
|
||||
superhashof({
|
||||
type => 'answer',
|
||||
id => '0-0-0',
|
||||
}),
|
||||
],
|
||||
}),
|
||||
superhashof({
|
||||
sid => 0,
|
||||
id => '0-1',
|
||||
text => 'Question 0-1',
|
||||
type => 'question',
|
||||
answers => [
|
||||
superhashof({
|
||||
type => 'answer',
|
||||
id => '0-1-0',
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
'nextQuestions returns the correct data structre, amounts and members'
|
||||
);
|
||||
|
||||
$rJSON->lastResponse(1);
|
||||
cmp_deeply(
|
||||
$rJSON->nextQuestions(),
|
||||
[
|
||||
superhashof({
|
||||
sid => 0,
|
||||
id => '0-2',
|
||||
text => 'Question 0-2',
|
||||
type => 'question',
|
||||
answers => [
|
||||
superhashof({
|
||||
type => 'answer',
|
||||
id => '0-2-0',
|
||||
}),
|
||||
superhashof({
|
||||
type => 'answer',
|
||||
id => '0-2-1',
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
'nextQuestions obeys questionPerPage'
|
||||
);
|
||||
|
||||
$rJSON->lastResponse(4);
|
||||
cmp_deeply(
|
||||
$rJSON->nextQuestions(),
|
||||
undef,
|
||||
'nextQuestions: returns undef if the next section is empty'
|
||||
);
|
||||
|
||||
####################################################
|
||||
#
|
||||
# goto
|
||||
#
|
||||
####################################################
|
||||
$rJSON->survey->section([0])->{variable} = 'goto 0';
|
||||
$rJSON->survey->question([0,0])->{variable} = 'goto 0-0';
|
||||
$rJSON->survey->question([0,1])->{variable} = 'goto 0-1';
|
||||
$rJSON->survey->question([0,2])->{variable} = 'goto 0-2';
|
||||
$rJSON->survey->section([1])->{variable} = 'goto 1';
|
||||
$rJSON->survey->question([1,0])->{variable} = 'goto 1-0';
|
||||
$rJSON->survey->question([1,1])->{variable} = 'goto 1-1';
|
||||
$rJSON->survey->section([2])->{variable} = 'goto 2';
|
||||
$rJSON->survey->section([3])->{variable} = 'goto 2';
|
||||
$rJSON->survey->question([3,0])->{variable} = 'goto 3-0';
|
||||
$rJSON->survey->question([3,1])->{variable} = 'goto 3-0'; ##Intentional duplicate
|
||||
$rJSON->survey->question([3,2])->{variable} = 'goto 3-2';
|
||||
|
||||
$rJSON->lastResponse(0);
|
||||
$rJSON->goto('goto 80');
|
||||
is($rJSON->lastResponse(), 0, 'goto: no change in lastResponse if the variable cannot be found');
|
||||
$rJSON->goto('goto 1');
|
||||
is($rJSON->lastResponse(), 2, 'goto: works on existing section');
|
||||
$rJSON->goto('goto 0-1');
|
||||
is($rJSON->lastResponse(), 0, 'goto: works on existing question');
|
||||
$rJSON->goto('goto 3-0');
|
||||
is($rJSON->lastResponse(), 5, 'goto: finds first if there are duplicates');
|
||||
|
||||
####################################################
|
||||
#
|
||||
# recordResponses
|
||||
#
|
||||
####################################################
|
||||
|
||||
$rJSON->lastResponse(4);
|
||||
my $terminals;
|
||||
cmp_deeply(
|
||||
$rJSON->recordResponses($session, {}),
|
||||
[ 0, undef ],
|
||||
'recordResponses, if section has no questions, returns terminal info in the section. With no terminal info, returns [0, undef]',
|
||||
);
|
||||
is($rJSON->lastResponse(), 5, 'recordResponses, increments lastResponse if there are no questions in the section');
|
||||
|
||||
$rJSON->survey->section([2])->{terminal} = 1;
|
||||
$rJSON->survey->section([2])->{terminalUrl} = '/terminal';
|
||||
|
||||
$rJSON->lastResponse(4);
|
||||
cmp_deeply(
|
||||
$rJSON->recordResponses($session, {}),
|
||||
[ 1, '/terminal' ],
|
||||
'recordResponses, if section has no questions, returns terminal info in the section.',
|
||||
);
|
||||
is($rJSON->questionsAnswered, 0, 'questionsAnswered=0, no questions answered');
|
||||
|
||||
$rJSON->survey->question([1,0])->{terminal} = 1;
|
||||
$rJSON->survey->question([1,0])->{terminalUrl} = 'question 1-0 terminal';
|
||||
|
||||
$rJSON->lastResponse(2);
|
||||
cmp_deeply(
|
||||
$rJSON->recordResponses($session, {
|
||||
'1-0comment' => 'Section 1, question 0 comment',
|
||||
'1-0-0' => 'First answer',
|
||||
'1-0-0comment' => 'Section 1, question 0, answer 0 comment',
|
||||
}),
|
||||
[ 1, 'question 1-0 terminal' ],
|
||||
'recordResponses: question terminal overrides section terminal',
|
||||
);
|
||||
is($rJSON->lastResponse(), 4, 'lastResponse advanced to next page of questions');
|
||||
is($rJSON->questionsAnswered, 1, 'questionsAnswered=1, answered one question');
|
||||
|
||||
cmp_deeply(
|
||||
$rJSON->responses,
|
||||
{
|
||||
'1-0' => {
|
||||
comment => 'Section 1, question 0 comment',
|
||||
},
|
||||
'1-0-0' => {
|
||||
comment => 'Section 1, question 0, answer 0 comment',
|
||||
'time' => num(time(), 3),
|
||||
value => 1,
|
||||
},
|
||||
'1-1' => {
|
||||
comment => undef,
|
||||
}
|
||||
},
|
||||
'recordResponses: recorded responses correctly, two questions, one answer, comments, values and time'
|
||||
);
|
||||
|
||||
$rJSON->survey->question([1,0,0])->{terminal} = 1;
|
||||
$rJSON->survey->question([1,0,0])->{terminalUrl} = 'answer 1-0-0 terminal';
|
||||
$rJSON->{responses} = {};
|
||||
$rJSON->lastResponse(2);
|
||||
$rJSON->questionsAnswered(-1 * $rJSON->questionsAnswered);
|
||||
|
||||
cmp_deeply(
|
||||
$rJSON->recordResponses($session, {
|
||||
'1-0comment' => 'Section 1, question 0 comment',
|
||||
'1-0-0' => "\t\t\t\n\n\n\t\t\t", #SOS in whitespace
|
||||
'1-0-0comment' => 'Section 1, question 0, answer 0 comment',
|
||||
}),
|
||||
[ 1, 'answer 1-0-0 terminal' ],
|
||||
'recordResponses: answer terminal overrides question and section terminals',
|
||||
);
|
||||
|
||||
cmp_deeply(
|
||||
$rJSON->responses,
|
||||
{
|
||||
'1-0' => {
|
||||
comment => 'Section 1, question 0 comment',
|
||||
},
|
||||
'1-1' => {
|
||||
comment => undef,
|
||||
}
|
||||
},
|
||||
'recordResponses: if the answer is all whitespace, it is skipped over'
|
||||
);
|
||||
is($rJSON->questionsAnswered, 0, 'question was all whitespace, not answered');
|
||||
|
||||
}
|
||||
|
||||
####################################################
|
||||
#
|
||||
# Utility test routines
|
||||
#
|
||||
####################################################
|
||||
|
||||
sub buildSurveyJSON {
|
||||
my $session = shift;
|
||||
my $sjson = WebGUI::Asset::Wobject::Survey::SurveyJSON->new(undef, $session->log);
|
||||
##Build 4 sections. Remembering that one is created by default when you make an empty SurveyJSON object
|
||||
$sjson->newObject([]);
|
||||
$sjson->newObject([]);
|
||||
$sjson->newObject([]);
|
||||
##Add questions to the sections
|
||||
$sjson->newObject([0]);
|
||||
$sjson->newObject([0]);
|
||||
$sjson->newObject([0]);
|
||||
$sjson->newObject([1]);
|
||||
$sjson->newObject([1]);
|
||||
##Section 3 has no questions
|
||||
$sjson->newObject([3]);
|
||||
$sjson->newObject([3]);
|
||||
$sjson->newObject([3]);
|
||||
##Add questions
|
||||
$sjson->updateQuestionAnswers([0,0], 'Email');
|
||||
$sjson->updateQuestionAnswers([0,1], 'Phone number');
|
||||
$sjson->updateQuestionAnswers([0,2], 'Yes/No');
|
||||
$sjson->updateQuestionAnswers([1,0], 'True/False');
|
||||
$sjson->updateQuestionAnswers([1,1], 'Gender');
|
||||
$sjson->updateQuestionAnswers([3,0], 'Date Range');
|
||||
$sjson->updateQuestionAnswers([3,1], 'Ideology');
|
||||
$sjson->updateQuestionAnswers([3,2], 'Email');
|
||||
##Title the sections and questions
|
||||
$sjson->section([0])->{title} = "Section 0";
|
||||
$sjson->section([1])->{title} = "Section 1";
|
||||
$sjson->section([2])->{title} = "Section 2";
|
||||
$sjson->section([3])->{title} = "Section 3";
|
||||
$sjson->question([0,0])->{text} = "Question 0-0";
|
||||
$sjson->question([0,1])->{text} = "Question 0-1";
|
||||
$sjson->question([0,2])->{text} = "Question 0-2";
|
||||
$sjson->question([1,0])->{text} = "Question 1-0";
|
||||
$sjson->question([1,1])->{text} = "Question 1-1";
|
||||
$sjson->question([3,0])->{text} = "Question 3-0";
|
||||
$sjson->question([3,1])->{text} = "Question 3-1";
|
||||
$sjson->question([3,2])->{text} = "Question 3-2";
|
||||
return $sjson;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
|
|
|||
133
t/Form/TimeField.pm
Normal file
133
t/Form/TimeField.pm
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2008 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 FindBin;
|
||||
use strict;
|
||||
use lib "$FindBin::Bin/../lib";
|
||||
|
||||
use WebGUI::Test;
|
||||
use WebGUI::Form;
|
||||
use WebGUI::Form::TimeField;
|
||||
use WebGUI::Session;
|
||||
use HTML::Form;
|
||||
use WebGUI::Form_Checking;
|
||||
|
||||
#The goal of this test is to verify that Text form elements work
|
||||
|
||||
use Test::More; # increment this value for each test you create
|
||||
|
||||
my $session = WebGUI::Test->session;
|
||||
|
||||
# put your tests here
|
||||
|
||||
my $testBlock = [
|
||||
{
|
||||
key => 'Time1',
|
||||
testValue => '00:00:10',
|
||||
expected => '10',
|
||||
comment => 'Send it mysql format data, seconds',
|
||||
},
|
||||
{
|
||||
key => 'Time2',
|
||||
testValue => '00:10:00',
|
||||
expected => '600',
|
||||
comment => 'Send it mysql format data, minutes',
|
||||
},
|
||||
{
|
||||
key => 'Time3',
|
||||
testValue => '10',
|
||||
expected => '10',
|
||||
comment => 'Send it seconds format data',
|
||||
},
|
||||
];
|
||||
|
||||
my $formType = 'text'; ##timeField is a text subclass
|
||||
|
||||
my $numTests = 37 + scalar @{ $testBlock };
|
||||
|
||||
plan tests => $numTests;
|
||||
|
||||
my ($header, $footer) = (WebGUI::Form::formHeader($session), WebGUI::Form::formFooter($session));
|
||||
|
||||
my $html = join "\n",
|
||||
$header,
|
||||
WebGUI::Form::TimeField->new($session, {
|
||||
name => 'TestTime',
|
||||
value => '00:00:10',
|
||||
})->toHtml,
|
||||
$footer;
|
||||
|
||||
my @forms = HTML::Form->parse($html, 'http://www.webgui.org');
|
||||
|
||||
##Test Form Generation
|
||||
|
||||
is(scalar @forms, 1, '1 form was parsed');
|
||||
|
||||
my @inputs = $forms[0]->inputs;
|
||||
is(scalar @inputs, 2, 'The form has 2 inputs. One for the field, another for the JS pop-up button.');
|
||||
|
||||
#Basic tests
|
||||
|
||||
my $input = $inputs[0];
|
||||
is($input->name, 'TestTime', 'Checking input name');
|
||||
is($input->type, $formType, 'Checking input type');
|
||||
is($input->value, '00:00:10', 'Checking default value');
|
||||
|
||||
WebGUI::Form_Checking::auto_check($session, 'TimeField', $testBlock);
|
||||
|
||||
# test that we can process non-POST values correctly
|
||||
my $cntl;
|
||||
$cntl = WebGUI::Form::TimeField->new($session,{ });
|
||||
is($cntl->getValue('10'), '10', 'no default, not mysql mode, all digits');
|
||||
is($cntl->getValue('00:00:10'), '10', 'no default, not mysql mode, mysql formatted data, 3 pairs');
|
||||
is($cntl->getValue('00:10'), '600', 'no default, not mysql mode, mysql formatted data, 2 pairs');
|
||||
is($cntl->getValue('00:10:00'), '600', 'no default, not mysql mode, mysql formatted data, 3 pairs');
|
||||
is($cntl->getValue('innocent'), undef, 'no default, not mysql mode, wrong data');
|
||||
|
||||
$cntl = WebGUI::Form::TimeField->new($session,{ format => 'mysql' });
|
||||
is($cntl->getValue('10'), '00:00:10', 'no default, mysql mode, all digits');
|
||||
is($cntl->getValue('00:00:10'), '00:00:10', 'no default, mysql mode, mysql formatted data, 3 pairs');
|
||||
is($cntl->getValue('00:10'), '00:10', 'no default, mysql mode, mysql formatted data, 2 pairs');
|
||||
is($cntl->getValue('00:10:00'), '00:10:00', 'no default, mysql mode, mysql formatted data, 3 pairs');
|
||||
is($cntl->getValue('innocent'), undef, 'no default, mysql mode, wrong data');
|
||||
|
||||
$cntl = WebGUI::Form::TimeField->new($session,{ defaultValue => 0, });
|
||||
is($cntl->getValue('10'), '10', '0 default, not mysql mode, all digits');
|
||||
is($cntl->getValue('00:00:10'), '10', '0 default, not mysql mode, mysql formatted data, 3 pairs');
|
||||
is($cntl->getValue('00:10'), '600', '0 default, not mysql mode, mysql formatted data, 2 pairs');
|
||||
is($cntl->getValue('00:10:00'), '600', '0 default, not mysql mode, mysql formatted data, 3 pairs');
|
||||
|
||||
$cntl = WebGUI::Form::TimeField->new($session,{ defaultValue => 1, });
|
||||
is($cntl->getValue('10'), '10', '1 default, not mysql mode, all digits');
|
||||
is($cntl->getValue('00:00:10'), '10', '1 default, not mysql mode, mysql formatted data, 3 pairs');
|
||||
is($cntl->getValue('00:10'), '600', '1 default, not mysql mode, mysql formatted data, 2 pairs');
|
||||
is($cntl->getValue('00:10:00'), '600', '1 default, not mysql mode, mysql formatted data, 3 pairs');
|
||||
|
||||
$cntl = WebGUI::Form::TimeField->new($session,{ defaultValue => '55:55:55', });
|
||||
is($cntl->getValue('10'), '00:00:10', 'mysql defaultValue, all digits');
|
||||
is($cntl->getValue('00:00:10'), '00:00:10', 'mysql defaultValue, mysql formatted data, 3 pairs');
|
||||
is($cntl->getValue('00:10'), '00:10', 'mysql defaultValue, mysql formatted data, 2 pairs');
|
||||
is($cntl->getValue('00:10:00'), '00:10:00', 'mysql defaultValue, mysql formatted data, 3 pairs');
|
||||
|
||||
$cntl = WebGUI::Form::TimeField->new($session,{ defaultValue => 0, format => 'mysql', });
|
||||
is($cntl->getValue('10'), '00:00:10', '0 default, mysql mode, all digits');
|
||||
is($cntl->getValue('00:00:10'), '00:00:10', '0 default, mysql mode, mysql formatted data, 3 pairs');
|
||||
is($cntl->getValue('00:10'), '00:10', '0 default, mysql mode, mysql formatted data, 2 pairs');
|
||||
is($cntl->getValue('00:10:00'), '00:10:00', '0 default, mysql mode, mysql formatted data, 3 pairs');
|
||||
is($cntl->getValue('high noon'), undef, '0 default, mysql mode, mysql formatted data, bad data');
|
||||
|
||||
$cntl = WebGUI::Form::TimeField->new($session,{ defaultValue => 1, format => 'mysql', });
|
||||
is($cntl->getValue('10'), '00:00:10', '1 default, mysql mode, all digits');
|
||||
is($cntl->getValue('00:00:10'), '00:00:10', '1 default, mysql mode, mysql formatted data, 3 pairs');
|
||||
is($cntl->getValue('00:10'), '00:10', '1 default, mysql mode, mysql formatted data, 2 pairs');
|
||||
is($cntl->getValue('00:10:00'), '00:10:00', '1 default, mysql mode, mysql formatted data, 3 pairs');
|
||||
|
||||
__END__
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ use Test::More; # increment this value for each test you create
|
|||
|
||||
my $session = WebGUI::Test->session;
|
||||
|
||||
my $numTests = 0;
|
||||
my $numTests = 2;
|
||||
|
||||
$numTests += 1; #For the use_ok
|
||||
|
||||
|
|
@ -29,9 +29,22 @@ plan tests => $numTests;
|
|||
my $macro = 'WebGUI::Macro::AdminBar';
|
||||
my $loaded = use_ok($macro);
|
||||
|
||||
my $originalAssets = $session->config->get('assets');
|
||||
|
||||
SKIP: {
|
||||
|
||||
skip "Unable to load $macro", $numTests-1 unless $loaded;
|
||||
|
||||
my $output;
|
||||
$output = WebGUI::Macro::AdminBar::process($session);
|
||||
is($output, undef, 'AdminBar returns undef unless admin is on');
|
||||
$session->var->switchAdminOn;
|
||||
$output = WebGUI::Macro::AdminBar::process($session);
|
||||
ok($output, 'AdminBar returns something when admin is on');
|
||||
|
||||
|
||||
}
|
||||
|
||||
END: {
|
||||
$session->config->set('assets', $originalAssets);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ my $cwd = Cwd::cwd();
|
|||
|
||||
my ($extensionTests, $fileIconTests) = setupDataDrivenTests($session);
|
||||
|
||||
my $numTests = 75; # increment this value for each test you create
|
||||
my $numTests = 74; # increment this value for each test you create
|
||||
plan tests => $numTests + scalar @{ $extensionTests } + scalar @{ $fileIconTests };
|
||||
|
||||
my $uploadDir = $session->config->get('uploadsPath');
|
||||
|
|
@ -38,9 +38,6 @@ ok ($uploadDir, "uploadDir defined in config");
|
|||
my $uploadUrl = $session->config->get('uploadsURL');
|
||||
ok ($uploadUrl, "uploadDir defined in config");
|
||||
|
||||
my $originalCaseInsensitiveOS = $session->config->get('caseInsensitiveOS');
|
||||
$session->config->set('caseInsensitiveOS', 0);
|
||||
|
||||
####################################################
|
||||
#
|
||||
# get, getId
|
||||
|
|
@ -147,7 +144,6 @@ $storage1 = WebGUI::Storage->create($session);
|
|||
|
||||
isa_ok( $storage1, "WebGUI::Storage");
|
||||
ok($session->id->valid($storage1->getId), 'create returns valid sessionIds');
|
||||
is($storage1->getId, $storage1->getFileId, 'getId and getFileId are the same when caseInsensitiveOS=0');
|
||||
|
||||
is( $storage1->getErrorCount, 0, "No errors during object creation");
|
||||
|
||||
|
|
@ -462,5 +458,4 @@ END {
|
|||
) {
|
||||
ref $stor eq "WebGUI::Storage" and $stor->delete;
|
||||
}
|
||||
$session->config->set('caseInsensitiveOS', $originalCaseInsensitiveOS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,9 +75,6 @@ ok ($uploadDir, "uploadDir defined in config");
|
|||
my $uploadUrl = $session->config->get('uploadsURL');
|
||||
ok ($uploadUrl, "uploadDir defined in config");
|
||||
|
||||
my $originalCaseInsensitiveOS = $session->config->get('caseInsensitiveOS');
|
||||
$session->config->set('caseInsensitiveOS', 0);
|
||||
|
||||
####################################################
|
||||
#
|
||||
# getFile
|
||||
|
|
|
|||
|
|
@ -22,13 +22,18 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
Dom.setStyle(elCell.parentNode, "background-color", color);
|
||||
}
|
||||
elCell.innerHTML = sData;
|
||||
}else{
|
||||
elCell.innerHTML = sData;
|
||||
}
|
||||
};
|
||||
this.formatLabel = function(elCell, oRecord, oColumn, sData) {
|
||||
if(oRecord.getData("fieldType") == 'category'){
|
||||
elCell.innerHTML = "<b>" +sData + "</b>";
|
||||
}else{
|
||||
elCell.innerHTML = sData;
|
||||
elCell.innerHTML = sData;
|
||||
if(oRecord.getData("description")){
|
||||
elCell.innerHTML = elCell.innerHTML + "<div class='wg-hoverhelp'>" + oRecord.getData("description") +"</div>";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -52,8 +57,14 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
uri = uri+';listingId='+listingIds[i];
|
||||
}
|
||||
|
||||
var initAttributeHoverHelp = function() {
|
||||
initHoverHelp('compareList');
|
||||
}
|
||||
|
||||
var myDataTable = new YAHOO.widget.DataTable("compareList", myColumnDefs,
|
||||
this.myDataSource, {initialRequest:uri});
|
||||
myDataTable.subscribe("initEvent", initAttributeHoverHelp);
|
||||
|
||||
|
||||
window.removeListing = function(key) {
|
||||
myDataTable.hideColumn(myDataTable.removeColumn(key));
|
||||
|
|
@ -75,7 +86,7 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
|
||||
for (var i = 0; i < len; i++) {
|
||||
var c = oFullResponse.ColumnDefs[i];
|
||||
oFullResponse.ColumnDefs[i].label = oFullResponse.ColumnDefs[i].label + "<a href='javascript:removeListing(\""+oFullResponse.ColumnDefs[i].key+"\")'><img src='/extras/toolbar/bullet/delete.gif' border='0'></a>"
|
||||
oFullResponse.ColumnDefs[i].label = "<a href='"+ oFullResponse.ColumnDefs[i].url +"'>" + oFullResponse.ColumnDefs[i].label + "</a> <a href='javascript:removeListing(\""+oFullResponse.ColumnDefs[i].key+"\")'><img src='/extras/toolbar/bullet/delete.gif' border='0'></a>"
|
||||
myDataTable.insertColumn(c);
|
||||
}
|
||||
}
|
||||
|
|
@ -83,8 +94,9 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
}
|
||||
|
||||
var myCallback = function() {
|
||||
this.set("sortedBy", null);
|
||||
this.onDataReturnAppendRows.apply(this,arguments);
|
||||
this.set("sortedBy", null);
|
||||
this.onDataReturnAppendRows.apply(this,arguments);
|
||||
initHoverHelp('compareList');
|
||||
};
|
||||
|
||||
var callback2 = {
|
||||
|
|
@ -170,7 +182,6 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
hideStickies = 0;
|
||||
}
|
||||
},this,true);
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -17,14 +17,22 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
if(oRecord.getData("fieldType") == 'category'){
|
||||
elCell.innerHTML = "<b>" +sData + "</b>";
|
||||
}else{
|
||||
elCell.innerHTML = sData + "<div class='wg-hoverhelp'>" + oRecord.getData("description") +"</div>";
|
||||
}
|
||||
};
|
||||
this.formatColors = function(elCell, oRecord, oColumn, sData) {
|
||||
if(oRecord.getData("fieldType") != 'category'){
|
||||
var color = oRecord.getData("compareColor");
|
||||
if(color){
|
||||
Dom.setStyle(elCell.parentNode, "background-color", color);
|
||||
}
|
||||
elCell.innerHTML = sData;
|
||||
}
|
||||
};
|
||||
|
||||
var myColumnDefs = [
|
||||
{key:"stickied",formatter:this.formatStickied,label:""},
|
||||
{key:"label",formatter:this.formatLabel,label:""},
|
||||
{key:"value",label:""}
|
||||
{key:"value",label:"",formatter:this.formatColors}
|
||||
];
|
||||
|
||||
this.myDataSource = new YAHOO.util.DataSource("?");
|
||||
|
|
@ -32,13 +40,18 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
this.myDataSource.connXhrMode = "queueRequests";
|
||||
this.myDataSource.responseSchema = {
|
||||
resultsList: "ResultSet.Result",
|
||||
fields: ["label","value","attributeId","fieldType","checked"]
|
||||
fields: ["label","value","attributeId","fieldType","checked","description","compareColor"]
|
||||
};
|
||||
|
||||
var uri = "func=getAttributes";
|
||||
|
||||
var initAttributeHoverHelp = function() {
|
||||
initHoverHelp('attributes');
|
||||
}
|
||||
|
||||
var myDataTable = new YAHOO.widget.DataTable("attributes", myColumnDefs,
|
||||
this.myDataSource, {initialRequest:uri});
|
||||
myDataTable.subscribe("initEvent", initAttributeHoverHelp);
|
||||
|
||||
|
||||
this.myDataSource.doBeforeParseData = function (oRequest, oFullResponse) {
|
||||
|
|
|
|||
129
www/extras/yui-webgui/build/form/datatable.js
vendored
129
www/extras/yui-webgui/build/form/datatable.js
vendored
|
|
@ -398,64 +398,39 @@ WebGUI.Form.DataTable
|
|||
div.parentNode.removeChild( div );
|
||||
};
|
||||
|
||||
// Function to add a column
|
||||
var addColumn = function ( e ) {
|
||||
// this is the dialog
|
||||
var form = this.element.getElementsByTagName( "form" )[0];
|
||||
|
||||
// Find the last indexed column
|
||||
var newIdx = 0;
|
||||
while ( form.elements[ "oldKey_" + newIdx ] ) { newIdx++; }
|
||||
|
||||
var div = document.createElement( "div" );
|
||||
div.id = "col_" + newIdx;
|
||||
|
||||
var button = form.elements[ "removeColumn_" + (newIdx - 1) ].cloneNode(true);
|
||||
button.id = "removeColumn_" + newIdx;
|
||||
var del = new YAHOO.widget.Button( "removeColumn_" + newIdx, {
|
||||
type : "push",
|
||||
container : div,
|
||||
onclick : {
|
||||
fn : function () { removeColumn( i ) },
|
||||
scope : this
|
||||
}
|
||||
} );
|
||||
|
||||
var oldKey = form.elements[ "oldKey_" + (newIdx - 1) ].cloneNode(true);
|
||||
oldKey.name = "oldKey_" + newIdx;
|
||||
oldKey.value = "";
|
||||
div.appendChild( oldKey );
|
||||
|
||||
var newKey = form.elements[ "newKey_" + (newIdx - 1) ].cloneNode(true);
|
||||
newKey.name = "newKey_" + newIdx;
|
||||
newKey.value = "New Column " + newIdx;
|
||||
div.appendChild( newKey );
|
||||
|
||||
var format = form.elements[ "format_" + (newIdx - 1) ].cloneNode(true);
|
||||
format.name = "format_" + newIdx;
|
||||
format.selectedIndex = 0;
|
||||
div.appendChild( format );
|
||||
|
||||
form.appendChild( div );
|
||||
};
|
||||
var buttonLabel = this.i18n.get( "Form_DataTable", "delete column" );
|
||||
var availableFormats = [
|
||||
{
|
||||
"value" : "text",
|
||||
"label" : this.i18n.get( "Form_DataTable", "format text" )
|
||||
},
|
||||
{
|
||||
"value" : "number",
|
||||
"label" : this.i18n.get( "Form_DataTable", "format number" )
|
||||
},
|
||||
{
|
||||
"value" : "email",
|
||||
"label" : this.i18n.get( "Form_DataTable", "format email" )
|
||||
},
|
||||
{
|
||||
"value" : "link",
|
||||
"label" : this.i18n.get( "Form_DataTable", "format link" )
|
||||
},
|
||||
{
|
||||
"value" : "date",
|
||||
"label" : this.i18n.get( "Form_DataTable", "format date" )
|
||||
}
|
||||
];
|
||||
|
||||
var dg = new YAHOO.widget.Dialog( "editSchemaDialog", {
|
||||
modal : true,
|
||||
fixedcenter : true
|
||||
});
|
||||
dg.setHeader( this.i18n.get( "Form_DataTable", "edit schema" ) );
|
||||
|
||||
var body = document.createElement( 'form' );
|
||||
var cols = this.dataTable.getColumnSet().keys;
|
||||
for ( var i = 0; i < cols.length; i++ ) {
|
||||
//TODO: Refactor this to be a function, like addColumn above
|
||||
// function for creating new database columns to the table schema
|
||||
var createTableColumn = function(i,cols) {
|
||||
var div = document.createElement( 'div' );
|
||||
div.className = "yui-skin-sam";
|
||||
div.id = "col_" + i;
|
||||
|
||||
var del = new YAHOO.widget.Button( {
|
||||
type : "push",
|
||||
label : this.i18n.get( "Form_DataTable", "delete column" ),
|
||||
label : buttonLabel,
|
||||
container : div,
|
||||
onclick : {
|
||||
fn : removeColumn,
|
||||
|
|
@ -478,28 +453,7 @@ WebGUI.Form.DataTable
|
|||
|
||||
var format = document.createElement('select');
|
||||
format.name = "format_" + i;
|
||||
var availableFormats = [
|
||||
{
|
||||
"value" : "text",
|
||||
"label" : this.i18n.get( "Form_DataTable", "format text" )
|
||||
},
|
||||
{
|
||||
"value" : "number",
|
||||
"label" : this.i18n.get( "Form_DataTable", "format number" )
|
||||
},
|
||||
{
|
||||
"value" : "email",
|
||||
"label" : this.i18n.get( "Form_DataTable", "format email" )
|
||||
},
|
||||
{
|
||||
"value" : "link",
|
||||
"label" : this.i18n.get( "Form_DataTable", "format link" )
|
||||
},
|
||||
{
|
||||
"value" : "date",
|
||||
"label" : this.i18n.get( "Form_DataTable", "format date" )
|
||||
}
|
||||
];
|
||||
|
||||
for ( var x = 0; x < availableFormats.length; x++ ) {
|
||||
var opt = new Option(
|
||||
availableFormats[x].label,
|
||||
|
|
@ -509,8 +463,31 @@ WebGUI.Form.DataTable
|
|||
format.appendChild( opt );
|
||||
}
|
||||
div.appendChild( format );
|
||||
return div;
|
||||
};
|
||||
|
||||
// Function to add a column
|
||||
var addColumn = function ( e, cols ) {
|
||||
// this is the body of the dialog box
|
||||
|
||||
body.appendChild( div );
|
||||
// Find the last indexed column
|
||||
var newIdx = cols.length;
|
||||
// create a new column object
|
||||
cols[newIdx] = new YAHOO.widget.Column;
|
||||
// add it to the dialog box
|
||||
this.appendChild( createTableColumn(newIdx,cols) );
|
||||
};
|
||||
|
||||
var dg = new YAHOO.widget.Dialog( "editSchemaDialog", {
|
||||
modal : true,
|
||||
fixedcenter : true
|
||||
});
|
||||
dg.setHeader( this.i18n.get( "Form_DataTable", "edit schema" ) );
|
||||
|
||||
var cols = this.dataTable.getColumnSet().keys;
|
||||
var body = document.createElement( 'form' );
|
||||
for ( var i = 0; i < cols.length; i++ ) {
|
||||
body.appendChild( createTableColumn(i,cols) );
|
||||
}
|
||||
|
||||
// Columns to delete
|
||||
|
|
@ -523,7 +500,7 @@ WebGUI.Form.DataTable
|
|||
dg.setBody( body );
|
||||
|
||||
dg.cfg.queueProperty( "buttons", [
|
||||
{ text: this.i18n.get( "Form_DataTable", "add column" ), handler: addColumn },
|
||||
{ text: this.i18n.get( "Form_DataTable", "add column" ), handler: { fn : addColumn, obj : cols, scope : body } },
|
||||
{ text: this.i18n.get( "Form_DataTable", "cancel" ), handler: { fn: this.hideSchemaDialog, scope: this } },
|
||||
{ text: this.i18n.get( "Form_DataTable", "save" ), handler: { fn: this.updateSchema, scope: this }, isDefault: true }
|
||||
] );
|
||||
|
|
@ -531,6 +508,8 @@ WebGUI.Form.DataTable
|
|||
this.schemaDialog = dg;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* submitToAjax ( event )
|
||||
* Save the data table to the AJAX URL
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue