Merge with HEAD, 10472
This commit is contained in:
commit
19f703dc9b
102 changed files with 5700 additions and 2269 deletions
|
|
@ -247,7 +247,11 @@ By specifying this method, you activate this feature.
|
|||
|
||||
sub getAutoCommitWorkflowId {
|
||||
my $self = shift;
|
||||
return $self->getParent->get("submissionApprovalWorkflowId");
|
||||
|
||||
if($self->session->form->process("assetId") eq "new"){
|
||||
return $self->getParent->get("submissionApprovalWorkflowId");
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -312,6 +316,19 @@ sub getEditForm {
|
|||
hoverHelp =>$i18n->get('maintainer description'),
|
||||
);
|
||||
}
|
||||
else{
|
||||
my $userId;
|
||||
if ($func eq "add"){
|
||||
$userId = $session->user->userId;
|
||||
}
|
||||
else{
|
||||
$userId = $self->get('ownerUserId');
|
||||
}
|
||||
$form->hidden(
|
||||
-name =>'ownerUserId',
|
||||
-value =>$userId,
|
||||
);
|
||||
}
|
||||
$form->text(
|
||||
-name =>'version',
|
||||
-defaultValue =>undef,
|
||||
|
|
@ -492,6 +509,34 @@ sub processPropertiesFromFormPost {
|
|||
}
|
||||
$self->update({score => $score});
|
||||
|
||||
if ( $self->get('screenshots') ) {
|
||||
my $fileObject = WebGUI::Form::File->new($self->session,{ value=>$self->get('screenshots') });
|
||||
my $storage = $fileObject->getStorageLocation;
|
||||
my @files;
|
||||
@files = @{ $storage->getFiles } if (defined $storage);
|
||||
foreach my $file (@files) {
|
||||
unless ($file =~ m/^thumb-/){
|
||||
my ($resizeWidth,$resizeHeight);
|
||||
my ($width, $height) = $storage->getSizeInPixels($file);
|
||||
my $maxWidth = $self->getParent->get('maxScreenshotWidth');
|
||||
my $maxHeight = $self->getParent->get('maxScreenshotHeight');
|
||||
if ($width > $maxWidth){
|
||||
my $newHeight = $height * ($maxWidth / $width);
|
||||
if ($newHeight > $maxHeight){
|
||||
# Heigth requires more resizing so use maxHeight
|
||||
$storage->resize($file, 0, $maxHeight);
|
||||
}
|
||||
else{
|
||||
$storage->resize($file, $maxWidth);
|
||||
}
|
||||
}
|
||||
elsif($height > $maxHeight){
|
||||
$storage->resize($file, 0, $maxHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$self->requestAutoCommit;
|
||||
return undef;
|
||||
}
|
||||
|
|
@ -962,6 +1007,7 @@ sub www_getScreenshots {
|
|||
@files = @{ $storage->getFiles } if (defined $storage);
|
||||
foreach my $file (@files) {
|
||||
unless ($file =~ m/^thumb-/){
|
||||
my ($width, $height) = $storage->getSizeInPixels($file);
|
||||
my $thumb = 'thumb-'.$file;
|
||||
$xml .= "
|
||||
<slide>
|
||||
|
|
@ -970,6 +1016,8 @@ sub www_getScreenshots {
|
|||
<image_source>".$storage->getUrl($file)."</image_source>
|
||||
<duration>5</duration>
|
||||
<thumb_source>".$storage->getUrl($thumb)."</thumb_source>
|
||||
<width>".$width."</width>
|
||||
<height>".$height."</height>
|
||||
</slide>
|
||||
";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -970,6 +970,7 @@ sub postProcess {
|
|||
my $spamStopWords = $self->session->config->get('spamStopWords');
|
||||
if (ref $spamStopWords eq 'ARRAY') {
|
||||
my $spamRegex = join('|',@{$spamStopWords});
|
||||
$spamRegex =~ s/\s/\\ /g;
|
||||
if ($data{content} =~ m/$spamRegex/xmsi) {
|
||||
$data{skipNotification} = 1;
|
||||
$self->trash;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use base 'WebGUI::Asset';
|
|||
use WebGUI::International;
|
||||
use WebGUI::Inbox;
|
||||
use WebGUI::Shop::Cart;
|
||||
|
||||
use JSON qw{ from_json to_json };
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
|
@ -41,7 +41,6 @@ use WebGUI::Asset::Sku;
|
|||
$hashRef = $self->getOptions;
|
||||
$integer = $self->getMaxAllowedInCart;
|
||||
$float = $self->getPrice;
|
||||
$float = $self->getTaxRate;
|
||||
$boolean = $self->isShippingRequired;
|
||||
$html = $self->processStyle($output);
|
||||
|
||||
|
|
@ -102,6 +101,7 @@ sub definition {
|
|||
my $definition = shift;
|
||||
my %properties;
|
||||
tie %properties, 'Tie::IxHash';
|
||||
|
||||
my $i18n = WebGUI::International->new($session, "Asset_Sku");
|
||||
%properties = (
|
||||
description => {
|
||||
|
|
@ -125,20 +125,6 @@ sub definition {
|
|||
label => $i18n->get("display title"),
|
||||
hoverHelp => $i18n->get("display title help")
|
||||
},
|
||||
overrideTaxRate => {
|
||||
tab => "shop",
|
||||
fieldType => "yesNo",
|
||||
defaultValue => 0,
|
||||
label => $i18n->get("override tax rate"),
|
||||
hoverHelp => $i18n->get("override tax rate help")
|
||||
},
|
||||
taxRateOverride => {
|
||||
tab => "shop",
|
||||
fieldType => "float",
|
||||
defaultValue => 0.00,
|
||||
label => $i18n->get("tax rate override"),
|
||||
hoverHelp => $i18n->get("tax rate override help")
|
||||
},
|
||||
vendorId => {
|
||||
tab => "shop",
|
||||
fieldType => "vendor",
|
||||
|
|
@ -146,6 +132,11 @@ sub definition {
|
|||
label => $i18n->get("vendor"),
|
||||
hoverHelp => $i18n->get("vendor help")
|
||||
},
|
||||
taxConfiguration => {
|
||||
noFormPost => 1,
|
||||
fieldType => 'hidden',
|
||||
defaultValue => '{}',
|
||||
},
|
||||
);
|
||||
push(@{$definition}, {
|
||||
assetName=>$i18n->get('assetName'),
|
||||
|
|
@ -206,6 +197,31 @@ sub getConfiguredTitle {
|
|||
return $self->getTitle;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
sub getEditForm {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
|
||||
my $tabform = $self->SUPER::getEditForm;
|
||||
|
||||
# Let the tax system add the form fields that are required by the active tax plugin for configuring the sku tax.
|
||||
# WebGUI::Shop::Tax->new( $session )->appendSkuForm( $self->getId, $tabform->getTab('shop') );
|
||||
|
||||
my $taxDriver = WebGUI::Shop::Tax->getDriver( $session );
|
||||
my $definition = $taxDriver->skuFormDefinition;
|
||||
my $config = $self->getTaxConfiguration( $taxDriver->className );
|
||||
my $shop = $tabform->getTab( 'shop' );
|
||||
|
||||
foreach my $fieldName ( keys %{ $definition } ) {
|
||||
$shop->dynamicField(
|
||||
%{ $definition->{ $fieldName } },
|
||||
name => $fieldName,
|
||||
value => $config->{ $fieldName },
|
||||
);
|
||||
}
|
||||
|
||||
return $tabform;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
|
|
@ -264,6 +280,22 @@ sub getPrice {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getPostPurchaseActions ( item )
|
||||
|
||||
Get a hash reference of LABEL => URL pairs of actions we can do on
|
||||
this Sku after it is purchased. These will show up in the Transaction
|
||||
screen. C<item> is the WebGUI::Shop::TransactionItem that was
|
||||
purchased.
|
||||
|
||||
=cut
|
||||
|
||||
sub getPostPurchaseActions {
|
||||
my ( $self, $item ) = @_;
|
||||
return {};
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getQuantityAvailable ( )
|
||||
|
||||
Returns 99999999. Needs to be overriden by subclasses. Tells the commerce system how many of this item is on hand.
|
||||
|
|
@ -288,16 +320,17 @@ sub getRecurInterval {
|
|||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
sub getTaxConfiguration {
|
||||
my $self = shift;
|
||||
my $namespace = shift;
|
||||
|
||||
=head2 getTaxRate ( )
|
||||
my $configs = eval { from_json( $self->getValue('taxConfiguration') ) };
|
||||
if ($@) {
|
||||
$self->session->log->error( 'Tax configuration of asset ' . $self->getId . ' appears to be corrupt. :' . $@ );
|
||||
return undef;
|
||||
}
|
||||
|
||||
Returns undef unless the "Override tax rate?" switch is set to yes. If it is, then it returns the value of the "Tax Rate Override" field.
|
||||
|
||||
=cut
|
||||
|
||||
sub getTaxRate {
|
||||
my $self = shift;
|
||||
return ($self->get("overrideTaxRate")) ? $self->get("taxRateOverride") : undef;
|
||||
return $configs->{ $namespace }
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -528,6 +561,20 @@ sub onRemoveFromCart {
|
|||
return undef;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
sub processPropertiesFromFormPost {
|
||||
my $self = shift;
|
||||
|
||||
my $output = $self->SUPER::processPropertiesFromFormPost( @_ );
|
||||
|
||||
my $taxDriver = WebGUI::Shop::Tax->new( $self->session )->getDriver;
|
||||
$self->session->log->fatal( 'Could not instanciate tax driver.' ) unless $taxDriver;
|
||||
|
||||
$self->setTaxConfiguration( $taxDriver->className, $taxDriver->processSkuFormPost );
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 processStyle ( output )
|
||||
|
|
@ -546,6 +593,28 @@ sub processStyle {
|
|||
return $self->getParent->processStyle($output);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
sub setTaxConfiguration {
|
||||
my $self = shift;
|
||||
my $namespace = shift;
|
||||
my $configuration = shift;
|
||||
|
||||
# Fetch current tax configurations
|
||||
my $configs = eval { from_json( $self->getValue('taxConfiguration') ) };
|
||||
if ($@) {
|
||||
$self->session->log->error( 'Tax configuration of asset ' . $self->getId . ' is corrupt.' );
|
||||
return undef;
|
||||
}
|
||||
|
||||
# Apply the new configuration for the given driver...
|
||||
$configs->{ $namespace } = $configuration;
|
||||
|
||||
# ...and persist it to the db.
|
||||
$self->update( {
|
||||
taxConfiguration => to_json( $configs ),
|
||||
} );
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_view ( )
|
||||
|
|
|
|||
708
lib/WebGUI/Asset/Sku/ThingyRecord.pm
Normal file
708
lib/WebGUI/Asset/Sku/ThingyRecord.pm
Normal file
|
|
@ -0,0 +1,708 @@
|
|||
package WebGUI::Asset::Sku::ThingyRecord;
|
||||
|
||||
=head1 LEGAL
|
||||
|
||||
-------------------------------------------------------------------
|
||||
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
|
||||
-------------------------------------------------------------------
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use Tie::IxHash;
|
||||
use base 'WebGUI::Asset::Sku';
|
||||
use WebGUI::Utility;
|
||||
|
||||
# Collateral data class... very long name. Zoffix eat your heart out.
|
||||
my $RECORD_CLASS = 'WebGUI::AssetCollateral::Sku::ThingyRecord::Record';
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Package WebGUI::Asset::Sku::ThingyRecord
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Purchase a record in a thingy.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use WebGUI::Asset::ThingyRecord;
|
||||
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
These methods are available from this class:
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 definition ( session, definition )
|
||||
|
||||
=head3 session
|
||||
|
||||
=head3 definition
|
||||
|
||||
A hash reference passed in from a subclass definition.
|
||||
|
||||
=cut
|
||||
|
||||
sub definition {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
my $definition = shift;
|
||||
my $i18n = WebGUI::International->new( $session, "Asset_ThingyRecord" );
|
||||
tie my %properties, 'Tie::IxHash', (
|
||||
templateIdView => {
|
||||
tab => "display",
|
||||
fieldType => "template",
|
||||
namespace => "ThingyRecord/View",
|
||||
label => $i18n->get('templateIdView label'),
|
||||
hoverHelp => $i18n->get('templateIdView description'),
|
||||
},
|
||||
thingId => {
|
||||
tab => "properties",
|
||||
fieldType => "selectBox",
|
||||
options => $class->getThingOptions($session),
|
||||
label => $i18n->get('thingId label'),
|
||||
hoverHelp => $i18n->get('thingId description'),
|
||||
extras => q{onchange="WebGUI.ThingyRecord.getThingFields(this.options[this.selectedIndex].value,'thingFields_formId')"},
|
||||
},
|
||||
thingFields => {
|
||||
tab => "properties",
|
||||
fieldType => "selectList",
|
||||
options => {}, # populated by ajax call
|
||||
label => $i18n->get('thingFields label'),
|
||||
hoverHelp => $i18n->get('thingFields description'),
|
||||
},
|
||||
thankYouText => {
|
||||
tab => "properties",
|
||||
fieldType => "HTMLArea",
|
||||
defaultValue=> $i18n->get('default thank you message','Asset_Product') . " ^ViewCart;",
|
||||
label => $i18n->get("thank you message",'Asset_Product'),
|
||||
hoverHelp => $i18n->get("thank you message help",'Asset_Product'),
|
||||
},
|
||||
price => {
|
||||
tab => "properties",
|
||||
fieldType => "float",
|
||||
label => $i18n->get('10',"Asset_Product"), #Price
|
||||
hoverHelp => $i18n->get('price','Asset_Product'),
|
||||
},
|
||||
duration => {
|
||||
tab => "properties",
|
||||
fieldType => "interval",
|
||||
defaultValue=> 60*60*24*7, # One week
|
||||
label => $i18n->get('duration label'),
|
||||
hoverHelp => $i18n->get('duration description'),
|
||||
},
|
||||
);
|
||||
push @{$definition}, {
|
||||
assetName => $i18n->get('assetName'),
|
||||
icon => 'ThingyRecord.gif',
|
||||
autoGenerateForms => 1,
|
||||
tableName => 'ThingyRecord',
|
||||
className => __PACKAGE__,
|
||||
properties => \%properties,
|
||||
};
|
||||
return $class->SUPER::definition( $session, $definition );
|
||||
} ## end sub definition
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 appendVarsEditRecord ( var, recordId )
|
||||
|
||||
Get the template variables for the form to edit the record. Does not include
|
||||
the header or footer!
|
||||
|
||||
=cut
|
||||
|
||||
sub appendVarsEditRecord {
|
||||
my ( $self, $var, $recordId ) = @_;
|
||||
my $session = $self->session;
|
||||
my $thingy = $self->getThingy;
|
||||
my $record = {};
|
||||
if ( $recordId ) {
|
||||
# Get an existing record
|
||||
$record = $self->getThingRecord( $self->get('thingId'), $recordId );
|
||||
if ( !%$record ) { # Record is hidden
|
||||
$record = JSON->new->decode(
|
||||
$RECORD_CLASS->new( $session, $recordId )->get('fields')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
my $fields = $self->getThingFields( $self->get('thingId') );
|
||||
my @allowed = split "\n", $self->get('thingFields');
|
||||
for my $field ( @{$fields} ) {
|
||||
next unless grep { $_ eq $field->{fieldId} } @allowed;
|
||||
$field->{value} = $record->{'field_'.$field->{fieldId}} || $field->{defaultValue};
|
||||
my %fieldProperties = (
|
||||
"input" => $thingy->getFormElement($field),
|
||||
"value" => $thingy->getFieldValue($field->{value}, $field),
|
||||
"label" => $field->{label},
|
||||
"isHidden" => ($field->{status} eq 'hidden'),
|
||||
"isVisible" => ($field->{status} eq "visible"),
|
||||
"isRequired" => ($field->{status} eq "required"),
|
||||
"pretext" => $field->{pretext},
|
||||
"subtext" => $field->{subtext},
|
||||
);
|
||||
push @{$var->{form_fields}}, {
|
||||
map { "field_" . $_ => $fieldProperties{$_} } keys %fieldProperties
|
||||
};
|
||||
# Add a way to get the field outside of the loop
|
||||
# TODO
|
||||
}
|
||||
|
||||
return $var;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 deleteThingRecord ( thingId, recordId )
|
||||
|
||||
Delete a record from a thing
|
||||
|
||||
=cut
|
||||
|
||||
sub deleteThingRecord {
|
||||
my ( $self, $thingId, $recordId ) = @_;
|
||||
my $db = $self->session->db;
|
||||
my $dbh = $self->session->db->dbh;
|
||||
my $tableName = $dbh->quote_identifier( 'Thingy_' . $thingId );
|
||||
$db->write(
|
||||
"DELETE FROM $tableName WHERE thingDataId=?",
|
||||
[$recordId]
|
||||
);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getEditForm ( )
|
||||
|
||||
Add the javascript needed for the edit form
|
||||
|
||||
=cut
|
||||
|
||||
sub getEditForm {
|
||||
my ( $self ) = @_;
|
||||
$self->session->style->setScript(
|
||||
$self->session->url->extras('yui/build/yahoo-dom-event/yahoo-dom-event.js'),
|
||||
{ type => "text/javascript" },
|
||||
);
|
||||
$self->session->style->setScript(
|
||||
$self->session->url->extras('yui/build/connection/connection-min.js'),
|
||||
{ type => "text/javascript" },
|
||||
);
|
||||
$self->session->style->setScript(
|
||||
$self->session->url->extras('yui/build/json/json-min.js'),
|
||||
{ type => "text/javascript" },
|
||||
);
|
||||
$self->session->style->setScript(
|
||||
$self->session->url->extras('yui-webgui/build/thingyRecord/thingyRecord.js'),
|
||||
{ type => "text/javascript" },
|
||||
);
|
||||
return $self->SUPER::getEditForm;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getMaxAllowedInCart ( )
|
||||
|
||||
One only!
|
||||
|
||||
=cut
|
||||
|
||||
sub getMaxAllowedInCart {
|
||||
my ( $self ) = @_;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getPostPurchaseActions ( item )
|
||||
|
||||
Return a hash reference of "label" => "url" to do things with this item after
|
||||
it is purchased. C<item> is the WebGUI::Shop::TransactionItem for this item
|
||||
|
||||
=cut
|
||||
|
||||
sub getPostPurchaseActions {
|
||||
my ( $self, $item ) = @_;
|
||||
my $session = $self->session;
|
||||
my $opts = $self->SUPER::getPostPurchaseActions();
|
||||
my $i18n = WebGUI::International->new( $session, "Asset_ThingyRecord" );
|
||||
my $recordId = $item->get('options')->{recordId};
|
||||
|
||||
$opts->{ $i18n->get('renew') }
|
||||
= $self->getUrl('func=renew;recordId='.$recordId);
|
||||
$opts->{ $i18n->get('575', 'WebGUI') } # edit
|
||||
= $self->getUrl('func=editRecord;recordid='.$recordId);
|
||||
|
||||
return $opts;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getPrice ( )
|
||||
|
||||
Get the price
|
||||
|
||||
=cut
|
||||
|
||||
sub getPrice {
|
||||
my ( $self ) = @_;
|
||||
return $self->get('price');
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getTemplateVars ( )
|
||||
|
||||
Get common template vars for this asset.
|
||||
|
||||
=cut
|
||||
|
||||
sub getTemplateVars {
|
||||
my $self = shift;
|
||||
my $var = $self->get;
|
||||
$var->{ url } = $self->getUrl;
|
||||
return $var;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getThingFields ( thingId )
|
||||
|
||||
Get the fields for a thing.
|
||||
|
||||
=cut
|
||||
|
||||
sub getThingFields {
|
||||
my ( $self, $thingId ) = @_;
|
||||
|
||||
my $fields = $self->session->db->buildArrayRefOfHashRefs(
|
||||
'SELECT * FROM Thingy_fields WHERE thingId = ? ORDER BY sequenceNumber',
|
||||
[$thingId]
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getThingOptions ( session )
|
||||
|
||||
Get all the thingys and all the things in them.
|
||||
|
||||
=cut
|
||||
|
||||
sub getThingOptions {
|
||||
my ( $class, $session ) = @_;
|
||||
tie my %options, 'Tie::IxHash', ( "" => "" );
|
||||
my $thingyIter = WebGUI::Asset->getRoot( $session )
|
||||
->getLineageIterator( ['descendants'], {
|
||||
includeOnlyClasses => ['WebGUI::Asset::Wobject::Thingy'],
|
||||
} );
|
||||
while ( my $thingy = $thingyIter->() ) {
|
||||
tie my %things, 'Tie::IxHash', (
|
||||
$session->db->buildHash(
|
||||
"SELECT thingId, label FROM Thingy_things WHERE assetId=?",
|
||||
[$thingy->getId]
|
||||
)
|
||||
);
|
||||
$options{$thingy->get('title')} = \%things;
|
||||
}
|
||||
|
||||
return \%options;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getThingRecord ( thingId, recordId )
|
||||
|
||||
Get a row of data from a thing. Returns a hashref
|
||||
|
||||
=cut
|
||||
|
||||
sub getThingRecord {
|
||||
my ( $self, $thingId, $recordId ) = @_;
|
||||
my $table = $self->session->db->dbh->quote_identifier( "Thingy_" . $thingId );
|
||||
return $self->session->db->quickHashRef(
|
||||
"SELECT * FROM " . $table . " WHERE thingDataId=?",
|
||||
[$recordId]
|
||||
);
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 getThingy ( )
|
||||
|
||||
Get the thingy associated with this ThingyRecord
|
||||
|
||||
=cut
|
||||
|
||||
sub getThingy {
|
||||
my ( $self ) = @_;
|
||||
my $thingyId = $self->session->db->quickScalar(
|
||||
"SELECT assetId FROM Thingy_things WHERE thingId=?",
|
||||
[$self->get('thingId')],
|
||||
);
|
||||
return WebGUI::Asset->newByDynamicClass( $self->session, $thingyId );
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 onCompletePurchase ( )
|
||||
|
||||
Purchase completed, add the record.
|
||||
|
||||
=cut
|
||||
|
||||
sub onCompletePurchase {
|
||||
my ( $self, $item ) = @_;
|
||||
|
||||
my $option = $self->getOptions;
|
||||
my $record = $RECORD_CLASS->new( $self->session, $option->{recordId} );
|
||||
my $now = time;
|
||||
|
||||
if ( $option->{action} eq "buy" ) {
|
||||
# Update record
|
||||
$record->update({
|
||||
expires => $now + $self->get('duration'),
|
||||
transactionId => $item->transaction->getId,
|
||||
isHidden => 0,
|
||||
});
|
||||
|
||||
# Add to thingy data
|
||||
my $data = JSON->new->decode( $record->get('fields') );
|
||||
$self->updateThingRecord( $self->get('thingId'), $record->getId, $data );
|
||||
}
|
||||
elsif ( $option->{action} eq "renew" ) {
|
||||
# Renew a currently active record
|
||||
if ( $record->get('expires') > $now ) {
|
||||
$record->update({
|
||||
expires => $record->get('expires') + $self->get('duration'),
|
||||
});
|
||||
}
|
||||
# Renew an expired but not deleted record
|
||||
else {
|
||||
$record->update({
|
||||
expires => $now + $self->get('duration'),
|
||||
isHidden => 0,
|
||||
});
|
||||
|
||||
# Add to thingy data
|
||||
my $data = JSON->new->decode( $record->get('fields') );
|
||||
$self->updateThingRecord( $self->get('thingId'), $record->getId, $data );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 onRemoveFromCart ( )
|
||||
|
||||
Removed from cart, remove all knowledge
|
||||
|
||||
=cut
|
||||
|
||||
sub onRemoveFromCart {
|
||||
my ( $self, $item ) = @_;
|
||||
|
||||
# Remove from cart
|
||||
my $option = $self->getOptions;
|
||||
if ( $option->{action} eq "buy" ) {
|
||||
my $record = $RECORD_CLASS->new($self->session,$option->{recordId});
|
||||
if ( $record ) {
|
||||
$record->delete;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 prepareView ( )
|
||||
|
||||
See WebGUI::Asset::prepareView() for details.
|
||||
|
||||
=cut
|
||||
|
||||
sub prepareView {
|
||||
my $self = shift;
|
||||
$self->SUPER::prepareView();
|
||||
my $template = WebGUI::Asset::Template->new( $self->session, $self->get("templateIdView") );
|
||||
$template->prepare($self->getMetaDataAsTemplateVariables);
|
||||
$self->{_viewTemplate} = $template;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 processEditRecordForm ( )
|
||||
|
||||
Process the edit record form and return the record
|
||||
|
||||
=cut
|
||||
|
||||
sub processEditRecordForm {
|
||||
my ( $self ) = @_;
|
||||
my $var = {};
|
||||
|
||||
my $fields = $self->getThingFields( $self->get('thingId') );
|
||||
for my $field ( @{$fields} ) {
|
||||
my $fieldName = 'field_'.$field->{fieldId};
|
||||
my $fieldType = $field->{fieldType};
|
||||
$fieldType = "" if ($fieldType =~ m/^otherThing/x);
|
||||
$var->{ $fieldName }
|
||||
= $self->session->form->get($fieldName,$fieldType,$field->{defaultValue},$field);
|
||||
}
|
||||
|
||||
return $var;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 purge ( )
|
||||
|
||||
Remove all collateral associated with the ThingyRecord sku
|
||||
|
||||
=cut
|
||||
|
||||
sub purge {
|
||||
my $self = shift;
|
||||
|
||||
my $options = {
|
||||
constraints => {
|
||||
'assetId = ?' => $self->getId,
|
||||
},
|
||||
};
|
||||
|
||||
my $iter = $RECORD_CLASS->getAllIterator($self->session,$options);
|
||||
while ( my $item = $iter->() ) {
|
||||
$item->delete;
|
||||
}
|
||||
|
||||
# Should we also remove the records from the Thingy?
|
||||
|
||||
return $self->SUPER::purge;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 updateThingRecord ( thingId, data )
|
||||
|
||||
Update data in a thing
|
||||
|
||||
=cut
|
||||
|
||||
sub updateThingRecord {
|
||||
my ( $self, $thingId, $recordId, $data ) = @_;
|
||||
my $db = $self->session->db;
|
||||
my $dbh = $self->session->db->dbh;
|
||||
my $tableName = $dbh->quote_identifier('Thingy_'.$thingId);
|
||||
$data->{ thingDataId } = $recordId;
|
||||
my $columns = join ",", map { $dbh->quote_identifier( $_ ) } keys %{$data};
|
||||
my $values = [ values %{$data} ];
|
||||
my $places = join ",", ('?') x @{$values};
|
||||
$self->session->db->write(
|
||||
"REPLACE INTO $tableName ($columns) VALUES ($places)",
|
||||
$values,
|
||||
);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 view ( options )
|
||||
|
||||
method called by the container www_view method.
|
||||
|
||||
=cut
|
||||
|
||||
sub view {
|
||||
my ( $self, $options ) = @_;
|
||||
my $session = $self->session;
|
||||
my $i18n = WebGUI::International->new( $session, "Asset_ThingyRecord" );
|
||||
my $var = $self->getTemplateVars;
|
||||
$self->appendVarsEditRecord( $var );
|
||||
$var->{ isNew } = 1;
|
||||
$var->{ message } = $options->{addedToCart}
|
||||
? $self->get('thankYouText')
|
||||
: $options->{message}
|
||||
;
|
||||
|
||||
# Add form header, footer, and submit button
|
||||
$var->{ form_header }
|
||||
= WebGUI::Form::formHeader( $session, {
|
||||
action => $self->getUrl('func=buy'),
|
||||
} );
|
||||
|
||||
$var->{ form_footer }
|
||||
= WebGUI::Form::formFooter( $session );
|
||||
|
||||
$var->{ form_submit }
|
||||
= WebGUI::Form::submit( $session, {
|
||||
value => $i18n->get('add to cart','Shop'),
|
||||
} );
|
||||
|
||||
return $self->processTemplate( $var, undef, $self->{_viewTemplate} );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 www_buy ( )
|
||||
|
||||
Create a new record and add it to the cart
|
||||
|
||||
=cut
|
||||
|
||||
sub www_buy {
|
||||
my ( $self ) = @_;
|
||||
my $session = $self->session;
|
||||
|
||||
# Get data for row
|
||||
my $recordFields = $self->processEditRecordForm;
|
||||
my $recordData = {
|
||||
userId => $session->user->userId,
|
||||
assetId => $self->getId,
|
||||
fields => JSON->new->encode( $recordFields ),
|
||||
};
|
||||
|
||||
# Add row to cart collateral
|
||||
my $record = $RECORD_CLASS->create( $session, $recordData );
|
||||
|
||||
# Add item to cart with appropriate action and recordId
|
||||
$self->addToCart({
|
||||
action => "buy",
|
||||
recordId => $record->getId,
|
||||
});
|
||||
|
||||
# Return thank you screen
|
||||
$self->prepareView;
|
||||
return $self->processStyle(
|
||||
$self->view({ addedToCart => 1 })
|
||||
);
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 www_editRecord ( options )
|
||||
|
||||
Edit the record after is has been purchased. Allow the user to show/hide the
|
||||
record while it is still active.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_editRecord {
|
||||
my ( $self, $options ) = @_;
|
||||
my $session = $self->session;
|
||||
my $recordId = $session->form->get( 'recordId' );
|
||||
my $record = $RECORD_CLASS->new( $session, $recordId );
|
||||
return $self->session->privilege->insufficient
|
||||
unless $self->session->user->userId eq $record->get('userId');
|
||||
my $i18n = WebGUI::International->new( $session, "Asset_ThingyRecord" );
|
||||
my $var = $self->getTemplateVars;
|
||||
$self->appendVarsEditRecord( $var, $recordId );
|
||||
$var->{ message } = $options->{message};
|
||||
|
||||
# Add form header, footer, and submit button
|
||||
$var->{ form_header }
|
||||
= WebGUI::Form::formHeader( $session, {
|
||||
action => $self->getUrl('func=editRecordSave;recordId=' . $recordId),
|
||||
} );
|
||||
|
||||
$var->{ form_footer }
|
||||
= WebGUI::Form::formFooter( $session );
|
||||
|
||||
$var->{ form_submit }
|
||||
= WebGUI::Form::submit( $session, {
|
||||
value => $i18n->get('save','WebGUI'),
|
||||
} );
|
||||
|
||||
# Add record information
|
||||
my $recordData = $record->get;
|
||||
for my $key ( keys %{$recordData} ) {
|
||||
$var->{ "record_" . $key } = $recordData->{ $key };
|
||||
}
|
||||
|
||||
# Add field to hide/show
|
||||
# Don't allow user to show expired record
|
||||
if ( time < $record->get('expires') ) {
|
||||
$var->{ form_hide }
|
||||
= WebGUI::Form::yesNo( $session, {
|
||||
name => "hide",
|
||||
value => $record->get('isHidden'),
|
||||
} );
|
||||
}
|
||||
|
||||
return $self->processStyle(
|
||||
$self->processTemplate( $var, $self->get('templateIdView') )
|
||||
);
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 www_editRecordSave ( )
|
||||
|
||||
Save the record
|
||||
|
||||
=cut
|
||||
|
||||
sub www_editRecordSave {
|
||||
my ( $self ) = @_;
|
||||
my $session = $self->session;
|
||||
my $form = $self->session->form;
|
||||
my $recordId = $form->get('recordId');
|
||||
my $record = $RECORD_CLASS->new( $session, $recordId );
|
||||
return $self->session->privilege->insufficient
|
||||
unless $self->session->user->userId eq $record->get('userId');
|
||||
my $i18n = WebGUI::International->new( $session, "Asset_ThingyRecord" );
|
||||
my $hide = $form->get('hide');
|
||||
my $recordData = $self->processEditRecordForm;
|
||||
$record->update({
|
||||
fields => JSON->new->encode( $recordData ),
|
||||
isHidden => $hide,
|
||||
});
|
||||
|
||||
if ( $hide ) {
|
||||
$self->deleteThingRecord( $self->get('thingId'), $recordId );
|
||||
}
|
||||
else {
|
||||
$self->updateThingRecord( $self->get('thingId'), $recordId, $recordData );
|
||||
}
|
||||
|
||||
return $self->www_editRecord({ message => $i18n->get('saved') });
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 www_renew ( )
|
||||
|
||||
Add more time to an existing record.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_renew {
|
||||
my ( $self ) = @_;
|
||||
my $session = $self->session;
|
||||
my $i18n = WebGUI::International->new( $session, "Asset_ThingyRecord" );
|
||||
my $recordId = $self->session->form->get('recordId');
|
||||
my $record = $RECORD_CLASS->new( $session, $recordId );
|
||||
return $session->privilege->insufficient
|
||||
unless $session->user->userId eq $record->get('userId');
|
||||
|
||||
$self->addToCart({
|
||||
action => "renew",
|
||||
recordId => $recordId,
|
||||
});
|
||||
|
||||
return $self->www_editRecord({ message => $i18n->get('renewal added to cart') . ' ^ViewCart;' });
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
#vim:ft=perl
|
||||
|
|
@ -125,6 +125,22 @@ sub getAutoCommitWorkflowId {
|
|||
my $self = shift;
|
||||
my $wiki = $self->getWiki;
|
||||
if ($wiki->hasBeenCommitted) {
|
||||
|
||||
# delete spam
|
||||
my $spamStopWords = $self->session->config->get('spamStopWords');
|
||||
if (ref $spamStopWords eq 'ARRAY') {
|
||||
my $spamRegex = join('|',@{$spamStopWords});
|
||||
$spamRegex =~ s/\s/\\ /g;
|
||||
if ($self->get('content') =~ m{$spamRegex}xmsi) {
|
||||
my $tag = WebGUI::VersionTag->new($self->session, $self->get('tagId'));
|
||||
$self->purgeRevision;
|
||||
if ($tag->getAssetCount == 0) {
|
||||
$tag->rollback;
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
return $wiki->get('approvalWorkflow')
|
||||
|| $self->session->setting->get('defaultVersionTagWorkflow');
|
||||
}
|
||||
|
|
@ -276,7 +292,6 @@ sub processPropertiesFromFormPost {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -380,10 +380,17 @@ An HTML blob to be parsed into the current style.
|
|||
=cut
|
||||
|
||||
sub processStyle {
|
||||
my $self = shift;
|
||||
my $output = shift;
|
||||
$self->session->style->setRawHeadTags($self->getExtraHeadTags);
|
||||
return $self->session->style->process($output,$self->get("styleTemplateId"));
|
||||
my ($self, $output) = @_;
|
||||
my $session = $self->session;
|
||||
my $style = $session->style;
|
||||
$style->setRawHeadTags($self->getExtraHeadTags);
|
||||
if ($self->get('synopsis')) {
|
||||
$style->setMeta({
|
||||
name => 'Description',
|
||||
content => $self->get('synopsis'),
|
||||
});
|
||||
}
|
||||
return $style->process($output,$self->get("styleTemplateId"));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1532,11 +1532,26 @@ sub www_process {
|
|||
my $default = $field->{defaultValue};
|
||||
WebGUI::Macro::process($self->session, \$default);
|
||||
my $value = $entry->field( $field->{name} ) || $default;
|
||||
|
||||
# WebGUI::Form::Integer::getValue() returns 0 even if no number is passed in.
|
||||
# Not really a suitable default if we want to trigger the error message
|
||||
|
||||
if ($field->{status} eq "required" || $field->{status} eq "editable") {
|
||||
|
||||
# get the raw value (by sending field type as blank)
|
||||
my $rawValue = $session->form->process($field->{name}, '');
|
||||
|
||||
$value = $session->form->process($field->{name}, $field->{type}, undef, {
|
||||
defaultValue => $default,
|
||||
value => $value,
|
||||
});
|
||||
|
||||
# this is a hack, but it's better than changing the default getValue() of Integer, which
|
||||
# could have massive effects downstream in other uses.
|
||||
if(($field->{type} =~ /integer/i) && defined($rawValue) && ($rawValue eq '') && ($value eq "0")) {
|
||||
$value = $rawValue;
|
||||
}
|
||||
|
||||
WebGUI::Macro::filter(\$value);
|
||||
}
|
||||
if ($field->{status} eq "required" && (! defined($value) || $value =~ /^\s*$/)) {
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@ sub prepareView {
|
|||
}
|
||||
|
||||
my %vars;
|
||||
$vars{showAdmin} = ($session->var->isAdminOn && $self->canEdit && $self->canEditIfLocked);
|
||||
|
||||
my $splitter = $self->{_viewSplitter} = $self->getSeparator;
|
||||
|
||||
|
|
@ -194,9 +195,12 @@ sub prepareView {
|
|||
$child->prepareView;
|
||||
$placeHolder{$assetId} = $child;
|
||||
push @children, {
|
||||
id => $assetId,
|
||||
isUncommitted => $child->get('status') eq 'pending',
|
||||
content => $splitter . $assetId . '~~',
|
||||
id => $assetId,
|
||||
isUncommitted => $child->get('status') eq 'pending',
|
||||
content => $splitter . $assetId . '~~',
|
||||
};
|
||||
if ($vars{showAdmin}) {
|
||||
$children[-1]->{'dragger.icon'} = sprintf '<div id="td%s_handle" class="dragable"><div class="dragTrigger dragTriggerWrap">%s</div></div>', $assetId, $session->icon->drag('class="dragTrigger"');
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -230,7 +234,6 @@ sub prepareView {
|
|||
unshift @{ $vars{"position1_loop"} }, reverse @children;
|
||||
}
|
||||
|
||||
$vars{showAdmin} = ($session->var->isAdminOn && $self->canEdit && $self->canEditIfLocked);
|
||||
if ($vars{showAdmin}) {
|
||||
# under normal circumstances we don't put HTML stuff in our code, but this will make it much easier
|
||||
# for end users to work with our templates
|
||||
|
|
@ -247,7 +250,6 @@ sub prepareView {
|
|||
}
|
||||
</style>
|
||||
');
|
||||
$vars{"dragger.icon"} = '<div class="dragTrigger dragTriggerWrap">'.$session->icon->drag('class="dragTrigger"').'</div>';
|
||||
$vars{"dragger.init"} = '
|
||||
<iframe id="dragSubmitter" style="display: none;" src="'.$session->url->extras('spacer.gif').'"></iframe>
|
||||
<script type="text/javascript">
|
||||
|
|
|
|||
|
|
@ -194,6 +194,20 @@ sub definition {
|
|||
hoverHelp =>$i18n->get('compare color yes description'),
|
||||
label =>$i18n->get('compare color yes label'),
|
||||
},
|
||||
maxScreenshotWidth=>{
|
||||
fieldType =>"integer",
|
||||
tab =>"display",
|
||||
defaultValue =>"800",
|
||||
hoverHelp =>$i18n->get('max screenshot width description'),
|
||||
label =>$i18n->get('max screenshot width label'),
|
||||
},
|
||||
maxScreenshotHeight=>{
|
||||
fieldType =>"integer",
|
||||
tab =>"display",
|
||||
defaultValue =>"600",
|
||||
hoverHelp =>$i18n->get('max screenshot height description'),
|
||||
label =>$i18n->get('max screenshot height label'),
|
||||
},
|
||||
categories=>{
|
||||
fieldType =>"textarea",
|
||||
tab =>"properties",
|
||||
|
|
|
|||
|
|
@ -197,8 +197,6 @@ sub definition {
|
|||
fieldType => 'workflow',
|
||||
label => 'Survey End Workflow',
|
||||
hoverHelp => 'Workflow to run when user completes the Survey',
|
||||
# label => $i18n->get('editForm workflowIdAddEntry label'),
|
||||
# hoverHelp => $i18n->get('editForm workflowIdAddEntry description'),
|
||||
none => 1,
|
||||
},
|
||||
quizModeSummary => {
|
||||
|
|
@ -207,13 +205,16 @@ sub definition {
|
|||
tab => 'properties',
|
||||
label => $i18n->get('Quiz mode summaries'),
|
||||
hoverHelp => $i18n->get('Quiz mode summaries help'),
|
||||
}
|
||||
},
|
||||
allowBackBtn => {
|
||||
fieldType => 'yesNo',
|
||||
defaultValue => 0,
|
||||
tab => 'properties',
|
||||
label => $i18n->get('Allow back button'),
|
||||
hoverHelp => $i18n->get('Allow back button help'),
|
||||
},
|
||||
);
|
||||
|
||||
#my $defaultMC = $session->
|
||||
|
||||
#%properties = ();
|
||||
|
||||
push @{$definition}, {
|
||||
assetName => $i18n->get('assetName'),
|
||||
icon => 'survey.gif',
|
||||
|
|
@ -800,7 +801,7 @@ sub www_loadSurvey {
|
|||
elsif ( $lastType eq 'question' ) {
|
||||
$q = 1;
|
||||
}
|
||||
$html .= "<li id='$scount' class='section'>S" . ( $scount + 1 ) . ": $_->{text}<\/li><br>\n";
|
||||
$html .= "<li id='$scount' class='section'>S" . ( $scount + 1 ) . ": $_->{text}<\/li>\n";
|
||||
push( @ids, $scount );
|
||||
}
|
||||
elsif ( $_->{type} eq 'question' ) {
|
||||
|
|
@ -808,7 +809,7 @@ sub www_loadSurvey {
|
|||
if ( $lastType eq 'answer' ) {
|
||||
$a = 1;
|
||||
}
|
||||
$html .= "<li id='$scount-$qcount' class='question'>Q" . ( $qcount + 1 ) . ": $_->{text}<\/li><br>\n";
|
||||
$html .= "<li id='$scount-$qcount' class='question'>Q" . ( $qcount + 1 ) . ": $_->{text}<\/li>\n";
|
||||
push @ids, "$scount-$qcount";
|
||||
$lastType = 'question';
|
||||
$acount = -1;
|
||||
|
|
@ -818,12 +819,12 @@ sub www_loadSurvey {
|
|||
$html
|
||||
.= "<li id='$scount-$qcount-$acount' class='answer'>A"
|
||||
. ( $acount + 1 )
|
||||
. ": $_->{text}<\/li><br>\n";
|
||||
. ": $_->{text}<\/li>\n";
|
||||
push @ids, "$scount-$qcount-$acount";
|
||||
$lastType = 'answer';
|
||||
}
|
||||
}
|
||||
|
||||
$html = "<ul class='draglist'>$html</ul>";
|
||||
my $warnings = $self->surveyJSON->validateSurvey();
|
||||
|
||||
my $return = {
|
||||
|
|
@ -1154,6 +1155,41 @@ sub www_submitQuestions {
|
|||
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_goBack
|
||||
|
||||
Handles the Survey back button
|
||||
|
||||
=cut
|
||||
|
||||
sub www_goBack {
|
||||
my $self = shift;
|
||||
|
||||
if ( !$self->canTakeSurvey() ) {
|
||||
$self->session->log->debug('canTakeSurvey false, surveyEnd');
|
||||
return $self->surveyEnd();
|
||||
}
|
||||
|
||||
my $responseId = $self->responseId();
|
||||
if ( !$responseId ) {
|
||||
$self->session->log->debug('No response id, surveyEnd');
|
||||
return $self->surveyEnd();
|
||||
}
|
||||
|
||||
if ( !$self->get('allowBackBtn') ) {
|
||||
$self->session->log->debug('allowBackBtn false, delegating to www_loadQuestions');
|
||||
return $self->www_loadQuestions();
|
||||
}
|
||||
|
||||
$self->responseJSON->pop;
|
||||
$self->persistResponseJSON;
|
||||
|
||||
return $self->www_loadQuestions();
|
||||
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getSummary
|
||||
|
|
@ -1305,15 +1341,8 @@ Sends the processed template and questions structure to the client
|
|||
|
||||
sub prepareShowSurveyTemplate {
|
||||
my ( $self, $section, $questions ) = @_;
|
||||
# my %multipleChoice = (
|
||||
# 'Multiple Choice', 1, 'Gender', 1, 'Yes/No', 1, 'True/False', 1, 'Ideology', 1,
|
||||
# 'Race', 1, 'Party', 1, 'Education', 1, 'Scale', 1, 'Agree/Disagree', 1,
|
||||
# 'Oppose/Support', 1, 'Importance', 1, 'Likelihood', 1, 'Certainty', 1, 'Satisfaction', 1,
|
||||
# 'Confidence', 1, 'Effectiveness', 1, 'Concern', 1, 'Risk', 1, 'Threat', 1,
|
||||
# 'Security', 1
|
||||
# );
|
||||
my %textArea = ( 'TextArea', 1 );
|
||||
my %text = ( 'Text', 1, 'Email', 1, 'Phone Number', 1, 'Text Date', 1, 'Currency', 1 );
|
||||
my %text = ( 'Text', 1, 'Email', 1, 'Phone Number', 1, 'Text Date', 1, 'Currency', 1, 'Number', 1 );
|
||||
my %slider = ( 'Slider', 1, 'Dual Slider - Range', 1, 'Multi Slider - Allocate', 1 );
|
||||
my %dateType = ( 'Date', 1, 'Date Range', 1 );
|
||||
my %dateShort = ( 'Year Month', 1 );
|
||||
|
|
@ -1379,6 +1408,7 @@ sub prepareShowSurveyTemplate {
|
|||
if(scalar @{$questions} == ($section->{totalQuestions} - $section->{questionsAnswered})){
|
||||
$section->{isLastPage} = 1
|
||||
}
|
||||
$section->{allowBackBtn} = $self->get('allowBackBtn');
|
||||
|
||||
my $out = $self->processTemplate( $section, $self->get('surveyQuestionsId') );
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ sub value {
|
|||
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]");
|
||||
$session->log->debug("value($asset_spec, $key) resolves to [$value]");
|
||||
return $value;
|
||||
} else {
|
||||
# Throw an exception, triggering run() to resolve the external reference and re-run
|
||||
|
|
@ -63,7 +63,7 @@ sub value {
|
|||
}
|
||||
my $key = shift;
|
||||
my $value = $values->{$key};
|
||||
$session->log->debug("[$key] resolves to [$value]");
|
||||
$session->log->debug("value($key) resolves to [$value]");
|
||||
return $value; # scalar variable, so no need to clone
|
||||
}
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ sub score {
|
|||
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]");
|
||||
$session->log->debug("score($asset_spec, $key) resolves to [$score]");
|
||||
return $score;
|
||||
} else {
|
||||
# Throw an exception, triggering run() to resolve the external reference and re-run
|
||||
|
|
@ -94,7 +94,7 @@ sub score {
|
|||
}
|
||||
my $key = shift;
|
||||
my $score = $scores->{$key};
|
||||
$session->log->debug("[$key] resolves to [$score]");
|
||||
$session->log->debug("score($key) resolves to [$score]");
|
||||
return $score; # scalar variable, so no need to clone
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,59 +39,6 @@ number of questions answered (L<"questionsAnswered">) and the Survey start time
|
|||
|
||||
This package is not intended to be used by any other Asset in WebGUI.
|
||||
|
||||
=head2 surveyOrder
|
||||
|
||||
This data strucutre is an array (reference) of Survey addresses (see
|
||||
L<WebGUI::Asset::Wobject::Survey::SurveyJSON/Address Parameter>), stored in the order
|
||||
in which items are presented to the user.
|
||||
|
||||
By making use of L<WebGUI::Asset::Wobject::Survey::SurveyJSON> methods which expect address params as
|
||||
arguments, you can access Section/Question/Answer items in order by iterating over surveyOrder.
|
||||
|
||||
For example:
|
||||
|
||||
# Access sections in order..
|
||||
for my $address (@{ $self->surveyOrder }) {
|
||||
my $section = $self->survey->section( $address );
|
||||
# etc..
|
||||
}
|
||||
|
||||
In general, the surveyOrder data structure looks like:
|
||||
|
||||
[ $sectionIndex, $questionIndex, [ $answerIndex1, $answerIndex2, ....]
|
||||
|
||||
There is one array element for every section and address in the survey. If there are
|
||||
no questions, or no addresses, those array elements will not be present.
|
||||
|
||||
=head2 responses
|
||||
|
||||
This data structure stores a snapshot of all question responses. Both question data and answer data
|
||||
is stored in this hash reference.
|
||||
|
||||
Questions keys are constructed by hypenating the relevant L<"sIndex"> and L<"qIndex">.
|
||||
Answer keys are constructed by hypenating the relevant L<"sIndex">, L<"qIndex"> and L<aIndex|"aIndexes">.
|
||||
|
||||
Question entries only contain a comment field:
|
||||
{
|
||||
...
|
||||
questionId => {
|
||||
comment => "question comment",
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
Answers entries contain: value (the recorded value), time and comment fields.
|
||||
|
||||
{
|
||||
...
|
||||
answerId => {
|
||||
value => "recorded answer value",
|
||||
time => time(),
|
||||
comment => "answer comment",
|
||||
},
|
||||
...
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
|
|
@ -252,7 +199,7 @@ sub hasTimedOut{
|
|||
|
||||
=head2 lastResponse ([ $responseIndex ])
|
||||
|
||||
Mutator. The lastResponse property represents the index of the most recent surveyOrder entry shown.
|
||||
Mutator. The lastResponse property represents the surveyOrder index of the most recent item shown.
|
||||
|
||||
This method returns (and optionally sets) the value of lastResponse.
|
||||
|
||||
|
|
@ -325,8 +272,32 @@ sub startTime {
|
|||
|
||||
=head2 surveyOrder
|
||||
|
||||
Accessor for surveyOrder (see L<"surveyOrder">).
|
||||
Initialized on first access via L<"initSurveyOrder">.
|
||||
Accessor. Initialized on first access via L<"initSurveyOrder">.
|
||||
|
||||
This data strucutre represents the list of items that are shown to the user, in the order
|
||||
that they will be shown (ignoring jumps and jump expressions).
|
||||
|
||||
Typically each item will correspond to a question, and contains enough information to look
|
||||
up both the corresponding section and all contained answers (if any).
|
||||
|
||||
Empty sections also appear in the list.
|
||||
|
||||
Each element of the array is an address, similar in structure to
|
||||
L<WebGUI::Asset::Wobject::Survey::SurveyJSON/Address Parameter>,
|
||||
except that instead of an answerIndex in the third slot, we have a sub-array of all contained answer indicies.
|
||||
|
||||
[ $sectionIndex, $questionIndex, [ $answerIndex1, $answerIndex2, ....]
|
||||
|
||||
By making use of L<WebGUI::Asset::Wobject::Survey::SurveyJSON> methods which expect address params as
|
||||
arguments, you can access Section/Question/Answer items in order by iterating over surveyOrder.
|
||||
|
||||
For example:
|
||||
|
||||
# Access sections in order..
|
||||
for my $address (@{ $self->surveyOrder }) {
|
||||
my $section = $self->survey->section( $address );
|
||||
# etc..
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
|
|
@ -489,7 +460,6 @@ sub recordResponses {
|
|||
$gotoExpression = $section->{gotoExpression};
|
||||
}
|
||||
|
||||
|
||||
# Handle empty Section..
|
||||
if ( !@questions ) {
|
||||
# No questions to process, so increment lastResponse and return
|
||||
|
|
@ -526,9 +496,22 @@ sub recordResponses {
|
|||
# Pluck the values out of the responses hash that we want to record..
|
||||
my $submittedAnswerResponse = $submittedResponses->{ $answer->{id} };
|
||||
my $submittedAnswerComment = $submittedResponses->{ $answer->{id} . 'comment' };
|
||||
my $submittedAnswerVerbatim = $submittedResponses->{ $answer->{id} . 'verbatim' };
|
||||
|
||||
# Proceed if we're satisfied that the submitted answer response is valid..
|
||||
if ( defined $submittedAnswerResponse && $submittedAnswerResponse =~ /\S/ ) {
|
||||
|
||||
#Validate answers met question criteria
|
||||
if($question->{questionType} eq 'Number'){
|
||||
if($answer->{max} =~ /\d/ and $submittedAnswerResponse > $answer->{max}){
|
||||
next;
|
||||
}elsif($answer->{min} =~ /\d/ and $submittedAnswerResponse < $answer->{min}){
|
||||
next;
|
||||
}elsif($answer->{step} =~ /\d/ and $submittedAnswerResponse % $answer->{step} != 0){
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
$aAnswered = 1;
|
||||
|
||||
# Now, decide what to record. For multi-choice questions, use recordedAnswer.
|
||||
|
|
@ -537,9 +520,10 @@ sub recordResponses {
|
|||
= $knownTypes{ $question->{questionType} }
|
||||
? $submittedAnswerResponse
|
||||
: $answer->{recordedAnswer};
|
||||
|
||||
$self->responses->{ $answer->{id} }->{time} = time;
|
||||
$self->responses->{ $answer->{id} }->{comment} = $submittedAnswerComment;
|
||||
|
||||
$self->responses->{ $answer->{id} }->{verbatim} = $answer->{verbatim} ? $submittedAnswerVerbatim : undef;
|
||||
$self->responses->{ $answer->{id} }->{time} = time;
|
||||
$self->responses->{ $answer->{id} }->{comment} = $submittedAnswerComment;
|
||||
|
||||
# Handle terminal Answers..
|
||||
if ( $answer->{terminal} ) {
|
||||
|
|
@ -609,6 +593,23 @@ A variable name to match against all section and question variable names.
|
|||
sub processGoto {
|
||||
my $self = shift;
|
||||
my ($goto) = validate_pos(@_, {type => SCALAR});
|
||||
|
||||
if ($goto eq 'NEXT_SECTION') {
|
||||
$self->session->log->debug("NEXT_SECTION jump target encountered");
|
||||
my $lastResponseSectionIndex = $self->lastResponseSectionIndex;
|
||||
|
||||
# Increment lastRepsonse until nextResponseSectionIndex moves
|
||||
while ($self->nextResponseSectionIndex == $lastResponseSectionIndex) {
|
||||
$self->lastResponse( $self->lastResponse + 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ($goto eq 'END_SURVEY') {
|
||||
$self->session->log->debug("END_SURVEY jump target encountered");
|
||||
$self->lastResponse( scalar( @{ $self->surveyOrder} ) - 1 );
|
||||
return;
|
||||
}
|
||||
|
||||
# Iterate over items in order..
|
||||
my $itemIndex = 0;
|
||||
|
|
@ -714,17 +715,31 @@ sub recordedResponses{
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 responseValuesByVariableName
|
||||
=head2 responseValuesByVariableName ( $options )
|
||||
|
||||
Returns a lookup table to question variable names and recorded response values.
|
||||
|
||||
Only questions with a defined variable name set are included. Values come from
|
||||
the L<responses> hash.
|
||||
|
||||
=head3 options
|
||||
|
||||
The following options are supported:
|
||||
|
||||
=over 3
|
||||
|
||||
=item * useText
|
||||
|
||||
For multiple choice questions, use the answer text instead of the recorded value
|
||||
(useful for doing [[var]] text substitution
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub responseValuesByVariableName {
|
||||
my $self = shift;
|
||||
my %options = validate(@_, { useText => 0 });
|
||||
|
||||
my %lookup;
|
||||
while (my ($address, $response) = each %{$self->responses}) {
|
||||
|
|
@ -742,14 +757,23 @@ sub responseValuesByVariableName {
|
|||
# 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};
|
||||
my $value = $response->{value};
|
||||
if ($options{useText}) {
|
||||
# Test if question is a multiple choice type so we can use the answer text instead
|
||||
if($self->survey->getMultiChoiceBundle($question->{questionType})){
|
||||
my $answer = $self->survey->answer([@address]);
|
||||
my $answerText = $answer->{text};
|
||||
|
||||
# For verbatim mc answers, combine answer text and recorded value
|
||||
if ($answer->{verbatim}) {
|
||||
$answerText = "$answerText - \"$response->{verbatim}\"";
|
||||
}
|
||||
$value = $answerText ? $answerText : $value;
|
||||
}
|
||||
}
|
||||
|
||||
# Add variable => value to our hash
|
||||
$lookup{$question->{variable}} = $answerText ? $answerText : $response->{value};
|
||||
$lookup{$question->{variable}} = $value;
|
||||
}
|
||||
return \%lookup;
|
||||
}
|
||||
|
|
@ -885,7 +909,7 @@ sub nextQuestions {
|
|||
my $questionsPerPage = $self->survey->section( [ $self->nextResponseSectionIndex ] )->{questionsPerPage};
|
||||
|
||||
# Get all of the existing question responses (so that we can do Section and Question [[var]] replacements
|
||||
my $responseValuesByVariableName = $self->responseValuesByVariableName();
|
||||
my $responseValuesByVariableName = $self->responseValuesByVariableName( { useText => 1 } );
|
||||
|
||||
# Do text replacement
|
||||
$section->{text} = $self->getTemplatedText($section->{text}, $responseValuesByVariableName);
|
||||
|
|
@ -1230,11 +1254,32 @@ sub response {
|
|||
return $self->{_response};
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 responses
|
||||
|
||||
Mutator for the L<"responses"> property.
|
||||
Mutator. Note, this is an unsafe reference.
|
||||
|
||||
Note, this is an unsafe reference.
|
||||
This data structure stores a snapshot of all question responses. Both question data and answer data
|
||||
is stored in this hash reference.
|
||||
|
||||
Questions keys are constructed by hypenating the relevant L<"sIndex"> and L<"qIndex">.
|
||||
Answer keys are constructed by hypenating the relevant L<"sIndex">, L<"qIndex"> and L<aIndex|"aIndexes">.
|
||||
|
||||
{
|
||||
# Question entries only contain a comment field, e.g.
|
||||
'0-0' => {
|
||||
comment => "question comment",
|
||||
},
|
||||
# ...
|
||||
# Answers entries contain: value (the recorded value), time and comment fields.
|
||||
'0-0-0' => {
|
||||
value => "recorded answer value",
|
||||
time => time(),
|
||||
comment => "answer comment",
|
||||
},
|
||||
# ...
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
|
|
@ -1247,6 +1292,62 @@ sub responses {
|
|||
return $self->response->{responses};
|
||||
}
|
||||
|
||||
=head2 pop
|
||||
|
||||
=cut
|
||||
|
||||
sub pop {
|
||||
my $self = shift;
|
||||
my %responses = %{ $self->responses };
|
||||
|
||||
# Iterate over responses first time to determine time of most recent response(s)
|
||||
my $lastResponseTime;
|
||||
for my $r ( values %responses ) {
|
||||
if ( $r->{time} ) {
|
||||
$lastResponseTime
|
||||
= !$lastResponseTime || $r->{time} > $lastResponseTime
|
||||
? $r->{time}
|
||||
: $lastResponseTime
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
return unless $lastResponseTime;
|
||||
|
||||
my $popped;
|
||||
my $poppedQuestions;
|
||||
# Iterate again, removing most recent responses
|
||||
while (my ($address, $r) = each %responses ) {
|
||||
if ( $r->{time} == $lastResponseTime) {
|
||||
$popped->{$address} = $r;
|
||||
delete $self->responses->{$address};
|
||||
|
||||
# Remove associated question/comment entry
|
||||
my ($sIndex, $qIndex, $aIndex) = split /-/, $address;
|
||||
my $qAddress = "$sIndex-$qIndex";
|
||||
$popped->{$qAddress} = $responses{$qAddress};
|
||||
delete $self->responses->{$qAddress};
|
||||
|
||||
# while we're here, build lookup table of popped question ids
|
||||
$poppedQuestions->{$qAddress} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
# Now, nextResponse should be set to index of the first popped question we can find in surveyOrder
|
||||
my $nextResponse = 0;
|
||||
for my $address (@{ $self->surveyOrder }) {
|
||||
my $questionId = "$address->[0]-$address->[1]";
|
||||
if ($poppedQuestions->{$questionId} ) {
|
||||
$self->session->log->debug("setting nextResponse to $nextResponse");
|
||||
$self->nextResponse($nextResponse);
|
||||
last;
|
||||
}
|
||||
$nextResponse++;
|
||||
}
|
||||
|
||||
return $popped;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 survey
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ sub loadTypes {
|
|||
'Slider',
|
||||
'Currency',
|
||||
'Email',
|
||||
'Number',
|
||||
'Phone Number',
|
||||
'Text',
|
||||
'Text Date',
|
||||
|
|
@ -413,16 +414,17 @@ Generates the list of valid goto targets
|
|||
sub getGotoTargets {
|
||||
my $self = shift;
|
||||
|
||||
# Valid goto targets are all of the section variable names..
|
||||
my @section_vars = map {$_->{variable}} @{$self->sections};
|
||||
# Valid goto targets are all of the non-empty section variable names..
|
||||
my @section_vars = grep { $_ ne q{} } map {$_->{variable}} @{$self->sections};
|
||||
|
||||
# ..and all of the question variable names..
|
||||
my @question_vars = map {$_->{variable}} @{$self->questions};
|
||||
# ..and all of the non-empty question variable names..
|
||||
my @question_vars = grep { $_ ne q{} } map {$_->{variable}} @{$self->questions};
|
||||
|
||||
# ..excluding the ones that are empty
|
||||
my @grep = grep { $_ ne q{} } (@section_vars, @question_vars);
|
||||
return \@grep;
|
||||
#return grep { $_ ne q{} } (@section_vars, @question_vars);
|
||||
# ..plus some special vars
|
||||
my @special_vars = qw(NEXT_SECTION END_SURVEY);
|
||||
|
||||
# ..all combined
|
||||
return [ @section_vars, @question_vars, @special_vars ];
|
||||
}
|
||||
|
||||
=head2 getSectionEditVars ( $address )
|
||||
|
|
@ -665,16 +667,32 @@ sub update {
|
|||
}
|
||||
}
|
||||
|
||||
$self->_handleSpecialAnswerUpdates($address,$properties);
|
||||
|
||||
# Update $object with all of the data in $properties
|
||||
while (my ($key, $value) = each %{$properties}) {
|
||||
if (defined $value) {
|
||||
$object->{$key} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub _handleSpecialAnswerUpdates{
|
||||
my $self = shift;
|
||||
my $address = shift;
|
||||
my $properties = shift;
|
||||
my $question = $self->question($address);
|
||||
if($question->{questionType} =~ /^Slider|Multi Slider - Allocate|Dual Slider - Range$/){
|
||||
for my $answer(@{$self->answers($address)}){
|
||||
$answer->{max} = $properties->{max};
|
||||
$answer->{min} = $properties->{min};
|
||||
$answer->{step} = $properties->{step};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
=head2 insertObject ( $object, $address )
|
||||
|
||||
Rearrange existing objects in the current data structure.
|
||||
|
|
@ -1036,10 +1054,9 @@ sub addAnswersToQuestion {
|
|||
# when updating answer text without causing side-effects for the caller's $address
|
||||
my @address_copy = @{$address};
|
||||
|
||||
for my $answer_index ( 0 .. $#{$answers} ) {
|
||||
|
||||
for my $answer (@$answers) {
|
||||
# Add a new answer to question
|
||||
push @{ $self->question( \@address_copy )->{answers} }, $answers->[$answer_index];
|
||||
push @{ $self->question( \@address_copy )->{answers} }, $answer;
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ sub generateFeed {
|
|||
# care of any encoding specified in the XML prolog
|
||||
utf8::downgrade($value, 1);
|
||||
eval {
|
||||
my $singleFeed = XML::FeedPP->new($value, utf8_flag => 1);
|
||||
my $singleFeed = XML::FeedPP->new($value, utf8_flag => 1, -type => 'string');
|
||||
$feed->merge($singleFeed);
|
||||
};
|
||||
if ($@) {
|
||||
|
|
|
|||
|
|
@ -292,19 +292,44 @@ sub duplicate {
|
|||
my $assetId = $self->get("assetId");
|
||||
my $fields;
|
||||
|
||||
my $otherThingFields = $db->buildHashRefOfHashRefs(
|
||||
"select fieldType, fieldId, right(fieldType,22) as otherThingId, fieldInOtherThingId from Thingy_fields
|
||||
where fieldType like 'otherThing_%' and assetId = ?",
|
||||
[$assetId],'fieldInOtherThingId'
|
||||
);
|
||||
|
||||
my $things = $self->getThings;
|
||||
while ( my $thing = $things->hashRef) {
|
||||
my $oldThingId = $thing->{thingId};
|
||||
my $newThingId = $newAsset->addThing($thing,0);
|
||||
my $oldSortBy = $thing->{sortBy};
|
||||
my $oldThingId = $thing->{thingId};
|
||||
my $newThingId = $newAsset->addThing($thing,0);
|
||||
$fields = $db->buildArrayRefOfHashRefs('select * from Thingy_fields where assetId=? and thingId=?'
|
||||
,[$assetId,$oldThingId]);
|
||||
foreach my $field (@$fields) {
|
||||
# set thingId to newly created thing's id.
|
||||
$field->{thingId} = $newThingId;
|
||||
|
||||
my $originalFieldId = $field->{fieldId};
|
||||
|
||||
$newAsset->addField($field,0);
|
||||
my $newFieldId = $newAsset->addField($field,0);
|
||||
if ($originalFieldId eq $oldSortBy){
|
||||
$self->session->db->write( "update Thingy_things set sortBy = ? where thingId = ?",
|
||||
[ $newFieldId, $newThingId ] );
|
||||
}
|
||||
|
||||
if ($otherThingFields->{$originalFieldId}){
|
||||
$otherThingFields->{$originalFieldId}->{newFieldType} = 'otherThing_'.$newThingId;
|
||||
$otherThingFields->{$originalFieldId}->{newFieldId} = $newFieldId;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach my $otherThingField (keys %$otherThingFields){
|
||||
$db->write('update Thingy_fields set fieldType = ?, fieldInOtherThingId = ?
|
||||
where fieldInOtherThingId = ? and assetId = ?',
|
||||
[$otherThingFields->{$otherThingField}->{newFieldType},
|
||||
$otherThingFields->{$otherThingField}->{newFieldId},
|
||||
$otherThingFields->{$otherThingField}->{fieldInOtherThingId}, $newAsset->get('assetId')]);
|
||||
}
|
||||
return $newAsset;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ sub getAlphabetSearchLoop {
|
|||
my $htmlEncodedLetter = encode_entities($letter);
|
||||
my $searchURL = "?searchExact_".$fieldName."=".$letter."%25";
|
||||
my $hasResults;
|
||||
my $users = $self->session->db->read("select userId from userProfileData where lastName like '".$letter."%'");
|
||||
my $users = $self->session->db->read("select userId from userProfileData where `$fieldName` like '".$letter."%'");
|
||||
while (my $user = $users->hashRef){
|
||||
my $showGroupId = $self->get("showGroupId");
|
||||
if ($showGroupId eq '0' || ($showGroupId && $self->isInGroup($showGroupId,$user->{userId}))){
|
||||
|
|
@ -535,7 +535,7 @@ sub view {
|
|||
my $users = $p->getPageData($paginatePage);
|
||||
foreach my $user (@$users){
|
||||
my $userObject = WebGUI::User->new($self->session,$user->{userId});
|
||||
if ($self->get('overridePublicProfile') || $userObject->profileIsViewable($userObject)){
|
||||
if ($self->get('overridePublicProfile') || $userObject->profileIsViewable()) {
|
||||
my (@profileFieldValues);
|
||||
my %userProperties;
|
||||
foreach my $profileField (@profileFields){
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue