Merge up to 10305
This commit is contained in:
parent
fa2e5c2c90
commit
1edaca4ed2
65 changed files with 1300 additions and 477 deletions
|
|
@ -1,7 +1,23 @@
|
|||
7.7.4
|
||||
- fixed #9989: thing-search template won't include data-save params in the url for pagination
|
||||
- fixed #10122: fixed date object to not change the value in 'toHtml' function.
|
||||
- fixed #9764: drag drop now uses the handle for 'pickup' rather than the whole object.
|
||||
- Default Survey Question bundles now store full answer information in json. Everything configured in an answer will be saved in a default configuration.
|
||||
- Survey [[question variable]] now returns the shown answer text for multiple choice questions, and the recorded value for non-multiple choice questions.
|
||||
- fixed #10142: Matrix 2.0 - Search screen compare button not functional
|
||||
- fixed #10141: Matrix 2.0 - Search does not check matching products
|
||||
- fixed #10077: after matrix sort can't return to alphanumeric sort
|
||||
- fixed #10138: Matrix 2.0 Links in Product Listing are broken
|
||||
|
||||
7.7.3
|
||||
- fixed #10094: double explanation in thread help
|
||||
- rfe #9612: Carousel Wobject (was Widget Wobject) (SDH Consulting Group)
|
||||
- Survey summaries now added. In the Survey edit, select quiz mode, and a summary will be shown to the user at the end of the survey.
|
||||
- fixed #10110: Matrix 2.0 - "Data Error" on Pending Product Listing Updates
|
||||
- rfe #9965: matrix/pls reverse dropped event variables
|
||||
- fixed install of Passive Analytics settings for new sites (SDH Consulting Group)
|
||||
- Survey Expression Engine upgraded (SDH Consulting Group)
|
||||
|
||||
7.7.2
|
||||
- fixed #10056: YUI javascripts included while adminOff (BNC)
|
||||
- fixed a bug that required you to hit "update cart" before the checkout
|
||||
|
|
|
|||
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.
BIN
docs/upgrades/packages-7.7.3/matrix-default-view-template.wgpkg
Normal file
BIN
docs/upgrades/packages-7.7.3/matrix-default-view-template.wgpkg
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
docs/upgrades/packages-7.7.3/survey.css.wgpkg
Normal file
BIN
docs/upgrades/packages-7.7.3/survey.css.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.7.4/default_page.wgpkg
Normal file
BIN
docs/upgrades/packages-7.7.4/default_page.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.7.4/matrix-default-view-template.wgpkg
Normal file
BIN
docs/upgrades/packages-7.7.4/matrix-default-view-template.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.7.4/matrix-search-template.wgpkg
Normal file
BIN
docs/upgrades/packages-7.7.4/matrix-search-template.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.7.4/new-matrix_matrix.css.wgpkg
Normal file
BIN
docs/upgrades/packages-7.7.4/new-matrix_matrix.css.wgpkg
Normal file
Binary file not shown.
Binary file not shown.
|
|
@ -23,7 +23,8 @@ use WebGUI::Session;
|
|||
use WebGUI::Storage;
|
||||
use WebGUI::Asset;
|
||||
use WebGUI::Utility;
|
||||
|
||||
use WebGUI::PassiveAnalytics::Rule;
|
||||
use WebGUI::Utility;
|
||||
|
||||
my $toVersion = '7.7.3';
|
||||
my $quiet; # this line required
|
||||
|
|
@ -35,11 +36,8 @@ my $session = start(); # this line required
|
|||
|
||||
addSurveyQuizModeColumns($session);
|
||||
addSurveyExpressionEngineConfigFlag($session);
|
||||
|
||||
# Story Manager
|
||||
installStoryManagerTables($session);
|
||||
sm_upgradeConfigFiles($session);
|
||||
sm_updateDailyWorkflow($session);
|
||||
addCarouselWobject($session);
|
||||
reInstallPassiveAnalyticsConfig($session);
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
|
|
@ -53,6 +51,22 @@ finish($session); # this line required
|
|||
# print "DONE!\n" unless $quiet;
|
||||
#}
|
||||
|
||||
sub addCarouselWobject{
|
||||
my $session = shift;
|
||||
print "\tAdding Carousel wobject... " unless $quiet;
|
||||
$session->db->write("create table Carousel (
|
||||
assetId char(22) binary not null,
|
||||
revisionDate bigint not null,
|
||||
items mediumtext,
|
||||
templateId char(22),
|
||||
primary key (assetId, revisionDate)
|
||||
)");
|
||||
my $assets = $session->config->get( "assets" );
|
||||
$assets->{ "WebGUI::Asset::Wobject::Carousel" } = { category => "utilities" };
|
||||
$session->config->set( "assets", $assets );
|
||||
print "Done.\n" unless $quiet;
|
||||
}
|
||||
|
||||
sub addSurveyQuizModeColumns{
|
||||
my $session = shift;
|
||||
print "\tAdding columns to Survey table... " unless $quiet;
|
||||
|
|
@ -68,97 +82,52 @@ sub addSurveyExpressionEngineConfigFlag{
|
|||
print "Done.\n" unless $quiet;
|
||||
}
|
||||
|
||||
sub installStoryManagerTables {
|
||||
my ($session) = @_;
|
||||
print "\tAdding Story Manager tables... " unless $quiet;
|
||||
my $db = $session->db;
|
||||
$db->write(<<EOSTORY);
|
||||
CREATE TABLE Story (
|
||||
assetId CHAR(22) BINARY NOT NULL,
|
||||
revisionDate BIGINT NOT NULL,
|
||||
headline CHAR(255),
|
||||
subtitle CHAR(255),
|
||||
byline CHAR(255),
|
||||
location CHAR(255),
|
||||
highlights TEXT,
|
||||
story MEDIUMTEXT,
|
||||
photo LONGTEXT,
|
||||
PRIMARY KEY ( assetId, revisionDate )
|
||||
)
|
||||
EOSTORY
|
||||
|
||||
$db->write(<<EOARCHIVE);
|
||||
CREATE TABLE StoryArchive (
|
||||
assetId CHAR(22) BINARY NOT NULL,
|
||||
revisionDate BIGINT NOT NULL,
|
||||
storiesPerPage INTEGER,
|
||||
groupToPost CHAR(22) BINARY,
|
||||
templateId CHAR(22) BINARY,
|
||||
storyTemplateId CHAR(22) BINARY,
|
||||
editStoryTemplateId CHAR(22) BINARY,
|
||||
archiveAfter INT(11),
|
||||
richEditorId CHAR(22) BINARY,
|
||||
approvalWorkflowId CHAR(22) BINARY DEFAULT 'pbworkflow000000000003',
|
||||
PRIMARY KEY ( assetId, revisionDate )
|
||||
)
|
||||
EOARCHIVE
|
||||
|
||||
$db->write(<<EOTOPIC);
|
||||
CREATE TABLE StoryTopic (
|
||||
assetId CHAR(22) BINARY NOT NULL,
|
||||
revisionDate BIGINT NOT NULL,
|
||||
storiesPer INTEGER,
|
||||
storiesShort INTEGER,
|
||||
templateId CHAR(22) BINARY,
|
||||
storyTemplateId CHAR(22) BINARY,
|
||||
PRIMARY KEY ( assetId, revisionDate )
|
||||
)
|
||||
EOTOPIC
|
||||
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
sub sm_upgradeConfigFiles {
|
||||
my ($session) = @_;
|
||||
print "\tAdding Story Manager to config file... " unless $quiet;
|
||||
my $config = $session->config;
|
||||
$config->addToHash(
|
||||
'assets',
|
||||
'WebGUI::Asset::Wobject::StoryTopic' => {
|
||||
'category' => 'community'
|
||||
},
|
||||
);
|
||||
$config->addToHash(
|
||||
'assets',
|
||||
"WebGUI::Asset::Wobject::StoryArchive" => {
|
||||
"isContainer" => 1,
|
||||
"category" => "community"
|
||||
},
|
||||
);
|
||||
my $activities = $config->get('workflowActivities');
|
||||
my $none = $activities->{None};
|
||||
if (!isIn('WebGUI::Workflow::Activity::ArchiveOldStories', @{ $none })) {
|
||||
unshift @{ $none }, 'WebGUI::Workflow::Activity::ArchiveOldStories';
|
||||
#----------------------------------------------------------------------------
|
||||
# Conditionally re-add passive analytics config because it wasn't added to WebGUI.conf.original
|
||||
# in version 7.7.0.
|
||||
sub reInstallPassiveAnalyticsConfig {
|
||||
my $session = shift;
|
||||
print "\tAdd Passive Analytics entry to the config file... " unless $quiet;
|
||||
# Admin Bar/Console
|
||||
my $adminConsole = $session->config->get('adminConsole');
|
||||
if (!exists $adminConsole->{'passiveAnalytics'}) {
|
||||
$adminConsole->{'passiveAnalytics'} = {
|
||||
"icon" => "passiveAnalytics.png",
|
||||
"uiLevel" => 1,
|
||||
"url" => "^PageUrl(\"\",op=passiveAnalytics;func=editRuleflow);",
|
||||
"title" => "^International(Passive Analytics,PassiveAnalytics);",
|
||||
"groupSetting" => "3",
|
||||
};
|
||||
$session->config->set('adminConsole', $adminConsole);
|
||||
}
|
||||
$config->set('workflowActivities', $activities);
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
sub sm_updateDailyWorkflow {
|
||||
my ($session) = @_;
|
||||
print "\tAdding Archive Old Stories to Daily Workflow... " unless $quiet;
|
||||
my $workflow = WebGUI::Workflow->new($session, 'pbworkflow000000000001');
|
||||
foreach my $activity (@{ $workflow->getActivities }) {
|
||||
return if $activity->getName() eq 'WebGUI::Workflow::Activity::ArchiveOldStories';
|
||||
# Content Handler
|
||||
my $contentHandlers = $session->config->get('contentHandlers');
|
||||
if (!isIn('WebGUI::Content::PassiveAnalytics',@{ $contentHandlers} ) ) {
|
||||
my $contentIndex = 0;
|
||||
HANDLER: while ($contentIndex <= $#{ $contentHandlers } ) {
|
||||
##Insert before Operation
|
||||
if($contentHandlers->[$contentIndex] eq 'WebGUI::Content::Operation') {
|
||||
splice @{ $contentHandlers }, $contentIndex, 0, 'WebGUI::Content::PassiveAnalytics';
|
||||
last HANDLER;
|
||||
}
|
||||
++$contentIndex;
|
||||
}
|
||||
$session->config->set('contentHandlers', $contentHandlers);
|
||||
}
|
||||
my $activity = $workflow->addActivity('WebGUI::Workflow::Activity::ArchiveOldStories');
|
||||
$activity->set('title', 'Archive Old Stories');
|
||||
$activity->set('description', 'Archive old stories, based on the settings of the Story Archives that own them');
|
||||
# Workflow Activities
|
||||
my $workflowActivities = $session->config->get('workflowActivities');
|
||||
my @none = @{ $workflowActivities->{'None'} };
|
||||
if (!isIn('WebGUI::Workflow::Activity::SummarizePassiveAnalytics', @none)) {
|
||||
push @none, 'WebGUI::Workflow::Activity::SummarizePassiveAnalytics';
|
||||
}
|
||||
if (!isIn('WebGUI::Workflow::Activity::BucketPassiveAnalytics', @none)) {
|
||||
push @none, 'WebGUI::Workflow::Activity::BucketPassiveAnalytics';
|
||||
}
|
||||
$workflowActivities->{'None'} = [ @none ];
|
||||
$session->config->set('workflowActivities', $workflowActivities);
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
|
|
|||
280
docs/upgrades/upgrade_7.7.3-7.7.4.pl
Normal file
280
docs/upgrades/upgrade_7.7.3-7.7.4.pl
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 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;
|
||||
use WebGUI::Utility;
|
||||
use JSON;
|
||||
|
||||
my $toVersion = '7.7.4';
|
||||
my $quiet; # this line required
|
||||
|
||||
|
||||
my $session = start(); # this line required
|
||||
|
||||
# upgrade functions go here
|
||||
updateSurveyQuestionTypes($session);
|
||||
|
||||
# Story Manager
|
||||
installStoryManagerTables($session);
|
||||
sm_upgradeConfigFiles($session);
|
||||
sm_updateDailyWorkflow($session);
|
||||
|
||||
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;
|
||||
#}
|
||||
sub updateSurveyQuestionTypes{
|
||||
my $session = shift;
|
||||
my $refs = $session->db->buildArrayRefOfHashRefs("SELECT * FROM Survey_questionTypes");
|
||||
for my $ref(@$refs){
|
||||
my $name = $ref->{questionType};
|
||||
my $params;
|
||||
my @texts = split/,/,$ref->{answers};
|
||||
#next if(@texts == 0);
|
||||
my $count = 0;
|
||||
for my $text(@texts){
|
||||
my $verbatim = 0;
|
||||
$verbatim = 1 if($text =~ /verbatim/);
|
||||
push(@$params,[$text,$count++,$verbatim]);
|
||||
}
|
||||
_loadValues($name,$params,$session);
|
||||
}
|
||||
}
|
||||
|
||||
sub _loadValues{
|
||||
my $name = shift;
|
||||
my $values = shift;
|
||||
my $session = shift;
|
||||
my $answers = [];
|
||||
for my $value(@$values){
|
||||
my $answer = _getAnswer();
|
||||
$answer->{text} = $value->[0];
|
||||
$answer->{recordedAnswer} = $value->[1];
|
||||
$answer->{verbatim} = $value->[2];
|
||||
push @$answers,$answer;
|
||||
}
|
||||
my $json = to_json($answers);
|
||||
$session->db->write("UPDATE Survey_questionTypes SET answers = ? WHERE questionType = ?",[$json,$name]);
|
||||
}
|
||||
|
||||
sub _getAnswer{
|
||||
my $answer = {
|
||||
text => q{},
|
||||
verbatim => 0,
|
||||
textCols => 10,
|
||||
textRows => 5,
|
||||
goto => q{},
|
||||
gotoExpression => q{},
|
||||
recordedAnswer => q{},
|
||||
isCorrect => 1,
|
||||
min => 1,
|
||||
max => 10,
|
||||
step => 1,
|
||||
value => 1,
|
||||
terminal => 0,
|
||||
terminalUrl => q{},
|
||||
type => 'answer'
|
||||
};
|
||||
return $answer;
|
||||
}
|
||||
|
||||
sub installStoryManagerTables {
|
||||
my ($session) = @_;
|
||||
print "\tAdding Story Manager tables... " unless $quiet;
|
||||
my $db = $session->db;
|
||||
$db->write(<<EOSTORY);
|
||||
CREATE TABLE Story (
|
||||
assetId CHAR(22) BINARY NOT NULL,
|
||||
revisionDate BIGINT NOT NULL,
|
||||
headline CHAR(255),
|
||||
subtitle CHAR(255),
|
||||
byline CHAR(255),
|
||||
location CHAR(255),
|
||||
highlights TEXT,
|
||||
story MEDIUMTEXT,
|
||||
photo LONGTEXT,
|
||||
PRIMARY KEY ( assetId, revisionDate )
|
||||
)
|
||||
EOSTORY
|
||||
|
||||
$db->write(<<EOARCHIVE);
|
||||
CREATE TABLE StoryArchive (
|
||||
assetId CHAR(22) BINARY NOT NULL,
|
||||
revisionDate BIGINT NOT NULL,
|
||||
storiesPerPage INTEGER,
|
||||
groupToPost CHAR(22) BINARY,
|
||||
templateId CHAR(22) BINARY,
|
||||
storyTemplateId CHAR(22) BINARY,
|
||||
editStoryTemplateId CHAR(22) BINARY,
|
||||
archiveAfter INT(11),
|
||||
richEditorId CHAR(22) BINARY,
|
||||
approvalWorkflowId CHAR(22) BINARY DEFAULT 'pbworkflow000000000003',
|
||||
PRIMARY KEY ( assetId, revisionDate )
|
||||
)
|
||||
EOARCHIVE
|
||||
|
||||
$db->write(<<EOTOPIC);
|
||||
CREATE TABLE StoryTopic (
|
||||
assetId CHAR(22) BINARY NOT NULL,
|
||||
revisionDate BIGINT NOT NULL,
|
||||
storiesPer INTEGER,
|
||||
storiesShort INTEGER,
|
||||
templateId CHAR(22) BINARY,
|
||||
storyTemplateId CHAR(22) BINARY,
|
||||
PRIMARY KEY ( assetId, revisionDate )
|
||||
)
|
||||
EOTOPIC
|
||||
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
sub sm_upgradeConfigFiles {
|
||||
my ($session) = @_;
|
||||
print "\tAdding Story Manager to config file... " unless $quiet;
|
||||
my $config = $session->config;
|
||||
$config->addToHash(
|
||||
'assets',
|
||||
'WebGUI::Asset::Wobject::StoryTopic' => {
|
||||
'category' => 'community'
|
||||
},
|
||||
);
|
||||
$config->addToHash(
|
||||
'assets',
|
||||
"WebGUI::Asset::Wobject::StoryArchive" => {
|
||||
"isContainer" => 1,
|
||||
"category" => "community"
|
||||
},
|
||||
);
|
||||
my $activities = $config->get('workflowActivities');
|
||||
my $none = $activities->{None};
|
||||
if (!isIn('WebGUI::Workflow::Activity::ArchiveOldStories', @{ $none })) {
|
||||
unshift @{ $none }, 'WebGUI::Workflow::Activity::ArchiveOldStories';
|
||||
}
|
||||
$config->set('workflowActivities', $activities);
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
sub sm_updateDailyWorkflow {
|
||||
my ($session) = @_;
|
||||
print "\tAdding Archive Old Stories to Daily Workflow... " unless $quiet;
|
||||
my $workflow = WebGUI::Workflow->new($session, 'pbworkflow000000000001');
|
||||
foreach my $activity (@{ $workflow->getActivities }) {
|
||||
return if $activity->getName() eq 'WebGUI::Workflow::Activity::ArchiveOldStories';
|
||||
}
|
||||
my $activity = $workflow->addActivity('WebGUI::Workflow::Activity::ArchiveOldStories');
|
||||
$activity->set('title', 'Archive Old Stories');
|
||||
$activity->set('description', 'Archive old stories, based on the settings of the Story Archives that own them');
|
||||
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 );
|
||||
|
||||
# Turn off the package flag, and set the default flag for templates added
|
||||
my $assetIds = $package->getLineage( ['self','descendants'] );
|
||||
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;
|
||||
}
|
||||
my $properties = { isPackage => 0 };
|
||||
if ($asset->isa('WebGUI::Asset::Template')) {
|
||||
$properties->{isDefault} = 1;
|
||||
}
|
||||
$asset->update( $properties );
|
||||
}
|
||||
|
||||
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
|
||||
|
|
@ -345,6 +345,13 @@
|
|||
"title" : "^International(manage graphics,Graphics);",
|
||||
"groupSetting" : "groupIdAdminGraphics"
|
||||
},
|
||||
"passiveAnalytics" : {
|
||||
"icon" : "passiveAnalytics.png",
|
||||
"uiLevel" : 1,
|
||||
"url" : "^PageUrl(\"\",op=passiveAnalytics;func=editRuleflow);",
|
||||
"title" : "^International(Passive Analytics,PassiveAnalytics);",
|
||||
"groupSetting" : "3"
|
||||
},
|
||||
"shop" : {
|
||||
"icon" : "shop.gif",
|
||||
"uiLevel" : 5,
|
||||
|
|
@ -827,7 +834,9 @@
|
|||
"WebGUI::Workflow::Activity::SummarizePassiveProfileLog",
|
||||
"WebGUI::Workflow::Activity::SyncProfilesToLdap",
|
||||
"WebGUI::Workflow::Activity::TrashClipboard",
|
||||
"WebGUI::Workflow::Activity::TrashExpiredEvents"
|
||||
"WebGUI::Workflow::Activity::TrashExpiredEvents",
|
||||
"WebGUI::Workflow::Activity::SummarizePassiveAnalytics",
|
||||
"WebGUI::Workflow::Activity::BucketPassiveAnalytics"
|
||||
],
|
||||
"WebGUI::Asset::Wobject::Thingy" : [
|
||||
"WebGUI::Workflow::Activity::NotifyAboutThing"
|
||||
|
|
@ -912,6 +921,7 @@
|
|||
"WebGUI::Content::Referral",
|
||||
"WebGUI::Content::AssetManager",
|
||||
"WebGUI::Content::AssetDiscovery",
|
||||
"WebGUI::Content::PassiveAnalytics",
|
||||
"WebGUI::Content::AjaxI18N",
|
||||
"WebGUI::Content::Account",
|
||||
"WebGUI::Content::AssetHistory",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package WebGUI;
|
||||
|
||||
|
||||
our $VERSION = '7.7.3';
|
||||
our $VERSION = '7.7.4';
|
||||
our $STATUS = 'beta';
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,14 @@ use WebGUI::DateTime;
|
|||
=head1 Methods
|
||||
|
||||
|
||||
=cut
|
||||
|
||||
####################################################################
|
||||
|
||||
=head2 addRevision ( )
|
||||
|
||||
Extent the method from the super class to handle iCalSequenceNumbers.
|
||||
|
||||
=cut
|
||||
|
||||
sub addRevision {
|
||||
|
|
@ -1698,6 +1706,12 @@ sub processPropertiesFromFormPost {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 purge ( )
|
||||
|
||||
Extent the method from the super class to delete all storage locations.
|
||||
|
||||
=cut
|
||||
|
||||
sub purge {
|
||||
my $self = shift;
|
||||
my $sth = $self->session->db->read("select storageId from Event where assetId=?",[$self->getId]);
|
||||
|
|
@ -1711,6 +1725,12 @@ sub purge {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 purgeRevision ( )
|
||||
|
||||
Extent the method from the super class to delete the storage location for this revision.
|
||||
|
||||
=cut
|
||||
|
||||
sub purgeRevision {
|
||||
my $self = shift;
|
||||
$self->getStorageLocation->delete;
|
||||
|
|
@ -1908,6 +1928,13 @@ sub view {
|
|||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_deleteFile ( )
|
||||
|
||||
Delete a file given in the form variable "filename" from the storage location.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_deleteFile {
|
||||
my $self = shift;
|
||||
$self->getStorageLocation->deleteFile($self->session->form->process("filename")) if $self->canEdit;
|
||||
|
|
|
|||
|
|
@ -640,6 +640,13 @@ sub view {
|
|||
$var->{manufacturerUrl_click} = $self->getUrl("func=click;manufacturer=1");
|
||||
$var->{productUrl_click} = $self->getUrl("func=click");
|
||||
|
||||
if($self->get('status') eq 'pending'){
|
||||
my $revisionDate = $self->get('revisionDate');
|
||||
$var->{revision} = $revisionDate;
|
||||
$var->{manufacturerUrl_click} .= ';revision='.$revisionDate;
|
||||
$var->{productUrl_click} .= ';revision='.$revisionDate;
|
||||
}
|
||||
|
||||
$self->session->style->setScript($self->session->url->extras('yui/build/yahoo/yahoo-min.js'),
|
||||
{type => 'text/javascript'});
|
||||
$self->session->style->setScript($self->session->url->extras('yui/build/dom/dom-min.js'),
|
||||
|
|
|
|||
|
|
@ -144,6 +144,12 @@ sub definition {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 duplicate ( )
|
||||
|
||||
Extend the super class to duplicate the storage location.
|
||||
|
||||
=cut
|
||||
|
||||
sub duplicate {
|
||||
my $self = shift;
|
||||
my $newAsset = $self->SUPER::duplicate(@_);
|
||||
|
|
@ -169,6 +175,14 @@ sub exportAssetData {
|
|||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getStorageLocation ( )
|
||||
|
||||
Fetches the storage location for this asset. If it does not have one,
|
||||
then make one. Build an internal cache of the storage object.
|
||||
|
||||
=cut
|
||||
|
||||
sub getStorageLocation {
|
||||
my $self = shift;
|
||||
unless (exists $self->{_storageLocation}) {
|
||||
|
|
@ -223,6 +237,13 @@ sub prepareView {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 processPropertiesFromFormPost ( )
|
||||
|
||||
Extend the super class to calculate total asset size from
|
||||
any files stored in the storage location.
|
||||
|
||||
=cut
|
||||
|
||||
sub processPropertiesFromFormPost {
|
||||
my $self = shift;
|
||||
$self->SUPER::processPropertiesFromFormPost(@_);
|
||||
|
|
@ -235,6 +256,15 @@ sub processPropertiesFromFormPost {
|
|||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 update ( )
|
||||
|
||||
Extend the super class to handle the storage location. Sets
|
||||
the correct privileges and deletes the internally cached
|
||||
Storage object.
|
||||
|
||||
=cut
|
||||
|
||||
sub update {
|
||||
my $self = shift;
|
||||
my $previousStorageId = $self->get('storageId');
|
||||
|
|
@ -253,6 +283,12 @@ sub update {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 purge ( )
|
||||
|
||||
Extend the super class to delete all storage locations.
|
||||
|
||||
=cut
|
||||
|
||||
sub purge {
|
||||
my $self = shift;
|
||||
my $sth = $self->session->db->read("select storageId from Article where assetId=?",[$self->getId]);
|
||||
|
|
@ -280,6 +316,12 @@ sub purgeCache {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 purgeRevision ( )
|
||||
|
||||
Extend the super class to delete the storage location for this revision.
|
||||
|
||||
=cut
|
||||
|
||||
sub purgeRevision {
|
||||
my $self = shift;
|
||||
$self->getStorageLocation->delete;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ sub definition {
|
|||
%properties = (
|
||||
templateId =>{
|
||||
fieldType =>"template",
|
||||
defaultValue =>'CarouselTmpl0000000002',
|
||||
defaultValue =>'CarouselTmpl0000000001',
|
||||
tab =>"display",
|
||||
noFormPost =>0,
|
||||
namespace =>"Carousel",
|
||||
|
|
@ -273,66 +273,5 @@ adminConsole views.
|
|||
# return $self->getAdminConsole->render($self->getEditForm->print, $i18n->get("edit title"));
|
||||
#}
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# Everything below here is to make it easier to install your custom
|
||||
# wobject, but has nothing to do with wobjects in general
|
||||
#-------------------------------------------------------------------
|
||||
# cd /data/WebGUI/lib
|
||||
# perl -MWebGUI::Asset::Wobject::Carousel -e install www.example.com.conf [ /path/to/WebGUI ]
|
||||
# - or -
|
||||
# perl -MWebGUI::Asset::Wobject::Carousel -e uninstall www.example.com.conf [ /path/to/WebGUI ]
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
|
||||
use base 'Exporter';
|
||||
our @EXPORT = qw(install uninstall);
|
||||
use WebGUI::Session;
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
sub install {
|
||||
my $config = $ARGV[0];
|
||||
my $home = $ARGV[1] || "/data/WebGUI";
|
||||
die "usage: perl -MWebGUI::Asset::Wobject::Carousel -e install www.example.com.conf\n" unless ($home && $config);
|
||||
print "Installing asset.\n";
|
||||
my $session = WebGUI::Session->open($home, $config);
|
||||
|
||||
my $assets = $session->config->get( "assets" );
|
||||
$assets->{ "WebGUI::Asset::Wobject::Carousel" } = { category => "utilities" };
|
||||
$session->config->set( "assets", $assets );
|
||||
#$session->config->addToArray("assets","WebGUI::Asset::Wobject::Carousel");
|
||||
$session->db->write("create table Carousel (
|
||||
assetId char(22) binary not null,
|
||||
revisionDate bigint not null,
|
||||
items mediumtext,
|
||||
templateId char(22),
|
||||
primary key (assetId, revisionDate)
|
||||
)");
|
||||
$session->var->end;
|
||||
$session->close;
|
||||
print "Done. Please restart Apache.\n";
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
sub uninstall {
|
||||
my $config = $ARGV[0];
|
||||
my $home = $ARGV[1] || "/data/WebGUI";
|
||||
die "usage: perl -MWebGUI::Asset::Wobject::Carousel -e uninstall www.example.com.conf\n" unless ($home && $config);
|
||||
print "Uninstalling asset.\n";
|
||||
my $session = WebGUI::Session->open($home, $config);
|
||||
$session->config->deleteFromArray("assets","WebGUI::Asset::Wobject::Carousel");
|
||||
my $rs = $session->db->read("select assetId from asset where className='WebGUI::Asset::Wobject::Carousel'");
|
||||
while (my ($id) = $rs->array) {
|
||||
my $asset = WebGUI::Asset->new($session, $id, "WebGUI::Asset::Wobject::Carousel");
|
||||
$asset->purge if defined $asset;
|
||||
}
|
||||
$session->db->write("drop table Carousel");
|
||||
$session->var->end;
|
||||
$session->close;
|
||||
print "Done. Please restart Apache.\n";
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
#vim:ft=perl
|
||||
|
|
|
|||
|
|
@ -1452,5 +1452,18 @@ sub www_view {
|
|||
return $self->next::method(@_);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_viewRSS ( )
|
||||
|
||||
Deprecated. Use www_viewRss() instead.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_viewRSS {
|
||||
my $self = shift;
|
||||
return $self->www_viewRss;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
|
|
|||
|
|
@ -567,6 +567,8 @@ sub view {
|
|||
$varStatistics = JSON->new->decode($varStatisticsEncoded);
|
||||
}
|
||||
else{
|
||||
$varStatistics->{alphanumeric_sortButton} = "<span id='sortByName'><button type='button'>Sort by name</button></span><br />";
|
||||
|
||||
# Get the MatrixListing with the most views as an object using getLineage.
|
||||
my ($bestViews_listing) = @{ $self->getLineage(['descendants'], {
|
||||
includeOnlyClasses => ['WebGUI::Asset::MatrixListing'],
|
||||
|
|
@ -629,7 +631,7 @@ sub view {
|
|||
lastUpdated => $self->session->datetime->epochToHuman($lastUpdatedListing->get('lastUpdated'),"%z")
|
||||
});
|
||||
}
|
||||
$var->{lastUpdated_sortButton} = "<span id='sortByUpdated'><button type='button'>Sort by updated</button></span><br />";
|
||||
$varStatistics->{lastUpdated_sortButton} = "<span id='sortByUpdated'><button type='button'>Sort by updated</button></span><br />";
|
||||
|
||||
# For each category, get the MatrixListings with the best ratings.
|
||||
|
||||
|
|
@ -1302,7 +1304,7 @@ sub www_search {
|
|||
$options{'blank'} = 'blank';
|
||||
$attribute->{options} = \%options;
|
||||
$attribute->{value} = 'blank';
|
||||
$attribute->{extras} = "style='width:120px'";
|
||||
$attribute->{extras} .= " style='width:120px'";
|
||||
}
|
||||
$attribute->{form} = WebGUI::Form::DynamicField->new($self->session,%{$attribute})->toHtml;
|
||||
push(@attribute_loop,$attribute);
|
||||
|
|
|
|||
|
|
@ -84,6 +84,13 @@ sub definition {
|
|||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getEditForm ( )
|
||||
|
||||
Manually build the edit form due to javascript elements.
|
||||
|
||||
=cut
|
||||
|
||||
sub getEditForm {
|
||||
my $self = shift;
|
||||
my $tabform = $self->SUPER::getEditForm;
|
||||
|
|
@ -340,7 +347,7 @@ sub getToolbar {
|
|||
|
||||
=head2 prepareView ( )
|
||||
|
||||
See WebGUI::Asset::prepareView() for details.
|
||||
Extend the superclass to add metadata and to preprocess the template.
|
||||
|
||||
=cut
|
||||
|
||||
|
|
@ -354,6 +361,13 @@ sub prepareView {
|
|||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 view ( )
|
||||
|
||||
See WebGUI::Asset::view() for details.
|
||||
|
||||
=cut
|
||||
|
||||
sub view {
|
||||
my $self = shift;
|
||||
# we've got to determine what our start point is based upon user conditions
|
||||
|
|
@ -512,6 +526,13 @@ sub view {
|
|||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_goBackToPage ( )
|
||||
|
||||
Do a redirect to the form parameter returnUrl if it exists.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_goBackToPage {
|
||||
my $self = shift;
|
||||
$self->session->http->setRedirect($self->session->form->process("returnUrl")) if ($self->session->form->process("returnUrl"));
|
||||
|
|
|
|||
|
|
@ -220,6 +220,13 @@ sub definition {
|
|||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getEditForm ( )
|
||||
|
||||
Manually make the edit form due to javascript for adding more queries.
|
||||
|
||||
=cut
|
||||
|
||||
sub getEditForm {
|
||||
my $self = shift;
|
||||
my $tabform = $self->SUPER::getEditForm();
|
||||
|
|
@ -495,6 +502,14 @@ sub purgeCache {
|
|||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 view ( )
|
||||
|
||||
See WebGUI::Asset::view() for details. This method also performs content caching
|
||||
if the user is not in Admin Mode.
|
||||
|
||||
=cut
|
||||
|
||||
sub view {
|
||||
my $self = shift;
|
||||
if (!$self->session->var->isAdminOn && $self->get("cacheTimeout") > 10) {
|
||||
|
|
|
|||
|
|
@ -396,6 +396,7 @@ Loads the initial edit survey page. All other edit actions are ajax calls from t
|
|||
|
||||
sub www_editSurvey {
|
||||
my $self = shift;
|
||||
|
||||
return $self->session->privilege->insufficient()
|
||||
if !$self->session->user->isInGroup( $self->get('groupToEditSurvey') );
|
||||
|
||||
|
|
@ -676,7 +677,7 @@ sub www_dragDrop {
|
|||
#If target is being moved down, then before has just moved up do to the target being deleted
|
||||
$bid[0]-- if($tid[0] < $bid[0]);
|
||||
|
||||
$self->surveyJSON->insertObject( $target, [ $bid[0] ] );
|
||||
$address = $self->surveyJSON->insertObject( $target, [ $bid[0] ] );
|
||||
}
|
||||
elsif ( @tid == 2 ) { #questions can be moved to any section, but a pushed to the end of a new section.
|
||||
if ( $bid[0] !~ /\d/ ) {
|
||||
|
|
@ -700,21 +701,21 @@ sub www_dragDrop {
|
|||
else{ #Moved within the same section
|
||||
$bid[1]-- if($tid[1] < $bid[1]);
|
||||
}
|
||||
$self->surveyJSON->insertObject( $target, [ $bid[0], $bid[1] ] );
|
||||
$address = $self->surveyJSON->insertObject( $target, [ $bid[0], $bid[1] ] );
|
||||
} ## end elsif ( @tid == 2 )
|
||||
elsif ( @tid == 3 ) { #answers can only be rearranged in the same question
|
||||
if ( @bid == 2 and $bid[1] == $tid[1] ) {#moved to the top of the question
|
||||
$bid[2] = -1;
|
||||
$self->surveyJSON->insertObject( $target, [ $bid[0], $bid[1], $bid[2] ] );
|
||||
$address = $self->surveyJSON->insertObject( $target, [ $bid[0], $bid[1], $bid[2] ] );
|
||||
}
|
||||
elsif ( @bid == 3 ) {
|
||||
#If target is being moved down, then before has just moved up do to the target being deleted
|
||||
$bid[2]-- if($tid[2] < $bid[2]);
|
||||
$self->surveyJSON->insertObject( $target, [ $bid[0], $bid[1], $bid[2] ] );
|
||||
$address = $self->surveyJSON->insertObject( $target, [ $bid[0], $bid[1], $bid[2] ] );
|
||||
}
|
||||
else {
|
||||
#else put it back where it was
|
||||
$self->surveyJSON->insertObject( $target, \@tid );
|
||||
$address = $self->surveyJSON->insertObject( $target, \@tid );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -742,6 +743,7 @@ sub www_loadSurvey {
|
|||
my ( $self, $options ) = @_;
|
||||
my $editflag = 1;
|
||||
my $address = defined $options->{address} ? $options->{address} : undef;
|
||||
|
||||
if ( !defined $address ) {
|
||||
if ( my $inAddress = $self->session->form->process('data') ) {
|
||||
if ( $inAddress eq q{-} ) {
|
||||
|
|
@ -760,7 +762,7 @@ sub www_loadSurvey {
|
|||
= defined $options->{var}
|
||||
? $options->{var}
|
||||
: $self->surveyJSON->getEditVars($address);
|
||||
|
||||
|
||||
my $editHtml;
|
||||
if ( $var->{type} eq 'section' ) {
|
||||
$editHtml = $self->processTemplate( $var, $self->get('sectionEditTemplateId') );
|
||||
|
|
@ -903,7 +905,7 @@ returns the output.
|
|||
sub view {
|
||||
my $self = shift;
|
||||
my $var = $self->getMenuVars;
|
||||
|
||||
|
||||
my ( $code, $overTakeLimit ) = $self->getResponseInfoForView();
|
||||
|
||||
$var->{lastResponseCompleted} = $code;
|
||||
|
|
@ -1153,13 +1155,23 @@ sub www_submitQuestions {
|
|||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
sub getSummary{
|
||||
|
||||
=head2 getSummary
|
||||
|
||||
Returns a copy of the summary stored in JSON, and the output of
|
||||
the survey summary template.
|
||||
|
||||
=cut
|
||||
|
||||
sub getSummary {
|
||||
my $self = shift;
|
||||
my $summary = $self->responseJSON->showSummary();
|
||||
my $out = $self->processTemplate( $summary, $self->get('surveySummaryTemplateId') );
|
||||
return $out;
|
||||
|
||||
return ($summary,$out);
|
||||
# return $self->session->style->process( $out, $self->get('styleTemplateId') );
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_loadQuestions
|
||||
|
|
@ -1171,7 +1183,6 @@ Determines which questions to display to the survey taker next, loads and return
|
|||
sub www_loadQuestions {
|
||||
my $self = shift;
|
||||
my $wasRestarted = shift;
|
||||
|
||||
if ( !$self->canTakeSurvey() ) {
|
||||
$self->session->log->debug('canTakeSurvey false, surveyEnd');
|
||||
return $self->surveyEnd();
|
||||
|
|
@ -1191,7 +1202,8 @@ sub www_loadQuestions {
|
|||
$self->session->log->debug('Response surveyEnd, so calling surveyEnd');
|
||||
if ( $self->get('quizModeSummary') ) {
|
||||
if(! $self->session->form->param('shownsummary')){
|
||||
my $json = to_json( { type => 'summary', summary => $self->getSummary() });
|
||||
my ($summary,$html) = $self->getSummary();
|
||||
my $json = to_json( { type => 'summary', summary => $summary, html => $html });
|
||||
return $json;
|
||||
}
|
||||
}
|
||||
|
|
@ -1750,7 +1762,7 @@ sub www_viewStatisticalOverview {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_exportTransposedResults ()
|
||||
=head2 www_exportSimpleResults ()
|
||||
|
||||
Exports transposed results in a tab deliniated file.
|
||||
|
||||
|
|
@ -1908,4 +1920,21 @@ sub www_editDefaultQuestions{
|
|||
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_downloadDefaulQuestions
|
||||
|
||||
Sends the user a json file of the default question types, which can be imported to other WebGUI instances.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_downloadDefaultQuestionTypes{
|
||||
my $self = shift;
|
||||
return $self->session->privilege->insufficient()
|
||||
if !$self->session->user->isInGroup( $self->get('groupToViewReports') );
|
||||
my $content = to_json($self->surveyJSON->{multipleChoiceTypes});
|
||||
return $self->export( "WebGUI-Survey-DefaultQuestionTypes.json", $content );
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@ Package WebGUI::Asset::Wobject::Survey::ExpressionEngine
|
|||
|
||||
This class is used to process Survey gotoExpressions.
|
||||
|
||||
If you want to allow the expression engine to run you need to turn on the enableSurveyExpressionEngine flag
|
||||
in your site config file. This is because no matter how 'Safe' the Safe.pm compartment is, it still has
|
||||
caveats. For example, it doesn't protect you from infinite loops.
|
||||
|
||||
See L<run> for more details.
|
||||
|
||||
=cut
|
||||
|
|
@ -17,6 +21,7 @@ use Params::Validate qw(:all);
|
|||
use Safe;
|
||||
use Data::Dumper;
|
||||
use List::Util qw/sum/;
|
||||
use WebGUI::Asset;
|
||||
Params::Validate::validation_options( on_fail => sub { WebGUI::Error::InvalidParam->throw( error => shift ) } );
|
||||
|
||||
# We need these as semi-globals so that utility subs (which are shared with the safe compartment)
|
||||
|
|
@ -27,20 +32,39 @@ my $scores;
|
|||
my $jump_count;
|
||||
my $validate;
|
||||
my $validTargets;
|
||||
|
||||
my $other_instances;
|
||||
|
||||
=head2 value
|
||||
|
||||
Utility sub that gives expressions access to recorded response values
|
||||
|
||||
value(question_variable) returns the recorded response value for the answer to question_variable
|
||||
|
||||
value(asset_spec, question_variable) returns value(question_variable) on the most recent completed response
|
||||
for the user on the survey instance given by asset_spec (either an assetId or a url)
|
||||
|
||||
=cut
|
||||
|
||||
sub value($) {
|
||||
sub value {
|
||||
# Two arguments implies the first arg is an asset_spec
|
||||
if ( @_ == 2 ) {
|
||||
my ( $asset_spec, $key ) = @_;
|
||||
|
||||
# See if $other_instances already contains the external survey
|
||||
if (my $other_instance = $other_instances->{$asset_spec}) {
|
||||
my $values = $other_instance->{values};
|
||||
my $value = $values->{$key};
|
||||
$session->log->debug("[$asset_spec, $key] resolves to [$value]");
|
||||
return $value;
|
||||
} else {
|
||||
# Throw an exception, triggering run() to resolve the external reference and re-run
|
||||
die( { other_instance => $asset_spec } );
|
||||
}
|
||||
}
|
||||
my $key = shift;
|
||||
my $value = $values->{$key};
|
||||
$session->log->debug("[$key] resolves to [$value]");
|
||||
return $value; # scalar variable, so no need to clone
|
||||
return $value; # scalar variable, so no need to clone
|
||||
}
|
||||
|
||||
=head2 score
|
||||
|
|
@ -52,11 +76,26 @@ score(section_variable) returns the summed score for the answers to all the ques
|
|||
|
||||
=cut
|
||||
|
||||
sub score($) {
|
||||
sub score {
|
||||
# Two arguments implies the first arg is an asset_spec
|
||||
if ( @_ == 2 ) {
|
||||
my ( $asset_spec, $key ) = @_;
|
||||
|
||||
# See if $other_instances already contains the external survey
|
||||
if (my $other_instance = $other_instances->{$asset_spec}) {
|
||||
my $scores = $other_instance->{scores};
|
||||
my $score = $scores->{$key};
|
||||
$session->log->debug("[$asset_spec, $key] resolves to [$score]");
|
||||
return $score;
|
||||
} else {
|
||||
# Throw an exception, triggering run() to resolve the external reference and re-run
|
||||
die( { other_instance => $asset_spec } );
|
||||
}
|
||||
}
|
||||
my $key = shift;
|
||||
my $score = $scores->{$key};
|
||||
$session->log->debug("[$key] resolves to [$score]");
|
||||
return $score; # scalar variable, so no need to clone
|
||||
return $score; # scalar variable, so no need to clone
|
||||
}
|
||||
|
||||
=head2 jump
|
||||
|
|
@ -71,17 +110,18 @@ catch the first successful jump.
|
|||
sub jump(&$) {
|
||||
my ( $sub, $target ) = @_;
|
||||
$jump_count++;
|
||||
|
||||
|
||||
# If $validTargets known, make sure target is valid
|
||||
if ($validTargets && !exists $validTargets->{$target}) {
|
||||
if ( $validTargets && !exists $validTargets->{$target} ) {
|
||||
$session->log->debug("Invalid target [$target]");
|
||||
if ($validate) {
|
||||
die("Invalid jump target \"$target\""); # bail and report error
|
||||
} else {
|
||||
return; # skip jump but continue with expression
|
||||
die("Invalid jump target \"$target\""); # bail and report error
|
||||
}
|
||||
else {
|
||||
return; # skip jump but continue with expression
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( $sub->() ) {
|
||||
$session->log->debug("jump call #$jump_count is truthy");
|
||||
die( { jump => $target } );
|
||||
|
|
@ -120,8 +160,12 @@ A gotoExpression is essentially a perl expression that gets evaluated in a Safe
|
|||
|
||||
To access Section/Question recorded response values, the expression calls L<value>.
|
||||
To access Section/Question recorded response scores, the expression calls L<score>.
|
||||
Both L<value> and L<score> allow you to resolve values and scores from other completed survey
|
||||
instances.
|
||||
|
||||
To trigger a jump, the expression calls L<jump>. The first truthy jump succeeds.
|
||||
We also give expressions access to some useful utility subs such as avg(), and all of the
|
||||
|
||||
Expressions also have access to some useful utility subs such as avg(), and all of the
|
||||
handy subs from List::Util (min, max, sum, etc..).
|
||||
|
||||
A very simple expression that checks if the response to s1q1 is 0 might look like:
|
||||
|
|
@ -131,7 +175,7 @@ A very simple expression that checks if the response to s1q1 is 0 might look lik
|
|||
A more complicated gotoExpression with two possible jumps might look like:
|
||||
|
||||
jump { value(q1) > 5 and value(s2q1) =~ m/textmatch/ } target1;
|
||||
jump { avg(value(q1), value(q2), value(q3)) > 10 } target2;
|
||||
jump { avg(value(q1), value(q2), value(home/anotherSurvey, q3)) > 10 } target2;
|
||||
|
||||
=head3 opts (optional)
|
||||
|
||||
|
|
@ -147,7 +191,7 @@ Hashref of values to make available to the expression via the L<value> utility s
|
|||
|
||||
Hashref of scores to make available to the expression via the L<score> utility sub
|
||||
|
||||
=item* validTargets
|
||||
=item * validTargets
|
||||
|
||||
A hashref of valid jump targets. If this is provided, all L<jump> calls will fail unless
|
||||
the specified target is a key in the hashref.
|
||||
|
|
@ -166,52 +210,113 @@ sub run {
|
|||
= validate_pos( @_, { isa => 'WebGUI::Session' }, { type => SCALAR }, { type => HASHREF, default => {} } );
|
||||
|
||||
# Init package globals
|
||||
( $session, $values, $scores, $jump_count, $validate, $validTargets ) = ( $s, $opts->{values}, $opts->{scores}, 0, $opts->{validate}, $opts->{validTargets} );
|
||||
|
||||
if (!$session->config->get('enableSurveyExpressionEngine')) {
|
||||
( $session, $values, $scores, $jump_count, $validate, $validTargets )
|
||||
= ( $s, $opts->{values}, $opts->{scores}, 0, $opts->{validate}, $opts->{validTargets} );
|
||||
|
||||
if ( !$session->config->get('enableSurveyExpressionEngine') ) {
|
||||
$session->log->debug('enableSurveyExpressionEngine config option disabled, skipping');
|
||||
return;
|
||||
}
|
||||
|
||||
# Create the Safe compartment
|
||||
my $compartment = Safe->new();
|
||||
REVAL: {
|
||||
|
||||
# Share our utility subs with the compartment
|
||||
$compartment->share('&value');
|
||||
$compartment->share('&score');
|
||||
$compartment->share('&jump');
|
||||
$compartment->share('&avg');
|
||||
|
||||
# Give them all of List::Util too
|
||||
$compartment->share_from('List::Util', ['&first', '&max', '&maxstr', '&min', '&minstr', '&reduce', '&shuffle', '&sum',]);
|
||||
# Create the Safe compartment
|
||||
my $compartment = Safe->new();
|
||||
|
||||
$session->log->debug("Expression is: \"$expression\"");
|
||||
$compartment->reval($expression);
|
||||
|
||||
# See if we ran the engine just to check for errors
|
||||
if ($opts->{validate}) {
|
||||
if ($@ && ref $@ ne 'HASH') {
|
||||
my $error = $@;
|
||||
$error =~ s/(.*?) at .*/$1/s; # don't reveal too much
|
||||
return $error;
|
||||
# Share our utility subs with the compartment
|
||||
$compartment->share('&value');
|
||||
$compartment->share('&score');
|
||||
$compartment->share('&jump');
|
||||
$compartment->share('&avg');
|
||||
|
||||
# Give them all of List::Util too
|
||||
$compartment->share_from( 'List::Util',
|
||||
[ '&first', '&max', '&maxstr', '&min', '&minstr', '&reduce', '&shuffle', '&sum', ] );
|
||||
|
||||
$session->log->debug("Expression is: \"$expression\"");
|
||||
|
||||
$compartment->reval($expression);
|
||||
|
||||
# See if we ran the engine just to check for errors
|
||||
if ( $opts->{validate} ) {
|
||||
if ( $@ && ref $@ ne 'HASH' ) {
|
||||
my $error = $@;
|
||||
$error =~ s/(.*?) at .*/$1/s; # don't reveal too much
|
||||
return $error;
|
||||
}
|
||||
return; # no validation errors
|
||||
}
|
||||
return; # no validation errors
|
||||
}
|
||||
|
||||
# A successful jump triggers a hashref containing the jump target to be thrown
|
||||
if ( ref $@ && ref $@ eq 'HASH' && $@->{jump} ) {
|
||||
my $jump = $@->{jump};
|
||||
$session->log->debug("Returning [$jump]");
|
||||
return $jump;
|
||||
}
|
||||
# A successful jump triggers a hashref containing the jump target to be thrown
|
||||
if ( ref $@ && ref $@ eq 'HASH' && $@->{jump} ) {
|
||||
my $jump = $@->{jump};
|
||||
$session->log->debug("Returning [$jump]");
|
||||
return $jump;
|
||||
}
|
||||
|
||||
# Log all other errors (for example compile errors from bad expressions)
|
||||
if ($@) {
|
||||
$session->log->error($@);
|
||||
}
|
||||
# See if an unresolved external reference was encountered
|
||||
if ( ref $@ && ref $@ eq 'HASH' && $@->{other_instance} ) {
|
||||
my $asset_spec = $@->{other_instance};
|
||||
$session->log->debug("Resolving external reference: $asset_spec");
|
||||
my $asset;
|
||||
|
||||
# Return undef on failure
|
||||
return;
|
||||
# Instantiate the asset to check it is a Survey instance, and to grab its assetId
|
||||
if ( $session->id->valid($asset_spec) ) {
|
||||
$asset = WebGUI::Asset->new( $session, $asset_spec );
|
||||
}
|
||||
if ( !$asset ) {
|
||||
$asset = WebGUI::Asset->newByUrl( $session, $asset_spec );
|
||||
}
|
||||
if ( ref $asset ne 'WebGUI::Asset::Wobject::Survey' ) {
|
||||
$session->log->warn("Not a survey instance: $asset_spec");
|
||||
return;
|
||||
}
|
||||
if ( !$asset ) {
|
||||
$session->log->warn("Unable to find asset: $asset_spec");
|
||||
return;
|
||||
}
|
||||
my $assetId = $asset->getId;
|
||||
|
||||
# Get the responseId of the most recently completed survey response for the user
|
||||
my $userId = $opts->{userId} || $session->user->userId;
|
||||
my $mostRecentlyCompletedResponseId = $session->db->quickScalar(
|
||||
"select Survey_responseId from Survey_response where userId = ? and assetId = ? and isComplete = 1",
|
||||
[ $userId, $assetId ]
|
||||
);
|
||||
|
||||
if ( !$mostRecentlyCompletedResponseId ) {
|
||||
$session->log->debug("User $userId has not completed Survey");
|
||||
return;
|
||||
}
|
||||
$session->log->debug("Using responseId: $mostRecentlyCompletedResponseId");
|
||||
|
||||
# (re)Instantiate the survey instance using the responseId
|
||||
use WebGUI::Asset::Wobject::Survey;
|
||||
$asset = WebGUI::Asset::Wobject::Survey->newByResponseId( $session, $mostRecentlyCompletedResponseId );
|
||||
$asset->responseIdCookies(0);
|
||||
if ( !$asset ) {
|
||||
$session->log->warn("Unable to instantiate asset by responseId: $mostRecentlyCompletedResponseId");
|
||||
return;
|
||||
}
|
||||
|
||||
$other_instances->{$asset_spec} = {
|
||||
values =>
|
||||
$asset->responseJSON( undef, $mostRecentlyCompletedResponseId )->responseValuesByVariableName,
|
||||
scores =>
|
||||
$asset->responseJSON( undef, $mostRecentlyCompletedResponseId )->responseScoresByVariableName,
|
||||
};
|
||||
$session->log->debug("Successfully looked up asset: $assetId. Repeating reval.");
|
||||
redo REVAL;
|
||||
}
|
||||
|
||||
# Log all other errors (for example compile errors from bad expressions)
|
||||
if ($@) {
|
||||
$session->log->error($@);
|
||||
}
|
||||
|
||||
# Return undef on failure
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ Answers entries contain: value (the recorded value), time and comment fields.
|
|||
{
|
||||
...
|
||||
answerId => {
|
||||
value => "answer value",
|
||||
value => "recorded answer value",
|
||||
time => time(),
|
||||
comment => "answer comment",
|
||||
},
|
||||
|
|
@ -738,12 +738,18 @@ sub responseValuesByVariableName {
|
|||
|
||||
# Grab the corresponding question
|
||||
my $question = $self->survey->question([@address]);
|
||||
|
||||
|
||||
# Filter out questions without defined variable names
|
||||
next if !$question || !defined $question->{variable};
|
||||
|
||||
#Test if question is a multiple choice type so we can use the answer text instead
|
||||
my $answerText;
|
||||
if($self->survey->getMultiChoiceBundle($question->{questionType})){
|
||||
$answerText = $self->survey->answer([@address])->{text};
|
||||
}
|
||||
|
||||
# Add variable => value to our hash
|
||||
$lookup{$question->{variable}} = $response->{value};
|
||||
$lookup{$question->{variable}} = $answerText ? $answerText : $response->{value};
|
||||
}
|
||||
return \%lookup;
|
||||
}
|
||||
|
|
@ -781,8 +787,11 @@ sub responseScoresByVariableName {
|
|||
# Grab the corresponding answer
|
||||
my $answer = $self->survey->answer([@address]);
|
||||
|
||||
# Use question score if answer score undefined
|
||||
my $score = (exists $answer->{value} && length $answer->{value} > 0) ? $answer->{value} : $question->{value};
|
||||
|
||||
# Add variable => score to our hash
|
||||
$lookup{$question->{variable}} = $answer->{value};
|
||||
$lookup{$question->{variable}} = $score;
|
||||
}
|
||||
|
||||
# Add section score totals
|
||||
|
|
@ -1074,9 +1083,8 @@ sub showSummary{
|
|||
|
||||
return if(! $responses);
|
||||
|
||||
my ($sectionIndex, $questionIndex, $answerIndex) = (-1, -1, -1);
|
||||
my ($currentSection,$currentQuestion) = (-1, -1);
|
||||
|
||||
my ($sectionIndex, $responseIndex) = (-1, 1);
|
||||
my ($currentSection,$currentQuestion) = (-1,-1);
|
||||
($summaries->{totalCorrect},$summaries->{totalIncorrect}) = (0,0);
|
||||
|
||||
for my $response (@$responses){
|
||||
|
|
@ -1090,62 +1098,54 @@ sub showSummary{
|
|||
if($currentSection != $response->{address}->[0]){
|
||||
$summaries->{totalSections}++;
|
||||
$sectionIndex++;
|
||||
$questionIndex = -1;
|
||||
$answerIndex = -1;
|
||||
$currentQuestion = -1;
|
||||
$responseIndex = -1;
|
||||
$currentSection = $response->{address}->[0];
|
||||
_loadSectionIntoSummary(\%{$summaries->{sections}->[$sectionIndex]},$response);
|
||||
}
|
||||
if($currentQuestion != $response->{address}->[1]){
|
||||
$summaries->{totalQuestions}++;
|
||||
$questionIndex++;
|
||||
$answerIndex = -1;
|
||||
$currentQuestion = $response->{address}->[1];
|
||||
_loadQuestionIntoSummary(\%{$summaries->{sections}->[$sectionIndex]->{questions}->[$questionIndex]},$response);
|
||||
}
|
||||
$answerIndex++;
|
||||
_loadAnswerIntoSummary(\%{$summaries->{sections}->[$sectionIndex]->{questions}->[$questionIndex]->{answers}->[$answerIndex]},
|
||||
_loadSectionIntoSummary(\%{$summaries->{sections}->[$sectionIndex]}, $response);
|
||||
$responseIndex++;
|
||||
_loadResponseIntoSummary(\%{$summaries->{sections}->[$sectionIndex]->{responses}->[$responseIndex]},
|
||||
$response,
|
||||
$self->survey->{multipleChoiceTypes});
|
||||
}
|
||||
return $summaries;
|
||||
}
|
||||
sub _loadAnswerIntoSummary{
|
||||
sub _loadResponseIntoSummary{
|
||||
my $node = shift;
|
||||
my $response = shift;
|
||||
my $types = shift;
|
||||
|
||||
$node->{id} = $response->{address}->[2] + 1;
|
||||
$node->{"Question ID"} = $response->{address}->[1] + 1;
|
||||
$node->{"Question Text"} = $response->{questionText};
|
||||
$node->{"Answer ID"} = $response->{address}->[2] + 1;
|
||||
if($response->{isCorrect}){
|
||||
$node->{iscorrect} = 1;
|
||||
$node->{score} = $response->{value};
|
||||
$node->{Correct} = "Y";
|
||||
$node->{Score} = $response->{value};
|
||||
}else{
|
||||
$node->{iscorrect} = 0;
|
||||
$node->{score} = 0;
|
||||
$node->{Correct} = "N";
|
||||
$node->{Score} = 0;
|
||||
}
|
||||
$node->{text} = $response->{answerText};
|
||||
$node->{"Answer Text"} = $response->{answerText};
|
||||
|
||||
#test if it is a multiple choide type
|
||||
if($types->{$response->{questionType}}){
|
||||
$node->{value} = $response->{value};
|
||||
$node->{Value} = $response->{value};
|
||||
}else{
|
||||
$node->{value} = $response->{recordedValue};
|
||||
$node->{Value} = $response->{recordedValue};
|
||||
}
|
||||
}
|
||||
sub _loadQuestionIntoSummary{
|
||||
my $node = shift;
|
||||
my $response = shift;
|
||||
$node->{id} = $response->{address}->[1] + 1;
|
||||
$node->{text} = $response->{questionText};
|
||||
}
|
||||
sub _loadSectionIntoSummary{
|
||||
my $node = shift;
|
||||
my $response = shift;
|
||||
$node->{id} = $response->{address}->[0] + 1;
|
||||
$node->{inCorrect} = 0 if(!defined $node->{section}->{inCorrect});
|
||||
$node->{score} = 0 if(!defined $node->{section}->{score});
|
||||
$node->{correct} = 0 if(!defined $node->{section}->{correct});
|
||||
if($response->{isCorrect}){
|
||||
$node->{inCorrect} = 0 if(!defined $node->{inCorrect});
|
||||
$node->{score} = 0 if(!defined $node->{score});
|
||||
$node->{correct} = 0 if(!defined $node->{correct});
|
||||
$node->{total} = 0 if(!defined $node->{total});
|
||||
$node->{total}++;
|
||||
if($response->{isCorrect} == 1){
|
||||
$node->{score} += $response->{value};
|
||||
$node->{correct}++;
|
||||
}else{
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ Loads the Multiple Choice and Special Question types
|
|||
|
||||
sub loadTypes {
|
||||
my $self = shift;
|
||||
|
||||
@{$self->{specialQuestionTypes}} = (
|
||||
'Dual Slider - Range',
|
||||
'Multi Slider - Allocate',
|
||||
|
|
@ -125,9 +126,11 @@ sub loadTypes {
|
|||
'Date Range',
|
||||
'Year Month',
|
||||
'Hidden',
|
||||
);
|
||||
my $refs = $self->session->db->buildArrayRefOfHashRefs("SELECT questionType, answers FROM Survey_questionTypes");
|
||||
map($self->{multipleChoiceTypes}->{$_->{questionType}} = [split/,/,$_->{answers}], @$refs);
|
||||
) if(! defined $self->{specialQuestionTypes});
|
||||
if(! defined $self->{multipleChoiceTypes}){
|
||||
my $refs = $self->session->db->buildArrayRefOfHashRefs("SELECT questionType, answers FROM Survey_questionTypes");
|
||||
map($self->{multipleChoiceTypes}->{$_->{questionType}} = $_->{answers} ? from_json($_->{answers}) : {}, @$refs);
|
||||
}
|
||||
}
|
||||
|
||||
sub addType {
|
||||
|
|
@ -135,11 +138,7 @@ sub addType {
|
|||
my $name = shift;
|
||||
my $address = shift;
|
||||
my $obj = $self->getObject($address);
|
||||
my @answers;
|
||||
for my $ans(@{$obj->{answers}}){
|
||||
push(@answers,$ans->{text});
|
||||
}
|
||||
my $ansString = join(',',@answers);
|
||||
my $ansString = $obj->{answers} ? to_json $obj->{answers} : {};
|
||||
$self->session->db->write("INSERT INTO Survey_questionTypes VALUES(?,?) ON DUPLICATE KEY UPDATE answers = ?",[$name,$ansString,$ansString]);
|
||||
$self->question($address)->{questionType} = $name;
|
||||
}
|
||||
|
|
@ -391,7 +390,6 @@ sections, questions, or answers.
|
|||
sub getEditVars {
|
||||
my $self = shift;
|
||||
my ($address) = validate_pos(@_, { type => ARRAYREF });
|
||||
|
||||
# Figure out what to do by counting the number of elements in the $address array ref
|
||||
my $count = @{$address};
|
||||
|
||||
|
|
@ -727,15 +725,18 @@ sub insertObject {
|
|||
# Use splice to rearrange the relevant array of objects..
|
||||
if ( $count == 1 ) {
|
||||
splice @{ $self->sections($address) }, sIndex($address) +1, 0, $object;
|
||||
$address->[0]++;
|
||||
}
|
||||
elsif ( $count == 2 ) {
|
||||
splice @{ $self->questions($address) }, qIndex($address) + 1, 0, $object;
|
||||
$address->[1]++;
|
||||
}
|
||||
elsif ( $count == 3 ) {
|
||||
splice @{ $self->answers($address) }, aIndex($address) + 1, 0, $object;
|
||||
$address->[2]++;
|
||||
}
|
||||
|
||||
return;
|
||||
return $address;
|
||||
}
|
||||
|
||||
=head2 copy ( $address )
|
||||
|
|
@ -988,16 +989,8 @@ sub updateQuestionAnswers {
|
|||
}
|
||||
elsif ( my $answerBundle = $self->getMultiChoiceBundle($type) ) {
|
||||
# We found a known multi-choice bundle.
|
||||
|
||||
# Mark any answer containing the string "verbatim" as verbatim
|
||||
my $verbatims = {};
|
||||
for my $answerIndex (0 .. $#$answerBundle) {
|
||||
if ($answerBundle->[$answerIndex] =~ /\(verbatim\)/) {
|
||||
$verbatims->{$answerIndex} = 1;
|
||||
}
|
||||
}
|
||||
# Add the bundle of multi-choice answers, along with the verbatims hash
|
||||
$self->addAnswersToQuestion( \@address_copy, $answerBundle, $verbatims );
|
||||
# Add the bundle of multi-choice answers
|
||||
$self->addAnswersToQuestion( \@address_copy, $answerBundle );
|
||||
} else {
|
||||
# Default action is to add a single, default answer to the question
|
||||
push @{ $question->{answers} }, $self->newAnswer();
|
||||
|
|
@ -1008,9 +1001,7 @@ sub updateQuestionAnswers {
|
|||
|
||||
=head2 getMultiChoiceBundle
|
||||
|
||||
Returns a list of answers for each multi-choice bundle.
|
||||
|
||||
Currently these are hard-coded but soon they will live in the database.
|
||||
Returns a list of answer objects for each multi-choice bundle.
|
||||
|
||||
=cut
|
||||
|
||||
|
|
@ -1021,7 +1012,7 @@ sub getMultiChoiceBundle {
|
|||
return $self->{multipleChoiceTypes}->{$type};
|
||||
}
|
||||
|
||||
=head2 addAnswersToQuestion ($address, $answers, $verbatims)
|
||||
=head2 addAnswersToQuestion ($address, $answers)
|
||||
|
||||
Helper routine for updateQuestionAnswers. Adds an array of answers to a question.
|
||||
|
||||
|
|
@ -1034,39 +1025,21 @@ See L<"Address Parameter">. The address of the question to add answers to.
|
|||
An array reference of answers to add. Each element will be assigned to the text field of
|
||||
the answer that is created.
|
||||
|
||||
=head3 $verbatims
|
||||
|
||||
An hash reference. Each key is an index into the answers array. The value is a placeholder
|
||||
for doing existance lookups. For each requested index, the verbatim flag in the answer is
|
||||
set to true.
|
||||
|
||||
=cut
|
||||
|
||||
sub addAnswersToQuestion {
|
||||
my $self = shift;
|
||||
my ( $address, $answers, $verbatims )
|
||||
= validate_pos( @_, { type => ARRAYREF }, { type => ARRAYREF }, { type => HASHREF } );
|
||||
my ( $address, $answers )
|
||||
= validate_pos( @_, { type => ARRAYREF }, { type => ARRAYREF } );
|
||||
|
||||
# Make a private copy of the $address arrayref that we can use locally
|
||||
# when updating answer text without causing side-effects for the caller's $address
|
||||
my @address_copy = @{$address};
|
||||
|
||||
|
||||
for my $answer_index ( 0 .. $#{$answers} ) {
|
||||
|
||||
|
||||
# Add a new answer to question
|
||||
push @{ $self->question( \@address_copy )->{answers} }, $self->newAnswer();
|
||||
|
||||
# Update address to point at newly created answer (so that we can update it)
|
||||
$address_copy[2] = $answer_index;
|
||||
|
||||
# Update the answer appropriately
|
||||
$self->update(
|
||||
\@address_copy,
|
||||
{ text => $answers->[$answer_index],
|
||||
recordedAnswer => $answer_index + 1, # 1-indexed
|
||||
verbatim => $verbatims->{$answer_index},
|
||||
}
|
||||
);
|
||||
push @{ $self->question( \@address_copy )->{answers} }, $answers->[$answer_index];
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
@ -1200,15 +1173,12 @@ Returns an array of messages to inform a user what is logically wrong with the S
|
|||
|
||||
sub validateSurvey{
|
||||
my $self = shift;
|
||||
#check all goto's
|
||||
#bad goto expressions
|
||||
#check that all survey is able to be seen
|
||||
|
||||
my @messages;
|
||||
|
||||
#set up valid goto targets
|
||||
my $gotoTargets = $self->getGotoTargets();
|
||||
my $goodTargets;
|
||||
my $goodTargets = {};
|
||||
my $duplicateTargets;
|
||||
for my $g (@{$gotoTargets}) {
|
||||
$goodTargets->{$g}++;
|
||||
|
|
@ -1302,7 +1272,11 @@ sub validateGotoExpression{
|
|||
my $self = shift;
|
||||
my $object = shift;
|
||||
my $goodTargets = shift;
|
||||
return unless $object->{gotoExpression};
|
||||
return unless $object->{gotoExpression};
|
||||
|
||||
if (!$self->session->config->get('enableSurveyExpressionEngine')) {
|
||||
return 'enableSurveyExpressionEngine is disabled in your site config!';
|
||||
}
|
||||
|
||||
use WebGUI::Asset::Wobject::Survey::ExpressionEngine;
|
||||
my $engine = "WebGUI::Asset::Wobject::Survey::ExpressionEngine";
|
||||
|
|
|
|||
|
|
@ -403,20 +403,6 @@ sub www_viewRSS10 {
|
|||
return $self->www_viewRdf;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_viewRSS ( )
|
||||
|
||||
Deprecated. Use www_viewRss() instead.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_viewRSS {
|
||||
my $self = shift;
|
||||
return $self->www_viewRss;
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_viewRSS20 ( )
|
||||
|
|
|
|||
|
|
@ -3152,6 +3152,9 @@ sub getSearchTemplateVars {
|
|||
|
||||
$currentUrl = $self->getUrl();
|
||||
foreach ($self->session->form->param) {
|
||||
# if we just saved data from an edit, we do not want to keep any of the params
|
||||
last if $_ eq 'func' and $self->session->form->process($_) eq 'editThingDataSave';
|
||||
|
||||
unless ($_ eq "pn" || $_ eq "op" || $_ =~ /identifier/xi || $_ =~ /password/xi || $_ eq "orderBy" ||
|
||||
$self->session->form->process($_) eq "") {
|
||||
$currentUrl = $self->session->url->append($currentUrl,$self->session->url->escape($_)
|
||||
|
|
@ -3260,10 +3263,16 @@ sequenceNumber');
|
|||
$templateVars{canEditThingData} = 1;
|
||||
$templateVars{searchResult_delete_icon} = $session->icon->delete('func=deleteThingDataConfirm;thingId='
|
||||
.$thingId.';thingDataId='.$thingDataId,$self->get("url"),$i18n->get('delete thing data warning'));
|
||||
$templateVars{searchResult_delete_url} = $session->url->append($url,
|
||||
'func=deleteThingDataConfirm;thingId='.$thingId.';thingDataId='.$thingDataId);
|
||||
$templateVars{searchResult_edit_icon} = $session->icon->edit('func=editThingData;thingId='
|
||||
.$thingId.';thingDataId='.$thingDataId,$self->get("url"));
|
||||
$templateVars{searchResult_edit_url} = $session->url->append($url,
|
||||
'func=editThingData;thingId='.$thingId.';thingDataId='.$thingDataId);
|
||||
$templateVars{searchResult_copy_icon} = $session->icon->copy('func=copyThingData;thingId='
|
||||
.$thingId.';thingDataId='.$thingDataId,$self->get("url"));
|
||||
$templateVars{searchResult_copy_url} = $session->url->append($url,
|
||||
'func=copyThingData;thingId='.$thingId.';thingDataId='.$thingDataId,);
|
||||
}
|
||||
push(@searchResult_loop,\%templateVars);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -252,12 +252,35 @@ sub exportAssetCollateral {
|
|||
|
||||
=head2 getRssFeedItems ()
|
||||
|
||||
This method should throw an exception if it's not overridden. Its intention is
|
||||
to be overridden by whatever class is using it and should return an array
|
||||
reference of hash references. Each hash reference should contain at minimum a title,
|
||||
description, link, and date field. The date field can be either an epoch date, an RFC 1123
|
||||
date, or a ISO date in the format of YYYY-MM-DD HH:MM::SS. Optionally specify an
|
||||
author, and a guid field.
|
||||
This method needs to be overridden by any class that is using it. To ensure
|
||||
this, it will throw an exception.
|
||||
|
||||
It returns an array reference of hash references. The list below shows
|
||||
which ones are required, along with some common keys which are optional.
|
||||
Other keys may be added, as well.
|
||||
|
||||
=head3 Hash reference keys
|
||||
|
||||
=head4 title
|
||||
|
||||
=head4 description
|
||||
|
||||
=head4 link
|
||||
|
||||
This is a url to the item.
|
||||
|
||||
=head4 date
|
||||
|
||||
An epoch date, an RFC 1123 date, or a date in ISO format (referred to as MySQL format
|
||||
inside WebGUI)
|
||||
|
||||
=head4 author
|
||||
|
||||
This is optional.
|
||||
|
||||
=head4 guid
|
||||
|
||||
This is optional. A unique descriptor for this item.
|
||||
|
||||
=cut
|
||||
|
||||
|
|
@ -405,12 +428,29 @@ sub getFeed {
|
|||
return $feed;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 prepareView ()
|
||||
|
||||
Extend the master class to insert head links via addHeaderLinks.
|
||||
|
||||
=cut
|
||||
|
||||
sub prepareView {
|
||||
my $self = shift;
|
||||
$self->addHeaderLinks;
|
||||
return $self->next::method(@_);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 addHeaderLinks ()
|
||||
|
||||
Add RSS, Atom, or RDF links in the HEAD block of the Asset, depending
|
||||
on how the Asset has configured feedHeaderLinks.
|
||||
|
||||
=cut
|
||||
|
||||
sub addHeaderLinks {
|
||||
my $self = shift;
|
||||
my $style = $self->session->style;
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ sub toHtml {
|
|||
|| !$self->get("value")
|
||||
|| $self->get("value") =~ m/^\d+$/) {
|
||||
# Epoch format
|
||||
$value = $self->set("value",$self->session->datetime->epochToSet($self->getOriginalValue));
|
||||
$value = $self->session->datetime->epochToSet($self->getOriginalValue);
|
||||
}
|
||||
else {
|
||||
# MySQL format
|
||||
|
|
|
|||
|
|
@ -132,6 +132,14 @@ sub getValue {
|
|||
return WebGUI::HTML::cleanSegment($self->SUPER::getValue(@_));
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getValueAsHtml ( )
|
||||
|
||||
Calls getValueAsHtml from WebGUI::Form::Control
|
||||
|
||||
=cut
|
||||
|
||||
sub getValueAsHtml {
|
||||
my $self = shift;
|
||||
return $self->WebGUI::Form::Control::getValueAsHtml(@_);
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ sub dateCreated {
|
|||
|
||||
=head2 delete ( )
|
||||
|
||||
Deletes this group and all references to it.
|
||||
Deletes this group from the group related tables in the database and calls clearCaches.
|
||||
|
||||
=cut
|
||||
|
||||
|
|
|
|||
|
|
@ -221,7 +221,11 @@ our $HELP = {
|
|||
{ 'name' => 'searchResult_id' },
|
||||
{ 'name' => 'searchResult_view_url' },
|
||||
{ 'name' => 'searchResult_edit_icon' },
|
||||
{ 'name' => 'searchResult_edit_url' },
|
||||
{ 'name' => 'searchResult_delete_icon' },
|
||||
{ 'name' => 'searchResult_delete_url' },
|
||||
{ 'name' => 'searchResult_copy_icon' },
|
||||
{ 'name' => 'searchResult_copy_url' },
|
||||
{ 'name' => 'searchResult_field_loop',
|
||||
'variables' => [
|
||||
{ 'name' => 'field_id' },
|
||||
|
|
|
|||
|
|
@ -503,9 +503,11 @@ Disconnects from the database. And destroys the object.
|
|||
=cut
|
||||
|
||||
sub disconnect {
|
||||
my $self = shift;
|
||||
$self->dbh->disconnect;
|
||||
undef $self;
|
||||
my $self = shift;
|
||||
my $dbh = delete $self->{_dbh};
|
||||
if ($dbh) {
|
||||
$dbh->disconnect;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -807,6 +807,17 @@ selectBox.</p>|
|
|||
message => q|Matrix Fieldtype|,
|
||||
},
|
||||
|
||||
'too many message' => {
|
||||
lastUpdated => 0,
|
||||
message => q|You tried to compare more than your maximum number of listings.|,
|
||||
context => q|A message shown to the user when they have selected too many listings to compare.|,
|
||||
},
|
||||
|
||||
'too few message' => {
|
||||
lastUpdated => 0,
|
||||
message => q|You tried to compare only one listing. If you want to view just one listing, click on its name.|,
|
||||
context => q|A message shown to the user when they have selected only one listing to compare.|,
|
||||
}
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -67,6 +67,10 @@ our $I18N = {
|
|||
message => q|Delete|,
|
||||
lastUpdated => 1224686319
|
||||
},
|
||||
'warnings' => {
|
||||
message => q|Warnings|,
|
||||
lastUpdated => 0
|
||||
},
|
||||
'section number' => {
|
||||
message => q|Section Number:|,
|
||||
lastUpdated => 1224686319
|
||||
|
|
@ -251,9 +255,9 @@ our $I18N = {
|
|||
lastUpdated => 1224686319
|
||||
},
|
||||
'show text in button description' => {
|
||||
message => q|Select if the buttons of a multiple choice question display the answer values or not.|,
|
||||
message => q|By default multiple choice answer buttons show the answer text above each button. Change this to have the text appear inside of the buttons.|,
|
||||
context => q|Description of the 'show text in button' field, used as hoverhelp in the edit question dialog.|,
|
||||
lastUpdated => 0
|
||||
lastUpdated => 1239251986
|
||||
},
|
||||
'allow comment' => {
|
||||
message => q|Allow comment:|,
|
||||
|
|
@ -300,14 +304,14 @@ our $I18N = {
|
|||
context => q|Description of the 'required' field, used as hoverhelp in the edit question dialog.|,
|
||||
lastUpdated => 0
|
||||
},
|
||||
'question value' => {
|
||||
message => q|Question value:|,
|
||||
'question score' => {
|
||||
message => q|Question score:|,
|
||||
lastUpdated => 1224686319
|
||||
},
|
||||
'question value description' => {
|
||||
message => q|Enter a value for this question.|,
|
||||
'question score description' => {
|
||||
message => q|Default score to use for answers in this question that don't have an answer score value set.|,
|
||||
context => q|Description of the 'question value' field, used as hoverhelp in the edit question dialog.|,
|
||||
lastUpdated => 0
|
||||
lastUpdated => 1239255403
|
||||
},
|
||||
'please enter answer information' => {
|
||||
message => q|Please enter answer information:|,
|
||||
|
|
@ -333,13 +337,13 @@ our $I18N = {
|
|||
lastUpdated => 0
|
||||
},
|
||||
'recorded answer' => {
|
||||
message => q|Answer title:|,
|
||||
message => q|Recorded Answer:|,
|
||||
lastUpdated => 1224686319
|
||||
},
|
||||
'recorded answer description' => {
|
||||
message => q|Text to display inside multiple-choice answer buttons (only if 'Show text in button' is enabled for this question).|,
|
||||
message => q|Determines what gets recorded as the response value if this answer is selected. Allows you to 'recode' recorded responses, e.g. 'Yes' could be recorded as '1' and 'No' as '0'. Relevant only for Multiple Choice questions (other question types record the input actually entered by the user: free text, selected date, etc..).|,
|
||||
context => q|Description of the 'recorded answer' field, used as hoverhelp in the edit answer dialog.|,
|
||||
lastUpdated => 0
|
||||
lastUpdated => 1239251436
|
||||
},
|
||||
'jump to' => {
|
||||
message => q|Jump to:|,
|
||||
|
|
@ -355,9 +359,9 @@ our $I18N = {
|
|||
lastUpdated => 0
|
||||
},
|
||||
'jump expression description' => {
|
||||
message => q|An expression used to control complex branching based user responses to previous questions. A branch expression is made up of a list of rules, one per line, along with a branch target for each rule. |,
|
||||
message => q|An expression used to control complex branching based user responses to previous questions. Ignored unless enableSurveyExpressionEngine enabled in your site config file.|,
|
||||
context => q|Description of the 'jump expression' field, used as hoverhelp in the edit answer dialog.|,
|
||||
lastUpdated => 0
|
||||
lastUpdated => 1239259550
|
||||
},
|
||||
'text answer' => {
|
||||
message => q|TextArea|,
|
||||
|
|
@ -416,14 +420,14 @@ our $I18N = {
|
|||
context => q|Description of the 'verbatim' field, used as hoverhelp in the edit answer dialog.|,
|
||||
lastUpdated => 0
|
||||
},
|
||||
'answer value' => {
|
||||
message => q|Answer value:|,
|
||||
lastUpdated => 1224686319
|
||||
'answer score' => {
|
||||
message => q|Answer score:|,
|
||||
lastUpdated => 1239251986
|
||||
},
|
||||
'answer value description' => {
|
||||
message => q|Assign a numeric scores to this answers. Used in question scoring and jump expressions.|,
|
||||
context => q|Description of the 'answer value' field, used as hoverhelp in the edit answer dialog.|,
|
||||
lastUpdated => 0
|
||||
'answer score description' => {
|
||||
message => q|Assign a numeric score to this answer. If blank, the question score value will used instead. Used in question scoring and jump expressions.|,
|
||||
context => q|Description of the 'answer score' field, used as hoverhelp in the edit answer dialog.|,
|
||||
lastUpdated => 1239251986
|
||||
},
|
||||
'checked' => {
|
||||
message => q|Checked|,
|
||||
|
|
@ -1282,7 +1286,7 @@ section/answer.|,
|
|||
},
|
||||
|
||||
'textInButton' => {
|
||||
message => q|A boolean indicating whether the buttons for answers to multiple choice questions should display the answer's text.|,
|
||||
message => q|A boolean indicating whether the buttons for answers to multiple choice questions should display the answer's text inside or above.|,
|
||||
context => q|Description of a template variable for a template Help page.|,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
|
@ -1318,7 +1322,7 @@ section/answer.|,
|
|||
},
|
||||
|
||||
'recordedAnswer' => {
|
||||
message => q|The value that gets recorded for this answer in the database.|,
|
||||
message => q|Determines what gets recorded as the response value if this answer is selected. Allows you to 'recode' recorded responses, e.g. 'Yes' could be recorded as '1' and 'No' as '0'. Relevant only for Multiple Choice questions (other question types record the input actually entered by the user: free text, selected date, etc..).|,
|
||||
context => q|Description of a template variable for a template Help page.|,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1013,12 +1013,35 @@ search has been done.|,
|
|||
context => q|Description of a tmpl_var for the template help.|,
|
||||
},
|
||||
|
||||
'searchResult_edit_url' => {
|
||||
message => q|Url to the edit screen of this search result.|,
|
||||
lastUpdated => 1104630516,
|
||||
context => q|Description of a tmpl_var for the template help.|,
|
||||
},
|
||||
|
||||
'searchResult_delete_icon' => {
|
||||
message => q|Delete icon to delete this search result.|,
|
||||
lastUpdated => 1104630516,
|
||||
context => q|Description of a tmpl_var for the template help.|,
|
||||
},
|
||||
|
||||
'searchResult_delete_url' => {
|
||||
message => q|Url to delete this search result.|,
|
||||
lastUpdated => 1104630516,
|
||||
context => q|Description of a tmpl_var for the template help.|,
|
||||
},
|
||||
|
||||
'searchResult_copy_icon' => {
|
||||
message => q|Copy icon to copy this search result.|,
|
||||
lastUpdated => 1104630516,
|
||||
context => q|Description of a tmpl_var for the template help.|,
|
||||
},
|
||||
|
||||
'searchResult_copy_url' => {
|
||||
message => q|Url to copy this search result.|,
|
||||
lastUpdated => 1104630516,
|
||||
},
|
||||
|
||||
'searchResult_field_loop' => {
|
||||
message => q|A loop containing the fields that are to be displayed for this search result.|,
|
||||
lastUpdated => 1104630516,
|
||||
|
|
|
|||
|
|
@ -63,12 +63,14 @@ $testGroups{'canEdit asset'} = WebGUI::Group->new($session, 'new');
|
|||
$testUsers{'canEdit group user'} = WebGUI::User->new($session, 'new');
|
||||
$testUsers{'canEdit group user'}->addToGroups([$testGroups{'canEdit asset'}->getId]);
|
||||
$testUsers{'canEdit group user'}->username('Edit Group User');
|
||||
WebGUI::Test->groupsToDelete($testGroups{'canEdit asset'});
|
||||
|
||||
##A group and user for groupIdEdit
|
||||
$testGroups{'canAdd asset'} = WebGUI::Group->new($session, 'new');
|
||||
$testUsers{'canAdd group user'} = WebGUI::User->new($session, 'new');
|
||||
$testUsers{'canAdd group user'}->addToGroups([$testGroups{'canAdd asset'}->getId]);
|
||||
$testUsers{'canEdit group user'}->username('Can Add Group User');
|
||||
WebGUI::Test->groupsToDelete($testGroups{'canAdd asset'});
|
||||
|
||||
my $canAddMaker = WebGUI::Test::Maker::Permission->new();
|
||||
$canAddMaker->prepare({
|
||||
|
|
@ -819,9 +821,6 @@ END {
|
|||
foreach my $user (values %testUsers) {
|
||||
$user->delete;
|
||||
}
|
||||
foreach my $group (values %testUsers) {
|
||||
$group->delete;
|
||||
}
|
||||
}
|
||||
|
||||
##Return an array of hashrefs. Each hashref describes a test
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use WebGUI::Session;
|
|||
use WebGUI::User;
|
||||
|
||||
use WebGUI::Asset;
|
||||
use Test::More tests => 92; # increment this value for each test you create
|
||||
use Test::More tests => 90; # increment this value for each test you create
|
||||
use Test::Deep;
|
||||
|
||||
# Test the methods in WebGUI::AssetLineage
|
||||
|
|
@ -195,12 +195,10 @@ is(
|
|||
#
|
||||
####################################################
|
||||
|
||||
ok(!$snippet2->setParent($folder), 'setParent: user must be in group 4 to do this');
|
||||
$session->user({userId => $editor->userId});
|
||||
ok(!$snippet2->setParent(), 'setParent: new parent must be passed in');
|
||||
ok(!$snippet2->setParent($snippet2), 'setParent: cannot be your own parent');
|
||||
ok(!$snippet2->setParent($folder2), 'setParent: will not move self to current parent');
|
||||
ok(!$snippet2->setParent($folder), 'setParent: user cannot edit parent');
|
||||
|
||||
$session->user({userId => 3});
|
||||
ok(!$folder2->setParent($snippet2), 'setParent: will not move self to my child');
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ my $otherUser = WebGUI::User->new($session, 'new');
|
|||
my $groupIdEditUser = WebGUI::User->new($session, 'new');
|
||||
my $groupToEditPost = WebGUI::Group->new($session, $collab->get('groupToEditPost'));
|
||||
my $groupIdEditGroup = WebGUI::Group->new($session, $collab->get('groupIdEdit'));
|
||||
WebGUI::Test->groupsToDelete($groupToEditPost, $groupIdEditGroup);
|
||||
$postingUser->username('userForPosting');
|
||||
$otherUser->username('otherUser');
|
||||
|
||||
|
|
|
|||
49
t/Asset/Wobject/Carousel.t
Normal file
49
t/Asset/Wobject/Carousel.t
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 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";
|
||||
|
||||
##The goal of this test is to test the creation of Carousel Wobjects.
|
||||
|
||||
use WebGUI::Test;
|
||||
use WebGUI::Session;
|
||||
use Test::More tests => 2; # increment this value for each test you create
|
||||
use WebGUI::Asset::Wobject::Carousel;
|
||||
|
||||
my $session = WebGUI::Test->session;
|
||||
|
||||
# Do our work in the import node
|
||||
my $node = WebGUI::Asset->getImportNode($session);
|
||||
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Search Test"});
|
||||
my $carousel = $node->addChild({className=>'WebGUI::Asset::Wobject::Carousel'});
|
||||
|
||||
# Test for a sane object type
|
||||
isa_ok($carousel, 'WebGUI::Asset::Wobject::Carousel');
|
||||
|
||||
# Test to see if we can set new values
|
||||
my $newSettings = {
|
||||
templateId=>'testingtestingtesting1',
|
||||
};
|
||||
$carousel->update($newSettings);
|
||||
|
||||
foreach my $newSetting (keys %{$newSettings}) {
|
||||
is ($carousel->get($newSetting), $newSettings->{$newSetting}, "updated $newSetting is ".$newSettings->{$newSetting});
|
||||
}
|
||||
|
||||
|
||||
END {
|
||||
# Clean up after thy self
|
||||
$versionTag->rollback();
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ use WebGUI::Asset::Wobject::Collaboration;
|
|||
use WebGUI::Asset::Post;
|
||||
use WebGUI::Asset::Wobject::Layout;
|
||||
use Data::Dumper;
|
||||
use Test::More tests => 7; # increment this value for each test you create
|
||||
use Test::More tests => 10; # increment this value for each test you create
|
||||
|
||||
my $session = WebGUI::Test->session;
|
||||
|
||||
|
|
@ -50,7 +50,10 @@ my $layout = $node->addChild({className => 'WebGUI::Asset::Wobject::Layout'});
|
|||
$session->asset($layout);
|
||||
|
||||
# finally, add the collab
|
||||
my $collab = $layout->addChild({className => 'WebGUI::Asset::Wobject::Collaboration'});
|
||||
my $collab = $layout->addChild({
|
||||
className => 'WebGUI::Asset::Wobject::Collaboration',
|
||||
url => 'collab',
|
||||
});
|
||||
|
||||
# Test for a sane object type
|
||||
isa_ok($collab, 'WebGUI::Asset::Wobject::Collaboration');
|
||||
|
|
@ -91,6 +94,11 @@ $post = $collab->addChild($props,
|
|||
my $rssitems = $collab->getRssFeedItems();
|
||||
is(scalar @{ $rssitems }, 2, 'rssitems set to number of posts added');
|
||||
|
||||
diag "AssetAspect tests";
|
||||
is($collab->getRssFeedUrl, '/collab?func=viewRss', 'getRssFeedUrl');
|
||||
is($collab->getRdfFeedUrl, '/collab?func=viewRdf', 'getRdfFeedUrl');
|
||||
is($collab->getAtomFeedUrl, '/collab?func=viewAtom', 'getAtomFeedUrl');
|
||||
|
||||
TODO: {
|
||||
local $TODO = "Tests to make later";
|
||||
ok(0, 'A whole lot more work to do here');
|
||||
|
|
|
|||
|
|
@ -22,23 +22,24 @@ my $session = WebGUI::Test->session;
|
|||
|
||||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
my $tests = 36;
|
||||
my $tests = 41;
|
||||
plan tests => $tests + 1;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# put your tests here
|
||||
|
||||
my $usedOk = use_ok('WebGUI::Asset::Wobject::Survey::ExpressionEngine');
|
||||
|
||||
my ($user, $survey, $versionTag);
|
||||
SKIP: {
|
||||
|
||||
skip $tests, "Unable to load ExpressionEngine" unless $usedOk;
|
||||
|
||||
my $e = "WebGUI::Asset::Wobject::Survey::ExpressionEngine";
|
||||
|
||||
WebGUI::Test->originalConfig('enableSurveyExpressionEngine');
|
||||
$session->config->set( 'enableSurveyExpressionEngine', 0 );
|
||||
is( $e->run( $session, 'jump { 1 } target' ),
|
||||
undef, "Nothing happens unless we turn on enableSurveyExpressionEngine in config" );
|
||||
WebGUI::Test->originalConfig('enableSurveyExpressionEngine');
|
||||
$session->config->set( 'enableSurveyExpressionEngine', 1 );
|
||||
is( $e->run( $session, 'jump { 1 } target' ), 'target', "..now we're in business!" );
|
||||
|
||||
|
|
@ -109,8 +110,63 @@ SKIP: {
|
|||
undef, 'target is not valid' );
|
||||
is( $e->run( $session, q{jump {1} target}, { values => \%values, validTargets => { target => 1 } } ),
|
||||
'target', '..whereas now it is ok' );
|
||||
|
||||
|
||||
# Create a test user
|
||||
$user = WebGUI::User->new( $session, 'new' );
|
||||
|
||||
# Create a Survey
|
||||
$versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$survey = WebGUI::Asset->getImportNode($session)->addChild(
|
||||
{ className => 'WebGUI::Asset::Wobject::Survey',
|
||||
},
|
||||
);
|
||||
isa_ok($survey, 'WebGUI::Asset::Wobject::Survey');
|
||||
my $url = $survey->get('url');
|
||||
my $id = $survey->getId;
|
||||
|
||||
$survey->surveyJSON->newObject([]); # s0
|
||||
$survey->surveyJSON->newObject([0]); # s0q0
|
||||
$survey->surveyJSON->newObject([0,0]); # s0q0a0
|
||||
$survey->surveyJSON->newObject([0]); # s0q1
|
||||
$survey->surveyJSON->newObject([0,1]); # s0q1a0
|
||||
|
||||
$survey->surveyJSON->section([0])->{variable} = 'ext_s0';
|
||||
$survey->surveyJSON->question([0,0])->{variable} = 'ext_s0q0';
|
||||
$survey->surveyJSON->question([0,1])->{variable} = 'ext_s0q1';
|
||||
$survey->surveyJSON->answer([0,0,0])->{recordedAnswer} = 'ext_s0q0a0';
|
||||
$survey->surveyJSON->answer([0,0,0])->{value} = 150; # worth 150 points
|
||||
$survey->surveyJSON->answer([0,1,0])->{recordedAnswer} = 'ext_s0q1a0';
|
||||
$survey->surveyJSON->answer([0,1,0])->{value} = 50; # worth 50 points
|
||||
|
||||
$survey->responseIdCookies(0); # disable cookies so that test code doesn't die
|
||||
my $responseId = $survey->responseId($user->userId);
|
||||
|
||||
my $rJSON = $survey->responseJSON(undef, $responseId);
|
||||
$rJSON->recordResponses({
|
||||
'0-0-0' => 'My ext_s0q0a0 answer',
|
||||
'0-1-0' => 'My ext_s0q1a0 answer',
|
||||
});
|
||||
|
||||
# Remember to persist our changes..
|
||||
$survey->persistSurveyJSON();
|
||||
$survey->persistResponseJSON();
|
||||
$survey->surveyEnd;
|
||||
|
||||
is( $e->run( $session, qq{jump {value('$id', ext_s0q0) eq 'ext_s0q0a0'} target}, {userId => $user->userId} ),
|
||||
'target', 'external value resolves ok when id used' );
|
||||
is( $e->run( $session, qq{jump {value('$url', ext_s0q0) eq 'ext_s0q0a0'} target}, {userId => $user->userId} ),
|
||||
'target', 'external value resolves ok when url used' );
|
||||
is( $e->run( $session, qq{jump {score('$url', ext_s0q0) == 150} target}, {userId => $user->userId} ),
|
||||
'target', 'external score resolves ok too' );
|
||||
is( $e->run( $session, qq{jump {score('$url', ext_s0) == 200} target}, {userId => $user->userId} ),
|
||||
'target', 'external score section totals work too' );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Cleanup
|
||||
END { }
|
||||
END {
|
||||
$user->delete if $user;
|
||||
$survey->purge if $survey;
|
||||
$versionTag->rollback if $versionTag;
|
||||
}
|
||||
|
|
|
|||
16
t/Group.t
16
t/Group.t
|
|
@ -233,6 +233,7 @@ my $gB = WebGUI::Group->new($session, "new");
|
|||
$gA->name('Group A');
|
||||
$gB->name('Group B');
|
||||
ok( ($gA->name eq 'Group A' and $gB->name eq 'Group B'), 'object name assignment, multiple objects');
|
||||
WebGUI::Test->groupsToDelete($gA, $gB);
|
||||
|
||||
$gB->addGroups([$gA->getId]);
|
||||
|
||||
|
|
@ -253,6 +254,7 @@ cmp_bag($gA->getGroupsIn(), [3], 'Not allowed to add myself to my group');
|
|||
my $gC = WebGUI::Group->new($session, "new");
|
||||
$gC->name('Group C');
|
||||
$gA->addGroups([$gC->getId]);
|
||||
WebGUI::Test->groupsToDelete($gC);
|
||||
|
||||
cmp_bag($gC->getGroupsFor(), [$gA->getId], 'Group A contains Group C');
|
||||
cmp_bag($gA->getGroupsIn(), [$gC->getId, 3], 'Group C is a member of Group A, cached');
|
||||
|
|
@ -279,6 +281,7 @@ my $gZ = WebGUI::Group->new($session, "new");
|
|||
$gX->name('Group X');
|
||||
$gY->name('Group Y');
|
||||
$gZ->name('Group Z');
|
||||
WebGUI::Test->groupsToDelete($gX, $gY, $gZ);
|
||||
|
||||
$gZ->addGroups([$gX->getId, $gY->getId]);
|
||||
|
||||
|
|
@ -439,6 +442,7 @@ ok( isIn($mob[0]->userId, @{ $gZ->getAllUsers() }), 'mob[0] in list of group Z u
|
|||
my $gK = WebGUI::Group->new($session, "new");
|
||||
$gK->name('Group K');
|
||||
$gC->addGroups([$gK->getId]);
|
||||
WebGUI::Test->groupsToDelete($gK);
|
||||
|
||||
# B
|
||||
# / \
|
||||
|
|
@ -498,6 +502,7 @@ $session->setting->set('useKarma', $defaultKarmaSetting);
|
|||
my $gS = WebGUI::Group->new($session, "new");
|
||||
$gS->name('Group S');
|
||||
$gC->addGroups([$gS->getId]);
|
||||
WebGUI::Test->groupsToDelete($gS);
|
||||
|
||||
# B
|
||||
# / \
|
||||
|
|
@ -579,6 +584,7 @@ foreach my $idx (0..$#ipTests) {
|
|||
}
|
||||
|
||||
my $gI = WebGUI::Group->new($session, "new");
|
||||
WebGUI::Test->groupsToDelete($gI);
|
||||
$gI->name('Group I');
|
||||
$gI->ipFilter('194.168.0.0/24');
|
||||
|
||||
|
|
@ -614,6 +620,7 @@ ok( !$cacheDude->isInGroup($gY->getId), "Cache dude removed from group Y");
|
|||
ok( !$cacheDude->isInGroup($gZ->getId), "Cache dude removed from group Z too");
|
||||
|
||||
my $gCache = WebGUI::Group->new($session, "new");
|
||||
WebGUI::Test->groupsToDelete($gCache);
|
||||
|
||||
$gCache->addUsers([$cacheDude->userId]);
|
||||
|
||||
|
|
@ -642,10 +649,13 @@ SKIP: {
|
|||
ok(undef, "expiration date in groupings for getUser");
|
||||
}
|
||||
|
||||
################################################################
|
||||
#
|
||||
# getUserList
|
||||
#
|
||||
################################################################
|
||||
|
||||
END {
|
||||
foreach my $testGroup ($gX, $gY, $gZ, $gA, $gB, $gI, $gC, $g, $gK, $gS, $gCache) {
|
||||
$testGroup->delete if (defined $testGroup and ref $testGroup eq 'WebGUI::Group');
|
||||
}
|
||||
foreach my $dude ($user, @crowd, @mob, @chameleons, @itchies, @tcps, $cacheDude) {
|
||||
$dude->delete if (defined $dude and ref $dude eq 'WebGUI::User');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,12 +53,6 @@ my @testArray = (
|
|||
output => 0,
|
||||
comment => "s.also Privoxy/3.0 (Anonymous)"
|
||||
},
|
||||
{
|
||||
agent => "*/Nutch-0.9-dev",
|
||||
address => "123.113.184.232",
|
||||
output => 1,
|
||||
comment => "Unknown Yahoo robot"
|
||||
},
|
||||
{
|
||||
agent => "123spider-Bot (Version: 1.02, powered by www.123spider.de",
|
||||
output => 1,
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ our $logger_error;
|
|||
my %originalConfig;
|
||||
my $originalSetting;
|
||||
|
||||
my @groupsToDelete;
|
||||
|
||||
BEGIN {
|
||||
|
||||
STDERR->autoflush(1);
|
||||
|
|
@ -129,12 +131,15 @@ BEGIN {
|
|||
$SESSION = WebGUI::Session->open( $WEBGUI_ROOT, $CONFIG_FILE );
|
||||
$SESSION->{_request} = $pseudoRequest;
|
||||
|
||||
$originalSetting = clone $SESSION->setting;
|
||||
$originalSetting = clone $SESSION->setting->get;
|
||||
|
||||
}
|
||||
|
||||
END {
|
||||
my $Test = Test::Builder->new;
|
||||
foreach my $group (@groupsToDelete) {
|
||||
$group->delete;
|
||||
}
|
||||
if ($ENV{WEBGUI_TEST_DEBUG}) {
|
||||
$Test->diag('Sessions: '.$SESSION->db->quickScalar('select count(*) from userSession'));
|
||||
$Test->diag('Scratch : '.$SESSION->db->quickScalar('select count(*) from userSessionScratch'));
|
||||
|
|
@ -149,8 +154,7 @@ END {
|
|||
$SESSION->config->delete($key);
|
||||
}
|
||||
}
|
||||
my $settings = $originalSetting->get();
|
||||
while (my ($param, $value) = each %{ $settings }) {
|
||||
while (my ($param, $value) = each %{ $originalSetting }) {
|
||||
$SESSION->setting->set($param, $value);
|
||||
}
|
||||
$SESSION->var->end;
|
||||
|
|
@ -384,6 +388,20 @@ sub originalConfig {
|
|||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 groupsToDelete ( $group, [$group ] )
|
||||
|
||||
Push a list of group objects onto the stack of groups to be automatically deleted
|
||||
at the end of the test.
|
||||
|
||||
=cut
|
||||
|
||||
sub groupsToDelete {
|
||||
my $class = shift;
|
||||
push @groupsToDelete, @_;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
When trying to load the APR module, perl invariably throws an Out Of Memory
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
if(typeof(oRecord.getData("checked")) != 'undefined' && oRecord.getData("checked") == 'checked'){
|
||||
innerHTML = innerHTML + " checked='checked'";
|
||||
}
|
||||
innerHTML = innerHTML + " onchange='javascript:compareFormButton()' class='compareCheckBox'>";
|
||||
innerHTML = innerHTML + " class='compareCheckBox'>";
|
||||
elCell.innerHTML = innerHTML;
|
||||
};
|
||||
|
||||
|
|
@ -77,12 +77,21 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
},this,true);
|
||||
}
|
||||
|
||||
if(document.getElementById("sortByName")){
|
||||
var btnSortByName = new YAHOO.widget.Button("sortByName");
|
||||
btnSortByName.on("click", function(e) {
|
||||
this.myDataTable.sortColumn(this.myDataTable.getColumn(1));
|
||||
var request = YAHOO.util.Connect.asyncRequest('POST', matrixUrl + "?func=setSort;sort=lastUpdated");
|
||||
},this,true);
|
||||
}
|
||||
|
||||
|
||||
var myCallback = function() {
|
||||
this.set("sortedBy", null);
|
||||
this.onDataReturnAppendRows.apply(this,arguments);
|
||||
};
|
||||
|
||||
window.compareFormButton = function() {
|
||||
var compareFormButton = function() {
|
||||
var compareCheckBoxes = YAHOO.util.Dom.getElementsByClassName('compareCheckBox','input');
|
||||
var checked = 0;
|
||||
var checkedCompareBoxes = new Object();
|
||||
|
|
@ -92,12 +101,12 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
checkedCompareBoxes[compareCheckBoxes[i].value] = true;
|
||||
}
|
||||
}
|
||||
if (checked > 1 && checked < maxComparisons){
|
||||
btnCompare.set("disabled",false);
|
||||
btnCompare2.set("disabled",false);
|
||||
if (checked < 2){
|
||||
alert(tooFewMessage);
|
||||
}else if (checked > maxComparisons){
|
||||
alert(tooManyMessage);
|
||||
}else{
|
||||
btnCompare.set("disabled",true);
|
||||
btnCompare2.set("disabled",true);
|
||||
window.document.forms['doCompare'].submit();
|
||||
}
|
||||
var elements = window.compareDataTable.getRecordSet().getRecords();
|
||||
for(j=0; j<elements.length; j++){
|
||||
|
|
@ -109,21 +118,17 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(document.getElementById("compare")){
|
||||
var btnCompare = new YAHOO.widget.Button("compare",{disabled:true,id:"compareButton"});
|
||||
btnCompare.on("click", function(e) {
|
||||
window.document.forms['doCompare'].submit();
|
||||
},this,true);
|
||||
var btnCompare = new YAHOO.widget.Button("compare",{id:"compareButton"});
|
||||
btnCompare.on("click", compareFormButton);
|
||||
}
|
||||
|
||||
if(document.getElementById("compare2")){
|
||||
var btnCompare2 = new YAHOO.widget.Button("compare2",{disabled:true,id:"compareButton2"});
|
||||
btnCompare2.on("click", function(e) {
|
||||
window.document.forms['doCompare'].submit();
|
||||
},this,true);
|
||||
var btnCompare2 = new YAHOO.widget.Button("compare2",{id:"compareButton2"});
|
||||
btnCompare2.on("click", compareFormButton);
|
||||
}
|
||||
|
||||
|
||||
if(document.getElementById("search")){
|
||||
var btnSearch = new YAHOO.widget.Button("search");
|
||||
btnSearch.on("click", function(e) {
|
||||
|
|
|
|||
|
|
@ -104,58 +104,40 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
scope : myDataTable
|
||||
};
|
||||
|
||||
var btnCompare = new YAHOO.widget.Button("compare",{disabled:true,id:"compareButton"});
|
||||
btnCompare.on("click", function(e) {
|
||||
var compareCheckBoxes = YAHOO.util.Dom.getElementsByClassName('compareCheckBox','input');
|
||||
var uri = "func=getCompareListData";
|
||||
for (var i = compareCheckBoxes.length; i--; ) {
|
||||
if(compareCheckBoxes[i].checked == true){
|
||||
uri = uri+';listingId='+compareCheckBoxes[i].value;
|
||||
}
|
||||
}
|
||||
myDataTable.getRecordSet().reset();
|
||||
myDataTable.refreshView();
|
||||
myDataTable.showTableMessage('Loading...');
|
||||
this.myDataSource.sendRequest(uri,callback2);
|
||||
},this,true);
|
||||
|
||||
var btnCompare2 = new YAHOO.widget.Button("compare2",{disabled:true,id:"compareButton2"});
|
||||
btnCompare2.on("click", function(e) {
|
||||
var compareCheckBoxes = YAHOO.util.Dom.getElementsByClassName('compareCheckBox','input');
|
||||
var uri = "func=getCompareListData";
|
||||
for (var i = compareCheckBoxes.length; i--; ) {
|
||||
if(compareCheckBoxes[i].checked == true){
|
||||
uri = uri+';listingId='+compareCheckBoxes[i].value;
|
||||
}
|
||||
}
|
||||
myDataTable.getRecordSet().reset();
|
||||
myDataTable.refreshView();
|
||||
myDataTable.showTableMessage('Loading...');
|
||||
this.myDataSource.sendRequest(uri,callback2);
|
||||
},this,true);
|
||||
|
||||
var btnSearch = new YAHOO.widget.Button("search");
|
||||
btnSearch.on("click", function(e) {
|
||||
window.location.href = matrixUrl + '?func=search';
|
||||
},this,true);
|
||||
|
||||
window.compareFormButton = function() {
|
||||
if(document.getElementById("compare3")){
|
||||
var btnCompare3 = new YAHOO.widget.Button("compare3",{id:"compareButton3"});
|
||||
btnCompare3.on("click", function(e) {
|
||||
var compareCheckBoxes = YAHOO.util.Dom.getElementsByClassName('compareCheckBox','input');
|
||||
var checked = 0;
|
||||
var checkedCompareBoxes = new Object();
|
||||
for (var i = compareCheckBoxes.length; i--; ) {
|
||||
if(compareCheckBoxes[i].checked){
|
||||
checked++;
|
||||
checkedCompareBoxes[compareCheckBoxes[i].value] = true;
|
||||
}
|
||||
}
|
||||
if (checked > 1 && checked < maxComparisons){
|
||||
btnCompare.set("disabled",false);
|
||||
btnCompare2.set("disabled",false);
|
||||
if (checked < 2){
|
||||
alert(tooFewMessage);
|
||||
}else if (checked > maxComparisons){
|
||||
alert(tooManyMessage);
|
||||
}else{
|
||||
btnCompare.set("disabled",true);
|
||||
btnCompare2.set("disabled",true);
|
||||
//window.document.forms['doCompare'].submit();
|
||||
var uri = "func=getCompareListData";
|
||||
for (var i = compareCheckBoxes.length; i--; ) {
|
||||
if(compareCheckBoxes[i].checked == true){
|
||||
uri = uri+';listingId='+compareCheckBoxes[i].value;
|
||||
}
|
||||
}
|
||||
myDataTable.getRecordSet().reset();
|
||||
myDataTable.refreshView();
|
||||
myDataTable.showTableMessage('Loading...');
|
||||
this.myDataSource.sendRequest(uri,callback2);
|
||||
}
|
||||
|
||||
},this,true);
|
||||
}
|
||||
|
||||
if(document.getElementById("stickied")){
|
||||
var btnStickied = new YAHOO.widget.Button("stickied");
|
||||
btnStickied.on("click", function(e) {
|
||||
var elements = myDataTable.getRecordSet().getRecords();
|
||||
|
|
@ -187,6 +169,7 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
hideStickies = 0;
|
||||
}
|
||||
},this,true);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
};
|
||||
|
||||
var uri = "func=getAttributes";
|
||||
if(typeof(revision) != 'undefined'){
|
||||
uri = uri + ';revision=' + revision;
|
||||
}
|
||||
|
||||
var initAttributeHoverHelp = function() {
|
||||
initHoverHelp('attributes');
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
if(typeof(oRecord.getData("checked")) != 'undefined' && oRecord.getData("checked") == 'checked'){
|
||||
innerHTML = innerHTML + " checked='checked'";
|
||||
}
|
||||
innerHTML = innerHTML + " onchange='javascript:compareFormButton()' class='compareCheckBox'>";
|
||||
innerHTML = innerHTML + " class='compareCheckBox'>";
|
||||
elCell.innerHTML = innerHTML;
|
||||
};
|
||||
|
||||
|
|
@ -42,7 +42,6 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
var myCallback = function() {
|
||||
this.set("sortedBy", null);
|
||||
this.onDataReturnAppendRows.apply(this,arguments);
|
||||
compareFormButton();
|
||||
};
|
||||
|
||||
var callback2 = {
|
||||
|
|
@ -72,12 +71,8 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
attributeSelects[i].onchange = reloadCompareForm;
|
||||
}
|
||||
|
||||
var btnCompare = new YAHOO.widget.Button("compare",{disabled:true,id:"compareButton"});
|
||||
var btnCompare = new YAHOO.widget.Button("compare",{id:"compareButton"});
|
||||
btnCompare.on("click", function(e) {
|
||||
window.document.forms['doCompare'].submit();
|
||||
},this,true);
|
||||
|
||||
window.compareFormButton = function() {
|
||||
var compareCheckBoxes = YAHOO.util.Dom.getElementsByClassName('compareCheckBox','input');
|
||||
var checked = 0;
|
||||
for (var i = compareCheckBoxes.length; i--; ) {
|
||||
|
|
@ -85,12 +80,15 @@ YAHOO.util.Event.addListener(window, "load", function() {
|
|||
checked++;
|
||||
}
|
||||
}
|
||||
if (checked > 1 && checked < maxComparisons){
|
||||
btnCompare.set("disabled",false);
|
||||
if (checked < 2){
|
||||
alert(tooFewMessage);
|
||||
}else if (checked > maxComparisons){
|
||||
alert(tooManyMessage);
|
||||
}else{
|
||||
btnCompare.set("disabled",true);
|
||||
window.document.forms['doCompare'].submit();
|
||||
}
|
||||
}
|
||||
},this,true);
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -324,14 +324,127 @@ if (typeof Survey === "undefined") {
|
|||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
YAHOO.widget.Chart.SWFURL = "/extras/yui/build/charts/assets/charts.swf";
|
||||
// Public API
|
||||
Survey.Form = {
|
||||
showSummary: function(html){
|
||||
Survey.Summary = {
|
||||
globalSummaryDataTip: function(item, index, series){
|
||||
var toolTipText = "hello";
|
||||
//var toolTipText = series.displayName + " for " + item.section;
|
||||
//toolTipText += "\n" + item[series.yField];
|
||||
return toolTipText;
|
||||
},
|
||||
showSummary: function(summary,html){
|
||||
var html = html;
|
||||
document.getElementById('survey').innerHTML = html;
|
||||
|
||||
|
||||
//Add totoal summary pie chart
|
||||
totalSummary =
|
||||
[
|
||||
{ correct: "Correct", count: summary.totalCorrect },
|
||||
{ correct: "Incorrect", count: summary.totalIncorrect }
|
||||
]
|
||||
|
||||
var totalSummaryDS = new YAHOO.util.DataSource( totalSummary );
|
||||
totalSummaryDS.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
|
||||
totalSummaryDS.responseSchema = { fields: [ "correct", "count" ] };
|
||||
|
||||
new YAHOO.widget.PieChart( "chart", totalSummaryDS,
|
||||
{
|
||||
dataField: "count",
|
||||
categoryField: "correct",
|
||||
style:
|
||||
{
|
||||
padding: 10,
|
||||
legend:
|
||||
{
|
||||
display: "left",
|
||||
padding: 10,
|
||||
spacing: 2,
|
||||
font:
|
||||
{
|
||||
family: "Arial",
|
||||
size: 13
|
||||
}
|
||||
}
|
||||
},
|
||||
//only needed for flash player express install
|
||||
expressInstall: "/extras/yui/build/charts/assets/charts.swf"
|
||||
});
|
||||
|
||||
//define section datatable columns
|
||||
var myColumnDefs = [
|
||||
{key:"Question ID", sortable:true, resizeable:true},
|
||||
{key:"Question Text", formatter: YAHOO.widget.DataTable.formatText, sortable:true, resizeable:true},
|
||||
{key:"Answer ID", sortable:true, resizeable:true},
|
||||
{key:"Correct", sortable:true, resizeable:true},
|
||||
{key:"Answer Text", formatter: YAHOO.widget.DataTable.formatText, sortable:true, resizeable:true},
|
||||
{key:"Score", sortable:true, resizeable:true},
|
||||
{key:"Value", formatter: YAHOO.widget.DataTable.formatText, sortable:true, resizeable:true}
|
||||
];
|
||||
var sectionSummary = [];
|
||||
//Load up datatables and create section data for bar chart
|
||||
for(var i = 0; i < summary.sections.length; i++){
|
||||
var temp = summary.sections[i];
|
||||
sectionSummary[sectionSummary.length] = {"Total Responses": temp.total, "Correct": temp.correct, "Incorrect": temp.inCorrect, "section": (i+1)};
|
||||
var myDataSource = new YAHOO.util.DataSource(summary.sections[i].responses);
|
||||
//These needs to be put in a destroy call list for when the html dom is recreated, if summaries are going to be uses with page reloads, else memory leak.
|
||||
myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
|
||||
myDataSource.responseSchema = {
|
||||
fields: ["Question ID","Question Text","Answer ID","Correct","Answer Text","Score","Value"]
|
||||
};
|
||||
var tempText = "section"+ (i+1) + "datatable";
|
||||
new YAHOO.widget.DataTable(tempText, myColumnDefs, myDataSource, {caption:"Section "+(i+1)});
|
||||
}
|
||||
|
||||
//Now create section summary bar charts
|
||||
var sectionSummaryDS = new YAHOO.util.DataSource( sectionSummary );
|
||||
sectionSummaryDS.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
|
||||
sectionSummaryDS.responseSchema =
|
||||
{
|
||||
fields: [ "Total Responses", "Correct", "Incorrect", "section" ]
|
||||
};
|
||||
var sectionSummarySeriesDef =
|
||||
[
|
||||
{
|
||||
displayName: "Total Responses",
|
||||
yField: "Total Responses",
|
||||
style:{size:10}
|
||||
},
|
||||
{
|
||||
displayName: "Correct",
|
||||
yField: "Correct",
|
||||
style:{size:10}
|
||||
},
|
||||
{
|
||||
displayName: "Incorrect",
|
||||
yField: "Incorrect",
|
||||
style:{size:10}
|
||||
}
|
||||
];
|
||||
//create a Numeric Axis for displaying dollars
|
||||
var responseAxis = new YAHOO.widget.NumericAxis();
|
||||
responseAxis.title = "Responses";
|
||||
//create Category Axis to specify a title for the months
|
||||
var sectionAxis = new YAHOO.widget.CategoryAxis();
|
||||
sectionAxis.title = "Sections";
|
||||
//create the Chart
|
||||
var mychart = new YAHOO.widget.ColumnChart( "summarychart", sectionSummaryDS,
|
||||
{
|
||||
series: sectionSummarySeriesDef,
|
||||
xField: "section",
|
||||
xAxis: sectionAxis,
|
||||
yAxis: responseAxis,
|
||||
// dataTipFunction: Survey.Form.globalSummaryDataTip, //try again in 2.7
|
||||
expressInstall: "/extras/yui/build/charts/assets/charts.swf"
|
||||
});
|
||||
|
||||
YAHOO.util.Event.addListener("submitbutton", "click", function(){ Survey.Comm.submitSummary(); });
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
Survey.Form = {
|
||||
displayQuestions: function(params){
|
||||
toValidate = [];
|
||||
var qs = params.questions;
|
||||
|
|
@ -530,3 +643,11 @@ YAHOO.util.Event.onDOMReady(function(){
|
|||
// Survey.Comm.setUrl('/' + document.getElementById('assetPath').value);
|
||||
Survey.Comm.callServer('', 'loadQuestions');
|
||||
});
|
||||
|
||||
YAHOO.example.getDataTipText = function( item, index, series )
|
||||
{
|
||||
var toolTipText = series.displayName + " for " + item.month;
|
||||
// toolTipText += "\n" + YAHOO.example.formatCurrencyAxisLabel( item[series.yField] );
|
||||
return toolTipText;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ if (typeof Survey === "undefined") {
|
|||
window.location = url;
|
||||
}
|
||||
else if(response.type === 'summary'){
|
||||
Survey.Form.showSummary(response.summary);
|
||||
Survey.Summary.showSummary(response.summary,response.html);
|
||||
}
|
||||
else {
|
||||
alert("bad response");
|
||||
|
|
|
|||
|
|
@ -56,9 +56,17 @@ Survey.Data = (function(){
|
|||
focus = d.address;//What is the current highlighted item.
|
||||
var warnings = "";
|
||||
for(var w in d.warnings){
|
||||
warnings = warnings + "<br>" + d.warnings[w];
|
||||
warnings += "<div class='warning'>" + d.warnings[w] + "</div>";
|
||||
}
|
||||
if (document.getElementById('warnings')) {
|
||||
if (warnings !== "") {
|
||||
document.getElementById('warnings').innerHTML = warnings;
|
||||
YAHOO.util.Dom.setStyle('warnings-outer', 'display', 'block');
|
||||
}
|
||||
else {
|
||||
YAHOO.util.Dom.setStyle('warnings-outer', 'display', 'none');
|
||||
}
|
||||
}
|
||||
document.getElementById('warnings').innerHTML = warnings;
|
||||
var showEdit = 1;
|
||||
if (lastId.toString() === d.address.toString()) {
|
||||
showEdit = 0;
|
||||
|
|
|
|||
|
|
@ -171,3 +171,13 @@ li.newAnswer {
|
|||
width:15em;
|
||||
margin-top:0.5em;
|
||||
}
|
||||
|
||||
#warnings-outer {
|
||||
margin: 5px;
|
||||
padding: 0 5px;
|
||||
border: 1px solid;
|
||||
color: red;
|
||||
}
|
||||
#warnings {
|
||||
color: red;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -223,8 +223,10 @@ function dragable_init(url) {
|
|||
}else {
|
||||
for (i = 0; i< children.length;i++) {
|
||||
draggableObjectList[draggableObjectList.length] = children[i];
|
||||
new YAHOO.webgui.DDList(document.getElementById(children[i].id + "_div"));
|
||||
new YAHOO.util.DDTarget(document.getElementById(children[i].id + "_div"));
|
||||
dragDropElement = document.getElementById(children[i].id + "_div");
|
||||
dragDrop = new YAHOO.webgui.DDList(dragDropElement);
|
||||
new YAHOO.util.DDTarget(dragDropElement);
|
||||
dragDrop.setHandleElId(children[i].id + "_handle");
|
||||
}
|
||||
}
|
||||
obj = document.getElementById("position" + contentCount);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue