Merge remote branch 'main/WebGUI8' into WebGUI8

This commit is contained in:
David Delikat 2011-11-07 17:49:29 +00:00
commit 546932869a
156 changed files with 5488 additions and 582 deletions

View file

@ -1,3 +1,38 @@
7.10.23
- fixed #12225: Stock asset, multiple instances on a page
- fixed #12229: Indexed thingy data has gateway url prepended to it
- fixed #12195: Visitor group by scratch membership shared among all Visitors (Dale Trexel)
- fixed #12227: Corrected AssetReport such that OrderBy works correctly.
- fixed #12238: Old template attachement in search template slows down sites
- fixed #12239: Still get cart error message after removing extra recurring items from the cart
- fixed #12240: Empty Extend Calendar Recurrance version tags
- fixed #12241: Account Shop
- fixed #12246: Layout inherits mobileStyleTemplateId and mobileTemplateId from parent Layouts
- fixed #12246: added extra_www_add_properties as properties fix-up hook in child for www_add
- fixed #12231: Thingy reindex fails on upgrade
- fixed #12245: Encrypt Login and Display Message on Login conflict
- fixed #12211: Recurring Item error message in Cart
7.10.22
- rfe #12223: Add date type to content profiling (metadata)
- rfe #12207: Thingy. Field_name info returned by www_editThingDataSaveViaAjax
- fixed #12206: Bad Subscription Groups in Duplicated Threads
- fixed #12208: replacements don't work
- fixed #12213: Unable to view cart when an asset is deleted.
- added: Better integration between User Profile fields, the Shop address book and the EMS.
- fixed #12218: Failed INSERT in Passive Profiling causes leak
- fixed #12173: CrystalX theme Thingy drop down problem
7.10.21
- added #9668 extension template variable to attachment loops for the following assets:
Article,Post,Event,File,Form::Attachments,Folder
- added WaitForUserConfirmation workflow activity
- added new setting - Enable Users after Anonymous Registration?
- added the optional WebGUI::Content::PDFGenerator, not enabled by default
(see the module's documentation).
- fixed #12204: Default forum notification template produces invalid HTML
- fixed #12202: JsonTable refers to unexistent YUI file
7.10.20
- fixed: Do not call group methods on an undefined value.
- fixed #12178: random deletion of columns may happen when a schema is saved (Amir Plivatsky)
@ -13,6 +48,7 @@
- fixed #12135: Geo::Coder::Googlev3 needs common sense
- fixed #12183: Posts do not disqualify themselves when purged
- fixed #12189: installClass ignores preload.custom
- fixed #12197: Default date Thingy disables date
7.10.19
- fixed #12169: extras uploads symlink export
@ -4224,3 +4260,4 @@
- Made the Include macro more secure.
- Added Len's patch to fix some caching problems.

View file

@ -31,6 +31,16 @@ save you many hours of grief.
Account Macro template
Admin Toggle Macro template
7.10.23
--------------------------------------------------------------------
* The default_search2 template had a bad template attachment pointing to
an old WebGUI CSS Snippet called /webgui.css. Any attachment with that
URL will be removed from ALL templates in the Search namespace.
7.10.21
--------------------------------------------------------------------
* WebGUI now depends on Kwargs.
7.10.17
--------------------------------------------------------------------
* Due to a formatting problem with form variables in the PayPal driver, WebGUI

View file

@ -2,7 +2,7 @@
# WebGUI Legal Information #
####################################################################
WebGUI is Copyright 2001-2009 Plain Black Corporation. All rights
WebGUI is Copyright 2001-2011 Plain Black Corporation. All rights
reserved.
WebGUI Content Engine, WebGUI Runtime Environment, and Plain Black

View file

@ -1,7 +1,7 @@
This is a running list of template changes made during upgrades. If you have copied the default
templates, you will need to apply these changes manually to your copies.
7.8.0
8.0
* Account Macro template variables renamed:
account.url => account_url
@ -11,6 +11,10 @@ templates, you will need to apply these changes manually to your copies.
toggle.url => toggle_url
toggle.text => toggle_text
7.10.22
* Thingy CSS file - root/import/thingy-templates/thingy.css
Add CSS to make sure that overflows are visible, to handle style that hide overflow by default.
7.10.18
* Collaboration System Default Notification Template /default_forum_notification
Replace table with divs to make inline replying easier.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,146 @@
#!/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;
my $toVersion = '7.10.21';
my $quiet; # this line required
my $session = start(); # this line required
addWaitForConfirmationWorkflow($session);
addCreateUsersEnabledSetting($session);
finish($session); # this line required
#----------------------------------------------------------------------------
sub addWaitForConfirmationWorkflow {
my $session = shift;
my $c = $session->config;
my $exists = $c->get('workflowActivities/WebGUI::User');
my $class = 'WebGUI::Workflow::Activity::WaitForUserConfirmation';
unless (grep { $_ eq $class } @$exists) {
print "Adding WaitForUserConfirmation workflow..." unless $quiet;
$c->addToArray('workflowActivities/WebGUI::User' => $class);
print "Done!\n" unless $quiet;
}
}
#----------------------------------------------------------------------------
sub addCreateUsersEnabledSetting {
my $session = shift;
my $s = $session->setting;
my $name = 'enableUsersAfterAnonymousRegistration';
return if $s->has($name);
print "Adding $name setting..." unless $quiet;
$s->add($name => 1);
print "Done!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Describe what our function does
#sub exampleFunction {
# my $session = shift;
# print "\tWe're doing some stuff here that you should know about... " unless $quiet;
# # and here's our code
# print "DONE!\n" unless $quiet;
#}
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
#----------------------------------------------------------------------------
# Add a package to the import node
sub addPackage {
my $session = shift;
my $file = shift;
print "\tUpgrading package $file\n" unless $quiet;
# 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 = eval {
my $node = WebGUI::Asset->getImportNode($session);
$node->importPackage( $storage, {
overwriteLatest => 1,
clearPackageFlag => 1,
setDefaultTemplate => 1,
} );
};
if ($package eq 'corrupt') {
die "Corrupt package found in $file. Stopping upgrade.\n";
}
if ($@ || !defined $package) {
die "Error during package import on $file: $@\nStopping upgrade\n.";
}
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',".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

View file

@ -0,0 +1,198 @@
#!/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;
my $toVersion = '7.10.22';
my $quiet; # this line required
my $session = start(); # this line required
# upgrade functions go here
addAuthorizePaymentDriver($session);
createAddressField($session);
addLinkedProfileAddress($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;
#}
#----------------------------------------------------------------------------
# Add the Authorize.net payment driver to each config file
sub addAuthorizePaymentDriver {
my $session = shift;
print "\tAdd the Authorize.net payment driver... " unless $quiet;
# and here's our code
$session->config->addToArray('paymentDrivers', 'WebGUI::Shop::PayDriver::CreditCard::AuthorizeNet');
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub addLinkedProfileAddress {
my $session = shift;
print "\tAdding linked profile addresses for existing users... " unless $quiet;
my $users = $session->db->buildArrayRef( q{
select userId from users where userId not in ('1','3')
} );
foreach my $userId (@$users) {
#check to see if there is user profile information available
my $u = WebGUI::User->new($session,$userId);
#skip if user does not have any homeAddress fields filled in
next unless (
$u->profileField("homeAddress")
|| $u->profileField("homeCity")
|| $u->profileField("homeState")
|| $u->profileField("homeZip")
|| $u->profileField("homeCountry")
|| $u->profileField("homePhone")
);
#Get the address book for the user (one is created if it does not exist)
my $addressBook = WebGUI::Shop::AddressBook->newByUserId($session,$userId);
#Add the profile address for the user
$addressBook->addAddress({
label => "Profile Address",
firstName => $u->profileField("firstName"),
lastName => $u->profileField("lastName"),
address1 => $u->profileField("homeAddress"),
city => $u->profileField("homeCity"),
state => $u->profileField("homeState"),
country => $u->profileField("homeCountry"),
code => $u->profileField("homeZip"),
phoneNumber => $u->profileField("homePhone"),
email => $u->profileField("email"),
isProfile => 1,
});
}
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub createAddressField {
my $session = shift;
#skip if field exists
my $columns = $session->db->buildArrayRef("show columns from address where Field='isProfile'");
return if(scalar(@$columns));
print "\tAdding profile link to Address... " unless $quiet;
$session->db->write( q{
alter table address add isProfile tinyint default 0
} );
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;
print "\tUpgrading package $file\n" unless $quiet;
# 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 = eval {
my $node = WebGUI::Asset->getImportNode($session);
$node->importPackage( $storage, {
overwriteLatest => 1,
clearPackageFlag => 1,
setDefaultTemplate => 1,
} );
};
if ($package eq 'corrupt') {
die "Corrupt package found in $file. Stopping upgrade.\n";
}
if ($@ || !defined $package) {
die "Error during package import on $file: $@\nStopping upgrade\n.";
}
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',".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

View file

@ -0,0 +1,141 @@
#!/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;
my $toVersion = '7.10.23';
my $quiet; # this line required
my $session = start(); # this line required
# upgrade functions go here
fixBadTemplateAttachments($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 fixBadTemplateAttachments {
my $session = shift;
print "\tRemove template attachements in search templates that refer to an old, deleted CSS snippet... " unless $quiet;
# and here's our code
use WebGUI::Asset::Template;
my $get_template = WebGUI::Asset::Template->getIsa($session);
TEMPLATE: while (1) {
my $template = eval {$get_template->()};
next TEMPLATE if Exception::Class->caught;
last TEMPLATE unless $template;
next TEMPLATE unless $template->get('namespace') eq 'Search';
$template->removeAttachments(['^/(webgui.css);']);
}
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;
print "\tUpgrading package $file\n" unless $quiet;
# 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 = eval {
my $node = WebGUI::Asset->getImportNode($session);
$node->importPackage( $storage, {
overwriteLatest => 1,
clearPackageFlag => 1,
setDefaultTemplate => 1,
} );
};
if ($package eq 'corrupt') {
die "Corrupt package found in $file. Stopping upgrade.\n";
}
if ($@ || !defined $package) {
die "Error during package import on $file: $@\nStopping upgrade\n.";
}
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',".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

View file

@ -0,0 +1,561 @@
#!/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;
my $toVersion = "0.0.0"; # make this match what version you're going to
my $quiet; # this line required
my $session = start(); # this line required
# upgrade functions go here
i18nForAddonsTitle($session);
addForkTable($session);
installForkCleanup($session);
addVersioningToMetadata($session);
installNewDashboardTables($session);
addStockDataCacheColumn($session);
addWeatherDataCacheColumn($session);
addLastModifiedByMacro($session);
addAutoPlayToCarousel( $session );
addProcessorDropdownToSnippet( $session );
addRichEditToCarousel($session);
alterAssetIndexTable($session);
reindexAllThingys($session);
use WebGUI::Asset::MapPoint;
WebGUI::AssetAspect::Installable::upgrade("WebGUI::Asset::MapPoint",$session);
addRenderThingDataMacro($session);
addAssetPropertyMacro($session);
createThingyDBColumns($session);
addAssetManagerSortPreferences($session);
addTicketLimitToBadgeGroup( $session );
addFormFieldMacroToConfig();
addWaitForConfirmationWorkflow($session);
addCreateUsersEnabledSetting($session);
addAuthorizePaymentDriver($session);
createAddressField($session);
addLinkedProfileAddress($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;
#}
#----------------------------------------------------------------------------
# This internationalizes the link text of the addons link in the adminconsole
sub i18nForAddonsTitle {
my $session = shift;
print "\tInternationalize the text of the addons link in the adminconsole... " unless $quiet;
$session->config->set('adminConsole/addons',
{
icon => "addons.png",
uiLevel => 1,
group => "12",
url => "http://www.webgui.org/addons",
title => "^International(Addons title,WebGUI);"
}
);
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Creates a new table for tracking background processes
sub addForkTable {
my $session = shift;
my $db = $session->db;
my $sth = $db->dbh->table_info('', '', 'Fork', 'TABLE');
return if ($sth->fetch);
print "\tAdding Fork table..." unless $quiet;
my $sql = q{
CREATE TABLE Fork (
id CHAR(22),
userId CHAR(22),
groupId CHAR(22),
status LONGTEXT,
error TEXT,
startTime BIGINT(20),
endTime BIGINT(20),
finished BOOLEAN DEFAULT FALSE,
latch BOOLEAN DEFAULT FALSE,
PRIMARY KEY(id)
);
};
$db->write($sql);
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# install a workflow to clean up old background processes
sub installForkCleanup {
my $session = shift;
print "\tInstalling Fork Cleanup workflow..." unless $quiet;
my $class = 'WebGUI::Workflow::Activity::RemoveOldForks';
$session->config->addToArray('workflowActivities/None', $class);
my $wf = WebGUI::Workflow->new($session, 'pbworkflow000000000001');
use List::Util qw/first/;
my $a = first { ref $_ eq $class } @{ $wf->getActivities };
unless ($a) {
$a = $wf->addActivity($class);
$a->set(title => 'Remove Old Forks');
};
print "DONE!\n" unless $quiet;
}
sub addVersioningToMetadata {
my $session = shift;
print "\tAltering metadata tables for versioning..." unless $quiet;
my $db = $session->db;
$db->write(q{
alter table metaData_values
add column revisionDate bigint,
drop primary key,
add primary key (fieldId, assetId, revisionDate);
});
$db->write(q{
create table metaData_classes (
className char(255),
fieldId char(22)
);
});
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Describe what our function does
sub addLastModifiedByMacro {
my $session = shift;
print "\tAdd LastModifiedBy macro to the config file... " unless $quiet;
# and here's our code
$session->config->addToHash('macros', 'LastModifiedBy', 'LastModifiedBy');
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Describe what our function does
sub installNewDashboardTables {
my $session = shift;
print "\tInstall new Dashboard tables... " unless $quiet;
$session->db->write(<<EOSQL);
CREATE TABLE IF NOT EXISTS Dashboard_dashlets (
dashboardAssetId CHAR(22) BINARY,
dashletAssetId CHAR(22) BINARY,
isStatic BOOLEAN,
isRequired BOOLEAN,
PRIMARY KEY (dashboardAssetId, dashletAssetId)
) TYPE=MyISAM CHARSET=utf8;
EOSQL
$session->db->write(<<EOSQL);
CREATE TABLE IF NOT EXISTS Dashboard_userPrefs (
dashboardAssetId CHAR(22) BINARY,
dashletAssetId CHAR(22) BINARY,
userId CHAR(22) BINARY,
isMinimized BOOLEAN,
properties LONGTEXT,
PRIMARY KEY (dashboardAssetId, dashletAssetId, userId)
) TYPE=MyISAM CHARSET=utf8;
EOSQL
# and here's our code
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Describe what our function does
sub addStockDataCacheColumn {
my $session = shift;
print "\tAdd cache column for the StockData asset... " unless $quiet;
$session->db->write(<<EOSQL);
ALTER TABLE StockData ADD COLUMN cacheTimeout BIGINT
EOSQL
# and here's our code
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Describe what our function does
sub addWeatherDataCacheColumn {
my $session = shift;
print "\tAdd cache column for the WeatherData asset... " unless $quiet;
$session->db->write(<<EOSQL);
ALTER TABLE WeatherData ADD COLUMN cacheTimeout BIGINT
EOSQL
# and here's our code
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Add AutoPlay fields to the Carousel
sub addAutoPlayToCarousel {
my $session = shift;
print "\tAdding Auto Play to Carousel... " unless $quiet;
$session->db->write(
"ALTER TABLE Carousel ADD COLUMN autoPlay INT, ADD COLUMN autoPlayInterval INT"
);
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub addProcessorDropdownToSnippet {
my $session = shift;
my $db = $session->db;
print "\tUpdating the Snippet table to add templateProcessor option..."
unless $quiet;
my $rows = $db->buildArrayRefOfHashRefs(q{
select assetId, revisionDate from snippet where processAsTemplate = 1
});
$db->write(q{
alter table snippet
drop column processAsTemplate,
add column templateParser char(255)
});
my $default = $session->config->get('defaultTemplateParser');
for my $row (@$rows) {
$db->write(q{
update snippet
set templateParser = ?
where assetId = ? and revisionDate = ?
}, [ $default, $row->{assetId}, $row->{revisionDate} ]);
}
print "Done!\n";
}
#----------------------------------------------------------------------------
# Describe what our function does
sub addRichEditToCarousel {
my $session = shift;
print "\tAdd RichEdit option to the Carousel... " unless $quiet;
# and here's our code
$session->db->write('ALTER TABLE Carousel ADD COLUMN richEditor CHAR(22) BINARY');
$session->db->write(q!update Carousel set richEditor='PBrichedit000000000001'!);
print "DONE!\n" unless $quiet;
}
sub addRenderThingDataMacro {
my $session = shift;
print "\tAdd the new RenderThingData macro to the site config... " unless $quiet;
$session->config->addToHash('macros', 'RenderThingData', 'RenderThingData');
print "DONE!\n" unless $quiet;
}
sub alterAssetIndexTable {
my $session = shift;
print "\tExtend the assetIndex table so we can search things other than assets... " unless $quiet;
$session->db->write(<<EOSQL);
alter table assetIndex
drop primary key,
add column subId char(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
add primary key (assetId, url)
EOSQL
print "DONE!\n" unless $quiet;
}
sub reindexAllThingys {
my $session = shift;
print "\tReindex all Thingys... " unless $quiet;
use WebGUI::Asset::Wobject::Thingy;
my $get_thingy = WebGUI::Asset::Wobject::Thingy->getIsa($session);
THINGY: while (1) {
my $thingy = eval { $get_thingy->() };
next THINGY if Exception::Class->caught();
last THINGY unless $thingy;
$thingy->indexContent;
}
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub addAssetPropertyMacro {
my $session = shift;
my $c = $session->config;
my $hash = $c->get('macros');
unless (grep { $_ eq 'AssetProperty' } values %$hash) {
print "\tAdding AssetProperty macro... " unless $quiet;
$c->set('macros/AssetProperty' => 'AssetProperty');
print "DONE!\n" unless $quiet;
}
}
#----------------------------------------------------------------------------
# Creates new column in tables for Thingy_fields and Thingy_things
sub createThingyDBColumns {
my $session = shift;
print "\tAdding db. columns Thingy_fields.isUnique and Thingy_things.maxEntriesTotal.." unless $quiet;
# and here's our code
my %tfHash = $session->db->quickHash("show columns from Thingy_fields where Field='isUnique'");
my %ttHash = $session->db->quickHash("show columns from Thingy_things where Field='maxEntriesTotal'");
unless ( $tfHash{'Field'}) { $session->db->write("alter table Thingy_fields add isUnique int(1) default 0"); }
unless ( $ttHash{'Field'}) { $session->db->write("alter table Thingy_things add maxEntriesTotal int default null"); }
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub addAssetManagerSortPreferences {
my $cn = 'assetManagerSortColumn';
my $on = 'assetManagerSortDirection';
use WebGUI::ProfileField;
unless (WebGUI::ProfileField->new($session, $cn)) {
print 'Adding Asset Manager Sort Column profile field...'
unless $quiet;
WebGUI::ProfileField->create($session, $cn => {
label =>
"WebGUI::International::get('$cn label', 'Account_Profile')",
protected => 1,
fieldType => 'selectBox',
dataDefault => 'lineage',
possibleValues => <<'VALUES',
{
lineage => WebGUI::International::get('rank', 'Asset'),
title => WebGUI::International::get(99, 'Asset'),
className => WebGUI::International::get('type', 'Asset'),
revisionDate => WebGUI::International::get('revision date', 'Asset'),
assetSize => WebGUI::International::get('size', 'Asset'),
lockedBy => WebGUI::International::get('locked', 'Asset'),
}
VALUES
}, 4);
print "Done!\n" unless $quiet;
}
unless (WebGUI::ProfileField->new($session, $on)) {
print 'Adding Asset Manager Sort Direction profile field...'
unless $quiet;
WebGUI::ProfileField->create($session, $on => {
label =>
"WebGUI::International::get('$on label', 'Account_Profile')",
protected => 1,
fieldType => 'selectBox',
dataDefault => 'asc',
possibleValues => <<'VALUES',
{
asc => WebGUI::International::get('ascending', 'Account_Profile'),
desc => WebGUI::International::get('descending', 'Account_Profile'),
}
VALUES
}, 4);
print "Done!\n" unless $quiet;
}
}
#----------------------------------------------------------------------------
# Add a ticket limit to badges in a badge group
sub addTicketLimitToBadgeGroup {
my $session = shift;
print "\tAdd ticket limit to badge groups... " unless $quiet;
# Make sure it hasn't been done already...
my $columns = $session->db->buildHashRef('describe EMSBadgeGroup');
if(! grep { /ticketsPerBadge/ } keys %{$columns}) {
$session->db->write(q{
ALTER TABLE EMSBadgeGroup ADD COLUMN `ticketsPerBadge` INTEGER
});
}
print "DONE!\n" unless $quiet;
}
sub addFormFieldMacroToConfig {
print "\tAdd FormField macro to config... " unless $quiet;
$session->config->addToHash( 'macros', FormField => 'FormField' );
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub addWaitForConfirmationWorkflow {
my $session = shift;
my $c = $session->config;
my $exists = $c->get('workflowActivities/WebGUI::User');
my $class = 'WebGUI::Workflow::Activity::WaitForUserConfirmation';
unless (grep { $_ eq $class } @$exists) {
print "Adding WaitForUserConfirmation workflow..." unless $quiet;
$c->addToArray('workflowActivities/WebGUI::User' => $class);
print "Done!\n" unless $quiet;
}
}
#----------------------------------------------------------------------------
sub addCreateUsersEnabledSetting {
my $session = shift;
my $s = $session->setting;
my $name = 'enableUsersAfterAnonymousRegistration';
return if $s->has($name);
print "Adding $name setting..." unless $quiet;
$s->add($name => 1);
print "Done!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# Add the Authorize.net payment driver to each config file
sub addAuthorizePaymentDriver {
my $session = shift;
print "\tAdd the Authorize.net payment driver... " unless $quiet;
# and here's our code
$session->config->addToArray('paymentDrivers', 'WebGUI::Shop::PayDriver::CreditCard::AuthorizeNet');
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub addLinkedProfileAddress {
my $session = shift;
print "\tAdding linked profile addresses for existing users... " unless $quiet;
my $users = $session->db->buildArrayRef( q{
select userId from users where userId not in ('1','3')
} );
use WebGUI::User;
use WebGUI::Shop::AddressBook;
foreach my $userId (@$users) {
#check to see if there is user profile information available
my $u = WebGUI::User->new($session,$userId);
#skip if user does not have any homeAddress fields filled in
next unless (
$u->profileField("homeAddress")
|| $u->profileField("homeCity")
|| $u->profileField("homeState")
|| $u->profileField("homeZip")
|| $u->profileField("homeCountry")
|| $u->profileField("homePhone")
);
#Get the address book for the user (one is created if it does not exist)
my $addressBook = WebGUI::Shop::AddressBook->newByUserId($session,$userId);
#Add the profile address for the user
$addressBook->addAddress({
label => "Profile Address",
firstName => $u->profileField("firstName"),
lastName => $u->profileField("lastName"),
address1 => $u->profileField("homeAddress"),
city => $u->profileField("homeCity"),
state => $u->profileField("homeState"),
country => $u->profileField("homeCountry"),
code => $u->profileField("homeZip"),
phoneNumber => $u->profileField("homePhone"),
email => $u->profileField("email"),
isProfile => 1,
});
}
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub createAddressField {
my $session = shift;
#skip if field exists
my $columns = $session->db->buildArrayRef("show columns from address where Field='isProfile'");
return if(scalar(@$columns));
print "\tAdding profile link to Address... " unless $quiet;
$session->db->write( q{
alter table address add isProfile tinyint default 0
} );
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;
print "\tUpgrading package $file\n" unless $quiet;
# 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 = eval {
my $node = WebGUI::Asset->getImportNode($session);
$node->importPackage( $storage, {
overwriteLatest => 1,
clearPackageFlag => 1,
setDefaultTemplate => 1,
} );
};
if ($package eq 'corrupt') {
die "Corrupt package found in $file. Stopping upgrade.\n";
}
if ($@ || !defined $package) {
die "Error during package import on $file: $@\nStopping upgrade\n.";
}
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',".time().")");
$session->close();
}
#-------------------------------------------------
sub updateTemplates {
my $session = shift;
print "\tUpdating packages.\n" unless ($quiet);
addPackage( $session, 'packages-7.9.34-7.10.22/merged.wgpkg' );
}
#vim:ft=perl

View file

@ -218,6 +218,7 @@
"WebGUI::Shop::PayDriver::ITransact",
"WebGUI::Shop::PayDriver::PayPal::PayPalStd",
"WebGUI::Shop::PayDriver::PayPal::ExpressCheckout",
"WebGUI::Shop::PayDriver::CreditCard::AuthorizeNet",
"WebGUI::Shop::PayDriver::Ogone"
],
@ -871,6 +872,7 @@
"r" : "r_printable",
"Spacer" : "Spacer",
"SpectreCheck" : "SpectreCheck",
"TwitterLogin" : "TwitterLogin",
"Thumbnail" : "Thumbnail",
"TwitterLogin" : "TwitterLogin",
"User" : "User",
@ -945,6 +947,7 @@
"WebGUI::Workflow::Activity::NotifyAboutUser",
"WebGUI::Workflow::Activity::ActivateUser",
"WebGUI::Workflow::Activity::DeactivateUser",
"WebGUI::Workflow::Activity::WaitForUserConfirmation",
"WebGUI::Workflow::Activity::DeleteUser"
],
"WebGUI::VersionTag" : [

View file

@ -1,10 +1,8 @@
package WebGUI;
our $VERSION = '8.0.0';
our $STATUS = 'beta';
=head1 LEGAL
-------------------------------------------------------------------

View file

@ -21,7 +21,7 @@ has method => (
has uid => (
is => 'rw',
default => 'view',
default => '',
);
has bare => (

View file

@ -7,6 +7,7 @@ use WebGUI::International;
use WebGUI::Pluggable;
use WebGUI::ProfileCategory;
use WebGUI::ProfileField;
use WebGUI::Shop::AddressBook;
use base qw/WebGUI::Account/;
=head1 NAME
@ -431,16 +432,65 @@ sub www_editSave {
unless(scalar(@{$retHash->{errors}})) {
my $profile = $retHash->{profile};
my $privacy = {};
$session->user->update($profile);
my $address = {};
my $address_mappings = WebGUI::Shop::AddressBook->getProfileAddressMappings;
foreach my $fieldName (keys %{$profile}) {
#set the shop address fields
my $address_key = $address_mappings->{$fieldName};
$address->{$address_key} = $profile->{ $fieldName } if ($address_key);
#set the privacy settings
my $privacySetting = $session->form->get("privacy_".$fieldName);
next unless $privacySetting;
$privacy->{$fieldName} = $privacySetting;
}
$session->user->setProfileFieldPrivacySetting($privacy);
#Update or create and update the shop address
if ( keys %$address ) {
$address->{'isProfile' } = 1;
#Get the address book for the user (one is created if it does not exist)
my $addressBook = WebGUI::Shop::AddressBook->newByUserId($session,$self->uid);
my $profileAddress = eval { $addressBook->getProfileAddress() };
my $e;
if($e = WebGUI::Error->caught('WebGUI::Error::ObjectNotFound')) {
#Get home address only mappings to avoid creating addresses with just firstName, lastName, email
my %home_address_map = %{$address_mappings};
delete $home_address_map{qw/firstName lastName email/};
#Add the profile address for the user if there are homeAddress fields
if( grep { $address->{$_} } values %home_address_map ) {
$address->{label} = "Profile Address";
my $new_address = $addressBook->addAddress($address);
#Set this as the default address if one doesn't already exist
my $defaultAddress = eval{ $addressBook->getDefaultAddress };
if(WebGUI::Error->caught('WebGUI::Error::ObjectNotFound')) {
$addressBook->update( {
defaultAddressId => $new_address->getId
} );
}
}
}
elsif ($e = WebGUI::Error->caught) {
#Bad stuff happened - log an error but don't fail since this isn't a vital function
$session->log->error(
q{Could not update Shop Profile Address for user }
.$self->username.q{ : }.$e->error
);
}
else {
#Update the profile address for the user
$profileAddress->update($address);
}
}
}
#Store the category the error occurred in the object for reference
$self->store->{selected} = $retHash->{errorCategory};

View file

@ -1126,10 +1126,12 @@ sub getEditForm {
###
# Properties
my $overrides = $session->config->get("assets/".$self->className) || {};
foreach my $property ( $self->getProperties ) {
my $fieldHash = $self->getFieldData( $property );
next if $fieldHash->{noFormPost};
$fieldHash = $self->setupFormField($property, $fieldHash, $overrides);
# Create tabs to have labels added later
if ( !$f->getTab( $fieldHash->{tab} ) ) {
$f->addTab( name => $fieldHash->{tab}, label => $fieldHash->{tab} );
@ -1167,22 +1169,37 @@ sub getEditForm {
return $f;
} ## end sub getEditForm
=head2 setupFormField ( $fieldName, $fieldHash, $overrides )
Applies overrides from the WebGUI config file to a set of field data. The overridden
and updated field data is returned.
=head3 $fieldName
The name of the field.
=head3 $fieldHash
A hash reference of field data for $fieldName.
=head3 $overrides
A hash reference of overrides from the config file. This is passed in instead of
looking it up each time as a speed optimization.
=cut
sub setupFormField {
my ( $self, $tabform, $fieldName, $extraFields, $overrides ) = @_;
my %params = %{ $extraFields->{$fieldName} };
my $tab = delete $params{tab};
my ( $self, $fieldName, $fieldHash, $overrides ) = @_;
if ( exists $overrides->{fields}{$fieldName} ) {
my %overrideParams = %{ $overrides->{fields}{$fieldName} };
my $overrideTab = delete $overrideParams{tab};
$tab = $overrideTab if defined $overrideTab;
foreach my $key ( keys %overrideParams ) {
$params{"-$key"} = $overrideParams{$key};
}
return $fieldHash unless exists $overrides->{fields}->{$fieldName};
my %overrideParams = %{ $overrides->{fields}->{$fieldName} };
foreach my $key ( keys %overrideParams ) {
(my $canon = $key) =~ s/^-//;
$fieldHash->{$canon} = $overrideParams{$key};
}
return $fieldHash;
$tab ||= 'properties';
return $tabform->getTab($tab)->addField( delete $params{fieldType}, %params);
} ## end sub setupFormField
#-------------------------------------------------------------------
@ -1259,9 +1276,13 @@ sub getFieldData {
my $attr = $self->meta->find_attribute_by_name( $property );
my $fieldType = $attr->fieldType;
my $fieldOverrides = $overrides->{ $property } || {};
my $noFormPost = $attr->noFormPost;
if (ref $noFormPost eq 'CODE') {
$noFormPost = $self->$noFormPost;
}
my $fieldHash = {
fieldType => $fieldType,
noFormPost => $attr->noFormPost,
noFormPost => $noFormPost,
tab => "properties",
%{ $self->getFormProperties( $property ) },
%{ $overrides },
@ -1410,6 +1431,28 @@ sub getImportNode {
return WebGUI::Asset->newById($session, "PBasset000000000000002");
}
#-------------------------------------------------------------------
=head2 getInheritableProperties ( )
Returns a hash (list) of properties that should be inherited from a parent when creating an asset.
=cut
sub getInheritableProperties {
my $self = shift;
return (
parentId => $self->getId,
groupIdView => $self->get("groupIdView"),
groupIdEdit => $self->get("groupIdEdit"),
ownerUserId => $self->get("ownerUserId"),
encryptPage => $self->get("encryptPage"),
styleTemplateId => $self->get("styleTemplateId"),
printableStyleTemplateId => $self->get("printableStyleTemplateId"),
isHidden => $self->get("isHidden"),
);
}
#-------------------------------------------------------------------
@ -1839,6 +1882,7 @@ exception.
sub loadModule {
my ($class, $className) = @_;
if ($className !~ /^WebGUI::Asset(?:::\w+)*$/ ) {
warn $className;
WebGUI::Error::InvalidParam->throw(param => $className, error => "Not a WebGUI::Asset class",);
}
(my $module = $className . '.pm') =~ s{::}{/}g;
@ -2732,15 +2776,8 @@ sub www_add {
}
my %properties = (
%prototypeProperties,
parentId => $self->getId,
groupIdView => $self->get("groupIdView"),
groupIdEdit => $self->get("groupIdEdit"),
ownerUserId => $self->get("ownerUserId"),
encryptPage => $self->get("encryptPage"),
styleTemplateId => $self->get("styleTemplateId"),
printableStyleTemplateId => $self->get("printableStyleTemplateId"),
isHidden => $self->get("isHidden"),
className=>$class,
$self->getInheritableProperties,
assetId=>"new",
url=>scalar($self->session->form->param("url")),
);

View file

@ -1289,6 +1289,7 @@ sub getTemplateVars {
url => $storage->getUrl($filename),
icon => $storage->getFileIconUrl($filename),
filename => $filename,
extension => WebGUI::Storage->getFileExtension($filename),
thumbnail => $storage->getThumbnailUrl($filename),
isImage => $storage->isImage($filename),
};

View file

@ -622,6 +622,7 @@ sub view {
$var{fileUrl} = $self->getFileUrl;
$var{fileIcon} = $self->getFileIconUrl;
$var{fileSize} = Number::Format::format_bytes($self->get("assetSize"));
$var{extension} = WebGUI::Storage->getFileExtension( $self->get("filename"));
my $out = $self->processTemplate(\%var,undef,$self->{_viewTemplate});
if (!$self->session->isAdminOn && $self->get("cacheTimeout") > 10) {
$self->session->cache->set($self->getViewCacheKey, $out, $self->get("cacheTimeout"));

View file

@ -1092,6 +1092,7 @@ sub getTemplateVars {
url => $fileUrl,
icon => $storage->getFileIconUrl($filename),
filename => $filename,
extension => WebGUI::Storage->getFileExtension($filename),
thumbnail => $isImage ? $storage->getThumbnailUrl($filename) : '',
isImage => $isImage,
});

View file

@ -257,15 +257,17 @@ sub duplicate {
my $self = shift;
my $session = $self->session;
my $copy = $self->SUPER::duplicate(@_);
my $oldGroupId = $self->get('subscriptionGroupId');
my $key = 'subscriptionGroupId';
my $oldGroupId = $self->get($key);
if ($oldGroupId) {
my $newGroup = WebGUI::Group->new($session, 'new');
my $oldGroup = WebGUI::Group->new($session, $oldGroupId);
if ($oldGroup) {
$copy->update({ $key => '' });
$copy->createSubscriptionGroup();
if (my $oldGroup = WebGUI::Group->new($session, $oldGroupId)) {
my $newGroup = WebGUI::Group->new($session, $copy->get($key));
$newGroup->addUsers($oldGroup->getUsers('withoutExpired'));
$newGroup->addGroups($oldGroup->getGroupsIn);
}
$copy->update({subscriptionGroupId => $newGroup->getId});
}
return $copy;
}

View file

@ -592,6 +592,22 @@ sub processStyle {
#-------------------------------------------------------------------
=head2 purge ( )
Extent the base class to clean out any items using this Sku in all Carts.
=cut
sub purge {
my $self = shift;
my $assetId = $self->getId;
my $success = $self->SUPER::purge;
return $success unless $success;
$self->session->db->write('delete from cartItem where assetId=?',[$assetId]);
}
#-------------------------------------------------------------------
=head2 setTaxConfiguration ($namespace, $configuration)
=head3 $namespace

View file

@ -83,6 +83,7 @@ property templateId => (
use JSON;
use WebGUI::International;
use WebGUI::Shop::Admin;
use WebGUI::Shop::AddressBook;
=head1 NAME
@ -204,6 +205,28 @@ sub getMaxAllowedInCart {
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();
if($self->getParent->isRegistrationStaff) {
my $i18n = WebGUI::International->new( $session, "Asset_EventManagementSystem" );
my $badgeId = $item->get('options')->{badgeId};
$opts->{ $i18n->get('print') } = $self->getParent->getUrl( "func=printBadge;badgeId=$badgeId" );
}
return $opts;
}
#-------------------------------------------------------------------
=head2 getPrice
@ -404,11 +427,19 @@ sub view {
;
# instanciate address
my $address = WebGUI::Shop::AddressBook->newByUserId($self->session)->getAddress($form->get("addressId")) if ($form->get("addressId"));
my $address = undef;
my $address_book = WebGUI::Shop::AddressBook->newByUserId($self->session);
if ($form->get("addressId")) {
$address = $address_book->getAddress($form->get("addressId"));
}
else {
$address = eval{ $address_book->getDefaultAddress }
}
# build the form that the user needs to fill out with badge holder information
$vars{formHeader} = WebGUI::Form::formHeader($session, {action => $self->getUrl})
. WebGUI::Form::hidden($session, {name=>"func", value =>'addToCart'});
. WebGUI::Form::hidden($session, {name=>"func", value =>'addToCart'})
. WebGUI::Form::hidden($session, {name=>"addressId", value=>(defined $address ? $address->getId : "" )});;
$vars{formFooter} = WebGUI::Form::formFooter($session);
$vars{name} = WebGUI::Form::text($session, {
name => 'name',
@ -457,9 +488,21 @@ sub view {
if($self->getQuantityAvailable() > 0){
$vars{submitAddress} = WebGUI::Form::submit($session, {value => $i18n->get('add to cart'),});
}
$vars{resetButton} = q{<input type="button" value="}.$i18n->get('clear form'). q{" onclick="WebGUI.Form.clearForm(this.form)" />};
$vars{title} = $self->getTitle;
$vars{description} = $self->description;
$vars{search_url } = $self->getUrl("shop=address;method=ajaxSearch");
my $shopAdmin = WebGUI::Shop::Admin->new($session);
my $isStaff = $self->getParent->isRegistrationStaff;
my $canManageShop = $shopAdmin->canManage;
my $isCashier = $shopAdmin->isCashier;
if($isStaff && ($canManageShop || $isCashier)) {
$vars{canSearch} = 1;
}
# render the page;
return $self->processTemplate(\%vars, undef, $self->{_viewTemplate});
}
@ -495,13 +538,46 @@ sub www_addToCart {
if ($badgeInfo{name} eq "") {
$error = sprintf $i18n->get('is required'), $i18n->get('name','Shop');
}
# return them back to the previous screen if they messed up
if ($error) {
$self->{_errorMessage} = $error;
return $self->www_view($error);
}
#check to see if address has changed - if so, create a new address and set it to the default
my $address_id = $form->get("addressId");
if($address_id) {
my $address = undef;
my $address_book = WebGUI::Shop::AddressBook->newByUserId($self->session);
$address = $address_book->getAddress($address_id);
my $has_changes = 0;
my $new_address = {};
foreach my $field_name (qw/name address1 address2 address3 city state country code phoneNumber organization email/) {
my $form_field_name = $field_name;
$form_field_name = "zipcode" if ($field_name eq "code");
if($field_name eq "name") {
if($address->get('firstName')." ".$address->get('lastName') ne $badgeInfo{name}) {
$has_changes = 1;
}
($new_address->{firstName},$new_address->{lastName}) = split(" ",$badgeInfo{name});
next;
}
elsif($address->get($field_name) ne $badgeInfo{$form_field_name}) {
$has_changes = 1;
}
$new_address->{$field_name} = $badgeInfo{$form_field_name};
}
if($has_changes) {
my $address_book = WebGUI::Shop::AddressBook->newByUserId($self->session);
$new_address->{label} = $form->get("label")." New";
my $new_address = $address_book->addAddress($new_address);
$address_book->update({defaultAddressId => $new_address->getId });
}
}
# add it to the cart
$self->addToCart(\%badgeInfo);
return $self->getParent->www_buildBadge($self->getOptions->{badgeId});

View file

@ -637,15 +637,15 @@ sub prepare {
$style->setRawHeadTags($headBlock);
my %props = ( type => 'text/css', rel => 'stylesheet' );
foreach my $sheet ( @{ $self->getAttachments('stylesheet') } ) {
my %props = ( type => 'text/css', rel => 'stylesheet' );
$style->setLink($sheet->{url}, \%props);
}
my $doScripts = sub {
my ($type, $body) = @_;
my %props = ( type => 'text/javascript' );
foreach my $script ( @{ $self->getAttachments($type) } ) {
my %props = ( type => 'text/javascript' );
$style->setScript($script->{url}, \%props, $body);
}
};
@ -1076,8 +1076,8 @@ sub www_preview {
my $session = $self->session;
return $session->privilege->insufficient unless $self->canEdit;
my $form = $session->form;
my $http = $session->http;
my $form = $session->form;
my $response = $session->response;
try {
my $output = $self->processRaw(
@ -1087,14 +1087,14 @@ sub www_preview {
$form->get('parser'),
);
if ($form->get('plainText')) {
$http->setMimeType('text/plain');
$response->content_type('text/plain');
}
elsif ($output !~ /<html>/) {
$output = $session->style->userStyle($output);
}
return $output;
} catch {
$http->setMimeType('text/plain');
$response->content_type('text/plain');
$_[0];
}
}

View file

@ -226,6 +226,21 @@ sub getCollateral {
}
#-------------------------------------------------------------------
=head2 getInheritableProperties ( )
Extend the base class to include the mobileStyleTemplateId.
=cut
override getInheritableProperties => sub {
my $self = shift;
my %properties = super();
$properties{mobileStyleTemplateId} = $self->mobileStyleTemplateId;
return %properties;
};
#-------------------------------------------------------------------
=head2 getStyleTemplateId

View file

@ -340,6 +340,7 @@ sub view {
}
push(@{$var{attachment_loop}}, {
filename => $file,
extension => WebGUI::Storage->getFileExtension($file),
isImage => $storage->isImage($file),
url=> $storage->getUrl($file),
thumbnailUrl => $storage->getThumbnailUrl($file),

View file

@ -139,9 +139,8 @@ sub getTemplateVars {
$rules->{'whereClause'} .= qq{$prop $op $value};
}
if($rules->{'whereClause'}) {
$rules->{'joinClass'} = $settings->{className};
}
# Always join to the class, asset and assetData are excluded by getLineageSql
$rules->{'joinClass'} = $settings->{className};
#Build the order by condition
my $order = $settings->{order};

View file

@ -1383,7 +1383,7 @@ around groupIdView => sub {
my $instance_data = {
workflowId => 'xR-_GRRbjBojgLsFx3dEMA',
className => 'WebGUI::Asset',
methodName => 'newById',
methodName => 'newPending',
parameters => $self->getId,
};
my $instance = WebGUI::Workflow::Instance->create($self->session, $instance_data);

View file

@ -2590,9 +2590,10 @@ sub www_printBadge {
my $self = shift;
my $session = $self->session;
return $session->privilege->insufficient unless ($self->isRegistrationStaff);
my $form = $session->form;
my $registrant = $self->getRegistrant($form->get('badgeId'));
my $badge = WebGUI::Asset::Sku::EMSBadge->newById($session, $registrant->{badgeAssetId});
my $form = $session->form;
my $badgeId = $form->get('badgeId');
my $registrant = $self->getRegistrant($badgeId);
my $badge = WebGUI::Asset::Sku::EMSBadge->newById($session, $registrant->{badgeAssetId});
$registrant->{badgeTitle} = $badge->getTitle;
# Add badge metadata
@ -2601,6 +2602,42 @@ sub www_printBadge {
$registrant->{ "badgeMeta_" . $key } = $meta->{ $key };
}
#Add tickets
my @tickets = $session->db->buildArray(
q{select ticketAssetId from EMSRegistrantTicket where badgeId=?},
[$badgeId]
);
$registrant->{ticket_loop} = [];
foreach my $ticketId (@tickets) {
my $ticket = WebGUI::Asset::Sku::EMSTicket->newById($session, $ticketId);
push (@{$registrant->{ticket_loop}}, $ticket->get);
}
#Add ribbons
my @ribbons = $session->db->buildArray(
q{select ribbonAssetId from EMSRegistrantRibbon where badgeId=?},
[$badgeId]
);
$registrant->{ribbon_loop} = [];
foreach my $ribbonId (@ribbons) {
my $ribbon = WebGUI::Asset::Sku::EMSRibbon->newById($session, $ribbonId);
push (@{$registrant->{ribbon_loop}}, $ribbon->get);
}
## Add tokens
my @tokens = $session->db->buildArray(
q{select tokenAssetId from EMSRegistrantToken where badgeId=?},
[$badgeId]
);
$registrant->{token_loop} = [];
foreach my $tokenId (@tokens) {
my $token = WebGUI::Asset::Sku::EMSToken->newById($session, $tokenId);
push (@{$registrant->{token_loop}}, $token->get);
}
return $self->processTemplate($registrant,$self->printBadgeTemplateId);
}

View file

@ -296,6 +296,7 @@ sub view {
"icon.small" => $child->getIcon(1),
"icon.big" => $child->getIcon,
type => $child->getName,
extension => WebGUI::Storage->getFileExtension( $child->get("filename")),
url => $child->getUrl,
canEdit => $child->canEdit,
controls => $child->getToolbar,

View file

@ -393,6 +393,21 @@ sub getContentLastModifiedBy {
#-------------------------------------------------------------------
=head2 getInheritableProperties ( )
Extend the base class to include the mobileTemplateId.
=cut
override getInheritableProperties => sub {
my $self = shift;
my %properties = super();
$properties{mobileTemplateId} = $self->mobileTemplateId;
return %properties;
};
#-------------------------------------------------------------------
=head2 www_view
Extend the base method to handle caching and ad rotation.
@ -437,4 +452,3 @@ override www_view => sub {
__PACKAGE__->meta->make_immutable;
1;

View file

@ -635,11 +635,15 @@ sub editThingDataSave {
if ($self->field_isa($fieldType, 'WebGUI::Form::File')) {
$field->{ defaultValue } = $thingData{ "field_" . $field->{ fieldId } };
}
elsif ($fieldType eq 'Date' or $fieldType eq 'DateTime') { ##Must be in epoch format to be stored in the db.
my $wdt = WebGUI::DateTime->new($session, $field->{defaultValue})->cloneToUserTimeZone;
$field->{defaultValue} = $wdt->epoch;
}
$fieldValue = $thingData->{$fieldName} || $session->form->process($fieldName,$fieldType,$field->{defaultValue},$field);
}
if ($field->{status} eq "required" && ($fieldValue =~ /^\s$/x || $fieldValue eq "" || !(defined $fieldValue))) {
push (@errors,{
"error_message"=>$field->{label}." ".$i18n->get('is required error').".",
"error_message"=>$field->{label}." ".$i18n->get('is required error').".", "field_name"=>$fieldName,
});
}
if ($field->{status} eq "hidden") {
@ -655,7 +659,7 @@ sub editThingDataSave {
unless ( $self->isUniqueEntry($thingId,$fieldName,$fieldValue,$thingDataId)) {
push (@errors,{
"error_message"=>$field->{label}. $i18n->get('needs to be unique error'),
"error_message"=>$field->{label}. $i18n->get('needs to be unique error'),"field_name"=>$fieldName,
});
}
}
@ -1042,17 +1046,17 @@ sub getFieldValue {
my $fieldType = lc $field->{fieldType};
if ($fieldType eq "date"){
my $dt = WebGUI::DateTime->new($session, $value);
$processedValue = $dt->webguiDate($dateFormat);
my $wdt = WebGUI::DateTime->new($session, $value);
$processedValue = $wdt->cloneToUserTimeZone->webguiDate($dateFormat);
}
elsif ($fieldType eq "datetime"){
my $dt = WebGUI::DateTime->new($session, $value);
$processedValue = $dt->webguiDate($dateTimeFormat);
my $wdt = WebGUI::DateTime->new($session, $value);
$processedValue = $wdt->cloneToUserTimeZone->webguiDate($dateTimeFormat);
}
# TODO: The otherThing field type is probably also handled by getFormPlugin, so the elsif below can probably be
# safely removed. However, this requires more testing than I can provide right now, so for now this stays the
# way it was.
elsif ($field->{fieldType} =~ m/^otherthing/x) {
elsif ($fieldType =~ m/^otherthing/x) {
my $otherThingId = $field->{fieldType};
$otherThingId =~ s/^otherThing_//x;
my $tableName = 'Thingy_'.$otherThingId;
@ -1599,11 +1603,11 @@ sub indexThing {
return unless $thing;
my $index = WebGUI::Search::Index->new($self);
$index->addRecord(
url => $self->getUrl($self->getThingUrl($thing)),
groupIdView => $thing->{groupIdView},
title => $thing->{label},
subId => $thing->{thingId},
keywords => join(' ', @{$thing}{qw/label editScreenTitle editInstructions searchScreenTitle searchDescription/}),
url => $self->session->url->append($self->get('url'), $self->getThingUrl($thing)),
);
##Easy update of all thingData fields for this thing. This is in lieu of deleting all records
##And rebuilding them all.
@ -1675,7 +1679,7 @@ sub indexThingData {
|| $self->getTitle;
$index->addRecord(
assetId => $self->getId,
url => $self->getUrl('func=viewThingData;thingId='. $thing->{thingId} . ';thingDataId='. $thingData->{thingDataId}),
url => $session->url->append($self->get('url'), 'func=viewThingData;thingId='. $thing->{thingId} . ';thingDataId='. $thingData->{thingDataId}),
groupIdView => $thing->{groupIdView},
title => $title,
subId => $thing->{thingId} . '-' . $thingData->{thingDataId},
@ -3008,7 +3012,7 @@ sub www_editThingDataSaveViaAjax {
return JSON->new->encode({message => $i18n->get("has entered max per user message")});
}
if($thingDataId eq 'new' && $self->hasEnteredMaxEntries($thingId)){
$session->http->setStatus("400", "Bad Request");
$session->response->status("400");
return JSON->new->encode({message => $i18n->get("has entered max total message")});
}
@ -3069,7 +3073,6 @@ sub www_exportThing {
### Loop through the returned structure and put it through Text::CSV
# Column heads
$self->session->log->warn("field labels: ". join ' ', @fieldLabels);
my $csv_filename = 'export_'.$thingProperties->{label}.'.csv';
open my $CSV, '>', $tempStorage->getPath($csv_filename);
print $CSV WebGUI::Text::joinCSV( @fieldLabels );

View file

@ -15,7 +15,6 @@ package WebGUI::Asset;
=cut
use strict;
use Tie::IxHash;
=head1 NAME
@ -380,7 +379,7 @@ sub www_editMetaDataField {
label=>$i18n->get(486),
hoverHelp=>$i18n->get('Data Type description'),
value=>$fieldInfo->{fieldType} || "text",
types=> [ qw /text integer yesNo selectBox radioList checkList/ ]
types=> [ qw /text integer yesNo selectBox radioList checkList date/ ]
);
my $default = ref WebGUI::Asset->assetName eq 'ARRAY'

View file

@ -20,9 +20,11 @@ use WebGUI::International;
use WebGUI::Asset::Template;
use WebGUI::User;
use WebGUI::Workflow::Instance;
use WebGUI::Shop::AddressBook;
use WebGUI::Inbox;
use WebGUI::Friends;
use WebGUI::Deprecate;
use URI;
# Profile field name for the number of times the showMessageOnLogin has been
# seen.
@ -910,17 +912,44 @@ sub www_createAccountSave {
my $userId = $u->userId;
$u->username($username);
$u->authMethod($self->authMethod);
$self->session->log->info( " override: " . $self->session->scratch->getLanguageOverride );
use Data::Dumper;
$self->session->log->info( Dumper $profile );
if (!$profile->{'language'} && $self->session->scratch->getLanguageOverride) {
$profile->{'language'} = $self->session->scratch->getLanguageOverride;
}
$u->karma($self->session->setting->get("karmaPerLogin"),"Login","Just for logging in.") if ($self->session->setting->get("useKarma"));
$u->updateProfileFields($profile) if ($profile);
$u->update($profile);
$self->update($properties);
my $address = {};
my $address_mappings = WebGUI::Shop::AddressBook->getProfileAddressMappings;
foreach my $fieldId (keys %$profile) {
#set the shop address fields
my $address_key = $address_mappings->{$fieldId};
$address->{$address_key} = $profile->{$fieldId} if ($address_key);
}
$self->session->user({user=>$u});
#Update or create and update the shop address
if ( keys %$address ) {
$address->{'isProfile' } = 1;
#Get home address only mappings to avoid creating addresses with just firstName, lastName, email
my %home_address_map = %{$address_mappings};
foreach my $exclude ( qw{ firstName lastName email } ) {
delete $home_address_map{$exclude};
}
#Add the profile address for the user if there are homeAddress fields
if( grep { $address->{$_} } values %home_address_map ) {
#Create the address book for the user
my $addressBook = WebGUI::Shop::AddressBook->newByUserId($self->session,$userId);
$address->{label} = "Profile Address";
my $new_address = $addressBook->addAddress($address);
#Set this as the default address if one doesn't already exist
$addressBook->update( { defaultAddressId => $new_address->getId } );
}
}
if ($self->getSetting("sendWelcomeMessage")){
my $var;
$var->{welcomeMessage} = $self->getSetting("welcomeMessage");
@ -936,7 +965,6 @@ sub www_createAccountSave {
});
}
$self->session->user({user=>$u});
$self->_logLogin($userId,"success");
if ($self->session->setting->get("runOnRegistration")) {
@ -1182,13 +1210,7 @@ sub www_login {
$u->karma($self->session->setting->get("karmaPerLogin"),"Login","Just for logging in.") if ($self->session->setting->get("useKarma"));
$self->_logLogin($uid,"success");
if ($self->session->setting->get('encryptLogin')) {
my $currentUrl = $self->session->url->page(undef,1);
$currentUrl =~ s/^https:/http:/;
$self->session->response->setRedirect($currentUrl);
}
# Run on login
# Run on login
my $command = $self->session->config->get("runOnLogin");
if ($command ne "") {
WebGUI::Macro::process($self->session,\$command);
@ -1196,7 +1218,6 @@ sub www_login {
$self->session->log->warn($error) if $error;
}
# Set the proper redirect
if ( $self->session->setting->get( 'showMessageOnLogin' )
&& $self->user->get( $LOGIN_MESSAGE_SEEN )
@ -1215,6 +1236,11 @@ sub www_login {
$self->session->response->setRedirect($self->session->setting->get("redirectAfterLoginUrl"));
$self->session->scratch->delete("redirectAfterLogin");
}
elsif ($self->session->setting->get('encryptLogin')) {
my $currentUrl = $self->session->url->page(undef,1);
$currentUrl =~ s/^https:/http:/;
$self->session->response->setRedirect($currentUrl);
}
# Get open version tag. This is needed if we want
# to reclaim a version right after login (singlePerUser and siteWide mode)
@ -1281,18 +1307,27 @@ sub www_showMessageOnLogin {
# Add the link to continue
my $session = $self->session;
my $redirectUrl = $self->session->form->get( 'returnUrl' )
|| $self->session->setting->get("redirectAfterLoginUrl")
|| $self->session->scratch->get( 'redirectAfterLogin' )
|| $self->session->url->getBackToSiteURL
my $redirectUrl = $session->form->get( 'returnUrl' )
|| $session->setting->get("redirectAfterLoginUrl")
|| $session->scratch->get( 'redirectAfterLogin' )
|| $session->url->getBackToSiteURL
;
$output .= '<p><a href="' . $redirectUrl . '">' . $i18n->get( 'showMessageOnLogin return' )
. '</a></p>'
;
if ($session->setting->get('encryptLogin') && ( ! $redirectUrl =~ /^http/)) {
##A scheme-less URL has been supplied. We need to make it an absolute one
##with a non-encrypted scheme. Otherwise the user will stay in SSL mode.
##We assume that the user put the gateway URL into their URL.
my $uri = URI->new_abs($redirectUrl, $session->url->getSiteURL);
$uri->scheme('http');
$redirectUrl = $uri->as_string;
}
# No matter what, we won't be redirecting after this
$self->session->scratch->delete( 'redirectAfterLogin' );
$session->scratch->delete( 'redirectAfterLogin' );
return $output;
}

View file

@ -23,6 +23,7 @@ use WebGUI::User;
use WebGUI::Form::Captcha;
use WebGUI::Macro;
use WebGUI::Deprecate;
use Scope::Guard qw(guard);
use Encode ();
use Tie::IxHash;
@ -679,12 +680,28 @@ sub www_createAccountSave {
$properties->{ identifier } = $self->hashPassword($password);
$properties->{ passwordLastUpdated } = time();
$properties->{ passwordTimeout } = $setting->get("webguiPasswordTimeout");
$properties->{ status } = 'Deactivated' if ($setting->get("webguiValidateEmail"));
my $afterCreateMessage = $self->SUPER::createAccountSave($username,$properties,$password,$profile);
my $sendEmail = $setting->get('webguiValidateEmail');
# We need to deactivate the user and log him out if there are additional
# things that need to be done before he should be logged in.
my $cleanupUser;
if ($sendEmail || !$setting->get('enableUsersAfterAnonymousRegistration')) {
$cleanupUser = guard {
$self->user->status('Deactivated');
$session->var->end($session->var->get('sessionId'));
$session->var->start(1, $session->getId);
my $u = WebGUI::User->new($session, 1);
$self->{user} = $u;
$self->logout;
};
}
# Send validation e-mail if required
if ($setting->get("webguiValidateEmail")) {
if ($sendEmail) {
my $key = $session->id->generate;
$self->update(emailValidationKey=>$key);
my $mail = WebGUI::Mail::Send->create($self->session, {
@ -700,12 +717,6 @@ WebGUI::Asset::Template->newById($self->session,$self->getSetting('accountActiva
$mail->addText($text);
$mail->addFooter;
$mail->queue;
$self->user->status("Deactivated");
$session->end();
$session->start(1, $session->getId);
my $u = WebGUI::User->new($session, 1);
$self->{user} = $u;
$self->logout;
return $self->www_displayLogin($i18n->get('check email for validation','AuthWebGUI'));
}
return $afterCreateMessage;

View file

@ -0,0 +1,145 @@
package WebGUI::Content::PDFGenerator;
use warnings;
use strict;
use List::Util qw(first);
use Scope::Guard qw(guard);
use WebGUI::Session;
use WebGUI::Content::Asset;
=head1 NAME
WebGUI::Content::PDFGenerator
=head1 DESCRIPTION
Generates a PDF of the requested URL when op=generatePdf.
=head1 PREREQUISITES
This handler depends on wkpdftohtml, which does not ship with WebGUI and is,
as of this writing, still in active development. This handler was written for
version 0.9.9. It is available from http://code.google.com/p/wkhtmltopdf/.
Compiling is rather difficult, but static binaries are available for the most
popular platforms.
=head1 INSTALLATION
Enable this content handler in your WebGUI config file, placing it somewhere
before WebGUI::Content::Operation, and add a pdfGen section to your config
file at the top level. This must contain the path to your wkhtmltopdf
executable, a cache timeout (how many seconds to cache the pdf), and
optionally the userId of a user to view the page as (defaults to Visitor). It
can also contain additional command line arguments to pass to wkhtmltopdf.
"pdfGen" : {
"exe" : "/usr/local/bin/wkhtmltopdf",
"args" : "--orientation Landscape",
"userId" : "_f7d61hs6djh0fjnxqw21",
"cacheTimeout" : 3600 # 1 hour cache timeout
},
"contentHandlers" : [
#...
"WebGUI::Content::PDFGenerator",
#...
"WebGUI::Content::Operation",
#...
"WebGUI::Content::NotFound"
],
=cut
#-------------------------------------------------------------------
# Return the cached pdf, generating if necessary.
=head2 cache ($asset)
Returns the cached PDF for an asset, if necessary
=cut
sub cache {
my $asset = shift;
my $session = $asset->session;
my $key = join '', 'PDFGen', $session->url->getRequestedUrl, $asset->get('revisionDate');
my $cache = $session->cache();
my $content = $cache->get($key);
unless ($content) {
$content = generate($asset);
$cache->set($key, $content, $session->config->get('pdfGen/cacheTimeout'));
}
return $content;
}
#-------------------------------------------------------------------
# Generate the pdf unconditionally and return it as a string.
=head2 generate ($asset)
Generate the pdf unconditionally and return it as a string.
=cut
sub generate {
my $asset = shift;
my $session = $asset->session;
my $url = $session->url;
my $c = $session->config;
my $o = $c->get('pdfGen');
my $login = WebGUI::Session->open($c->getWebguiRoot, $c->getFilename);
my $guard = guard { $login->var->end; $login->close };
$login->user({ userId => $o->{userId} || 1 });
my @args = (
$o->{exe}, @{$o->{args} || []},
'--cookie', $c->get('cookieName'), $login->getId,
$url->getSiteURL . $url->gateway($url->getRequestedUrl),
'-'
);
# We're using backticks because trying to run external programs from a
# mod_perl process is extremely tricky any other way, but TODO: figure out
# use a real call and pass an array of args, as that would be safer.
my $cmd = join ' ', @args;
`$cmd`;
}
#-------------------------------------------------------------------
=head2 cache ($asset)
Figure out which asset we need to check permissions for
=cut
sub getRequestedAsset {
my $session = shift;
my $assetUrl = $session->url->getRequestedUrl;
my $perms = WebGUI::Content::Asset::getUrlPermutations($assetUrl);
foreach my $url (@$perms) {
if (my $asset = WebGUI::Content::Asset::getAsset($session, $url)) {
return $asset;
}
}
}
#-------------------------------------------------------------------
# Top-level handler.
=head2 handler ($session)
Top-level handler
=cut
sub handler {
my $session = shift;
my $op = $session->form->get('op');
return undef unless $op && $op eq 'generatePdf';
my $asset = getRequestedAsset($session);
return $session->privilege->noAccess unless $asset->canView;
$session->response->content_type('application/pdf');
return cache($asset);
}
1;

View file

@ -300,6 +300,7 @@ sub www_upload {
title => $filename,
url => "attachments/".$filename,
filename => $filename,
extension => WebGUI::Storage->getFileExtension($filename),
ownerUserId => $owner,
groupIdEdit => "3",
groupIdView => "7",

View file

@ -40,7 +40,25 @@ The following methods are specifically available from this class. Check the supe
=cut
#-------------------------------------------------------------------
=head2 definition ( session, [ additionalTerms ] )
Add another field so we can provide extras to the text area vs the selectBox
=cut
sub definition {
my $class = shift;
my $session = shift;
my $definition = shift || [];
push(@{$definition}, {
textExtras=>{
defaultValue=>undef
},
});
return $class->SUPER::definition($session, $definition);
}
#-------------------------------------------------------------------
@ -127,7 +145,8 @@ sub toHtml {
.WebGUI::Form::Text->new($self->session,
size=>$self->session->setting->get("textBoxSize")-5,
name=>$self->get("name")."_new",
id=>$self->get('id')."_new"
id=>$self->get('id')."_new",
extras=>$self->get('textExtras'),
)->toHtml;
}

View file

@ -383,6 +383,7 @@ sub prepare {
$style->setCss( $url->extras( 'yui/build/button/assets/skins/sam/button.css'));
$style->setCss( $url->extras( 'yui/build/calendar/assets/skins/sam/calendar.css'));
$style->setCss( $url->extras('yui/build/container/assets/skins/sam/container.css'));
$style->setCss( $url->extras('yui-webgui/build/form/datatable.css'));
$style->setScript( $url->extras('yui/build/container/container-min.js') );
$style->setScript( $url->extras('yui/build/button/button-min.js') );
$style->setScript( $url->extras('yui/build/calendar/calendar-min.js') );

View file

@ -137,9 +137,9 @@ Send JS required for this plugin.
sub headTags {
my $self = shift;
my ( $url, $style ) = $self->session->quick(qw( url style ));
$style->setScript( $url->extras('yui/build/connection/connection-min.js') );
$style->setScript( $url->extras('yui/build/yahoo-dom-event/yahoo-dom-event.js'));
$style->setScript( $url->extras('yui/build/json/json-min.js'));
$style->setScript( $url->extras('yui/build/connect/connect-min.js') );
$style->setScript( $url->extras('yui-webgui/build/i18n/i18n.js') );
$style->setScript( $url->extras('yui-webgui/build/form/jsontable.js'));
}

View file

@ -234,7 +234,7 @@ sub getValue {
=head2 getDefaultValue ( )
Returns the either the "value" ore "defaultValue" passed in to the object in that order, and doesn't take into account form processing.
Returns the either the "value" or "defaultValue" passed in to the object in that order, and doesn't take into account form processing.
=cut
@ -259,7 +259,7 @@ sub getDefaultValue {
=head2 getOriginalValue ( )
Returns the either the "value" ore "defaultValue" passed in to the object in that order, and doesn't take into account form processing.
Returns the either the "value" or "defaultValue" passed in to the object in that order, and doesn't take into account form processing.
=cut

View file

@ -109,7 +109,7 @@ sub getValue {
=head2 getDefaultValue ( )
Returns the either the "value" ore "defaultValue" passed in to the object in that order, and doesn't take into account form processing.
Returns the either the "value" or "defaultValue" passed in to the object in that order, and doesn't take into account form processing.
=cut
@ -124,7 +124,7 @@ sub getDefaultValue {
=head2 getOriginalValue ( )
Returns the either the "value" ore "defaultValue" passed in to the object in that order, and doesn't take into account form processing.
Returns the either the "value" or "defaultValue" passed in to the object in that order, and doesn't take into account form processing.
=cut

View file

@ -1115,12 +1115,19 @@ Membership will always be false if no IpFilter has been set
id of the user to check for membership
=head3 sessionId
id of the session to check for user data. If no sessionId is passed in, then the
group's session will be used to find one.
=cut
sub hasIpUser {
my $self = shift;
my $userId = shift;
my $session = $self->session;
my $userId = shift;
my $userSessionId = shift || $session->getId;
my $IpFilter = $self->ipFilter();
return 0 unless ($IpFilter && $userId);
@ -1128,9 +1135,9 @@ sub hasIpUser {
$IpFilter =~ s/\s//g;
my @filters = split /;/, $IpFilter;
my @ips = $session->db->buildArray(
q{ select lastIP from userSession where expires > ? and userId = ? }
,[ time(), $userId ]
my @ips = $session->db->buildArray(
q{ select lastIP from userSession where expires > ? and userId = ? and sessionId=?}
,[ time(), $userId, $userSessionId, ]
);
foreach my $ip (@ips) {
@ -1231,7 +1238,7 @@ sub hasLDAPUser {
#-------------------------------------------------------------------
=head2 hasScratchUser ( userId )
=head2 hasScratchUser ( userId, [ $sessionId ] )
Determine if the user passed in is a member of this group via session scratch
variable settings and this group's scratchFilter.
@ -1242,12 +1249,18 @@ If no scratchFilter has been set for this group, membership will always be false
id of the user to check for membership
=head3 sessionId
id of the session for the user being checked for membership. If no sessionId is passed in, then the
group's session will be used to find one.
=cut
sub hasScratchUser {
my $self = shift;
my $userId = shift;
my $session = $self->session;
my $userId = shift;
my $userSessionId = shift || $self->session;
my $scratchFilter = $self->scratchFilter();
return 0 unless ($scratchFilter && $userId);
@ -1256,7 +1269,7 @@ sub hasScratchUser {
my @filters = split /;/, $scratchFilter;
my @scratchClauses = ();
my @scratchPlaceholders = ( $userId, time() );
my @scratchPlaceholders = ( $userSessionId, $userId, time() );
foreach my $filter (@filters) {
my ($name, $value) = split /=/, $filter;
push @scratchClauses, "(s.name=? AND s.value=?)";
@ -1270,6 +1283,7 @@ sub hasScratchUser {
from
userSession u, userSessionScratch s
where
u.sessionId = ? AND
u.sessionId=s.sessionId AND
u.userId = ? AND
u.expires > ? AND
@ -1297,6 +1311,7 @@ sub hasUser {
my $self = shift;
my $session = $self->session;
my $user = shift || WebGUI::User->new($session,3); #Check the admin account if no user is passed in
my $uSessionId = $user->session->getId;
my $gid = $self->getId;
my $db = $session->db;
@ -1383,9 +1398,9 @@ sub hasUser {
my $groupToCheck = __PACKAGE__->new($session,$groupIdInGroup);
### Check the 'has' method for each of the 'other' group methods available for this user
### perform checks in a least -> most expensive manner. If we find the user, stow the cache and return true
if( $groupToCheck->hasIpUser($uid)
if( $groupToCheck->hasIpUser($uid, $uSessionId)
|| $groupToCheck->hasKarmaUser($uid)
|| $groupToCheck->hasScratchUser($uid)
|| $groupToCheck->hasScratchUser($uid, $uSessionId)
|| $groupToCheck->hasDatabaseUser($uid)
|| $groupToCheck->hasLDAPUser($uid)
) {

View file

@ -419,7 +419,11 @@ sub processReplacements {
}
foreach my $searchFor (keys %{$replacements}) {
my $replaceWith = $replacements->{$searchFor};
$content =~ s/\b\Q$searchFor\E\b/$replaceWith/gs;
my $pattern = qr/\Q$searchFor\E/;
if ($searchFor =~ /^\w+/) {
$pattern = qr/\b$pattern\b/;
}
$content =~ s/$pattern/$replaceWith/gs;
}
return $content;
}

View file

@ -201,6 +201,7 @@ sub getOperations {
'ajaxDeleteUser' => 'User',
'ajaxUpdateUser' => 'User',
'becomeUser' => 'User',
'confirmUserEmail' => 'User',
'deleteUser' => 'User',
'editUser' => 'User',
'editUserSave' => 'User',

View file

@ -399,6 +399,15 @@ sub definition {
hoverHelp=>$i18n->get('118 description'),
defaultValue=>$setting->get("anonymousRegistration")
});
push(@fields, {
tab => 'user',
fieldType => 'yesNo',
name => 'enableUsersAfterAnonymousRegistration',
label => $i18n->get('Enable Users after Anonymous Registration?'),
hoverHelp => $i18n->get('enableUsersAfterAnonymousRegistration help'),
defaultValue => $setting->get('enableUsersAfterAnonymousRegistration')
}
);
push(@fields, {
tab=>"user",
fieldType=>"yesNo",

View file

@ -415,6 +415,38 @@ sub www_ajaxCreateUser {
#-------------------------------------------------------------------
=head2 www_confirmUserEmail ( )
Process links clicked from mails sent out by the WaitForUserConfmration
workflow activity.
=cut
sub www_confirmUserEmail {
my $session = shift;
my $f = $session->form;
my $instanceId = $f->get('instanceId');
my $token = $f->get('token');
my $actId = $f->get('activityId');
my $activity = WebGUI::Workflow::Activity->new($session, $actId)
or die;
my $instance = WebGUI::Workflow::Instance->new($session, $instanceId)
or die;
if ($activity->confirm($instance, $token)) {
my $msg = $activity->get('okMessage');
unless ($msg) {
my $i18n = WebGUI::International->new($session, 'WebGUI');
$msg = $i18n->get('ok');
}
return $session->style->userStyle($msg);
}
else {
return $session->privilege->noAccess;
}
}
#-------------------------------------------------------------------
=head2 www_ajaxDeleteUser ( )
Delete a user using a web service.
@ -758,7 +790,7 @@ sub www_editUser {
size=>15,
value=>\@groupsToDelete
);
return '<h1>' . $i18n->get(168) . '</h1>' . $f->toHtml;
return '<h1>' . $i18n->get(168) . '</h1>' . $error . $f->toHtml;
}
#-------------------------------------------------------------------
@ -786,7 +818,7 @@ sub www_editUserSave {
return $session->privilege->adminOnly() unless ($isAdmin || $isSecondary) && $session->form->validToken;
# Check to see if
# Check to see if
# 1) the userId associated with the posted username matches the posted userId (we're editing an account)
# or that the userId is new and the username selected is unique (creating new account)
# or that the username passed in isn't assigned a userId (changing a username)
@ -797,11 +829,11 @@ sub www_editUserSave {
my $postedUsername = $session->form->process("username");
$postedUsername = WebGUI::HTML::filter($postedUsername, "all");
if (($existingUserId eq $postedUserId || ($postedUserId eq "new" && !$existingUserId) || $existingUserId eq '')
if (($existingUserId eq $postedUserId || ($postedUserId eq "new" && !$existingUserId) || $existingUserId eq '')
&& $postedUsername ne '')
{
# Create a user object with the id passed in. If the Id is 'new', the new method will return a new user,
# otherwise return the existing users properties
# Create a user object with the id passed in. If the Id is 'new', the new method will return a new user,
# otherwise return the existing users properties
my $u = WebGUI::User->new($session,$postedUserId);
$actualUserId = $u->userId;
@ -819,10 +851,59 @@ sub www_editUserSave {
}
# Loop through all profile fields, and update them with new values.
foreach my $field (@{WebGUI::ProfileField->getFields($session)}) {
my $address = {};
my $address_mappings = WebGUI::Shop::AddressBook->getProfileAddressMappings;
foreach my $field (@{WebGUI::ProfileField->getFields($session)}) {
next if $field->getId =~ /contentPositions/;
$u->profileField($field->getId,$field->formProcess($u));
my $field_value = $field->formProcess($u);
$u->update({ $field->getId => $field_value} );
#set the shop address fields
my $address_key = $address_mappings->{$field->getId};
$address->{$address_key} = $field_value if ($address_key);
}
#Update or create and update the shop address
if ( keys %$address ) {
$address->{'isProfile' } = 1;
#Get the address book for the user (one is created if it does not exist)
my $addressBook = WebGUI::Shop::AddressBook->newByUserId($session, $actualUserId,);
my $profileAddress = eval { $addressBook->getProfileAddress() };
my $e;
if($e = WebGUI::Error->caught('WebGUI::Error::ObjectNotFound')) {
#Get home address only mappings to avoid creating addresses with just firstName, lastName, email
my %home_address_map = %{$address_mappings};
delete $home_address_map{qw/firstName lastName email/};
#Add the profile address for the user if there are homeAddress fields
if( grep { $address->{$_} } values %home_address_map ) {
$address->{label} = "Profile Address";
my $new_address = $addressBook->addAddress($address);
#Set this as the default address if one doesn't already exist
my $defaultAddress = eval{ $addressBook->getDefaultAddress };
if(WebGUI::Error->caught('WebGUI::Error::ObjectNotFound')) {
$addressBook->update( {
defaultAddressId => $new_address->getId
} );
}
else {
$session->log->warn("The default address exists, and it should not.");
}
}
}
elsif ($e = WebGUI::Error->caught) {
#Bad stuff happened - log an error but don't fail since this isn't a vital function
$session->log->error(
q{Could not update Shop Profile Address for user }
.$u->username.q{ : }.$e->error
);
}
else {
#Update the profile address for the user
$profileAddress->update($address);
}
}
# Update group assignements
my @groups = $session->form->group("groupsToAdd");

View file

@ -334,7 +334,7 @@ sub getRequestedUrl {
=head2 getSiteURL ( )
Returns a constructed site url. The returned value can be overridden using the setSiteURL function.
Returns a constructed site url without the gateway. The returned value can be overridden using the setSiteURL function.
=cut

View file

@ -88,6 +88,12 @@ property "addressBookId" => (
required => 1,
);
property "isProfile" => (
noFormPost => 1,
required => 0,
default => 0,
);
has [ qw/addressId addressBook/] => (
is => 'ro',
required => 1,
@ -196,6 +202,10 @@ An email address for this user.
The organization or company that this user is a part of.
=head4 isProfile
Whether or not this address is linked to the user profile. Defaults to 0
=cut
@ -357,5 +367,4 @@ sub write {
$book->session->db->setRow("address","addressId",$properties);
}
1;

View file

@ -26,6 +26,7 @@ require WebGUI::Asset::Template;
use WebGUI::Exception::Shop;
use WebGUI::Form;
use WebGUI::International;
use WebGUI::Shop::Admin;
use WebGUI::Shop::Address;
use Scalar::Util qw/blessed/;
@ -101,7 +102,7 @@ around BUILDARGS => sub {
}
my ($addressBookId) = $class->_init($session);
$properties->{addressBookId} = $addressBookId;
$properties->{userId} = $session->user->userId;
$properties->{userId} ||= $session->user->userId;
return $class->$orig($properties);
}
my $session = shift;
@ -369,6 +370,55 @@ sub getDefaultAddress {
#-------------------------------------------------------------------
=head2 getProfileAddress ()
Returns the profile address for this address book if there is one. Otherwise throws a WebGUI::Error::ObjectNotFound exception.
=cut
sub getProfileAddress {
my ($self) = @_;
my $id = $self->session->db->quickScalar(q{ select addressId from address where addressBookId=? and isProfile=1 },[$self->getId]);
if (!$id) {
WebGUI::Error::ObjectNotFound->throw(error=>"No profile address.");
}
my $address = eval { $self->getAddress($id) };
my $e;
if ($e = WebGUI::Error->caught('WebGUI::Error::ObjectNotFound')) {
$e->rethrow;
}
elsif ($e = WebGUI::Error->caught) {
$e->rethrow;
}
else {
return $address;
}
}
#-------------------------------------------------------------------
=head2 getProfileAddressMappings ( )
Class or object method which returns the profile address field mappings
=cut
sub getProfileAddressMappings {
return {
homeAddress => 'address1',
homeCity => 'city',
homeState => 'state',
homeZip => 'code',
homeCountry => 'country',
homePhone => 'phoneNumber',
email => 'email',
firstName => 'firstName',
lastName => 'lastName'
}
}
#-------------------------------------------------------------------
=head2 getId ()
Returns the unique id for this addressBook.
@ -458,7 +508,9 @@ sub newByUserId {
}
else {
# nope create one for the user
return $class->new($session);
my $book = $class->new({session => $session, userId => $userId});
$book->write;
return $book
}
}
@ -481,19 +533,19 @@ sub processAddressForm {
$prefix ||= '';
my $form = $self->session->form;
my %addressData = (
label => $form->get($prefix . "label"),
firstName => $form->get($prefix . "firstName"),
lastName => $form->get($prefix . "lastName"),
address1 => $form->get($prefix . "address1"),
address2 => $form->get($prefix . "address2"),
address3 => $form->get($prefix . "address3"),
city => $form->get($prefix . "city"),
state => $form->get($prefix . "state"),
code => $form->get($prefix . "code", "zipcode"),
country => $form->get($prefix . "country", "country"),
phoneNumber => $form->get($prefix . "phoneNumber", "phone"),
email => $form->get($prefix . "email", "email"),
organization => $form->get($prefix . "organization"),
label => $form->get($prefix . "label") || '',
firstName => $form->get($prefix . "firstName") || '',
lastName => $form->get($prefix . "lastName") || '',
address1 => $form->get($prefix . "address1") || '',
address2 => $form->get($prefix . "address2") || '',
address3 => $form->get($prefix . "address3") || '',
city => $form->get($prefix . "city") || '',
state => $form->get($prefix . "state") || '',
code => $form->get($prefix . "code", "zipcode") || '',
country => $form->get($prefix . "country", "country") || '',
phoneNumber => $form->get($prefix . "phoneNumber", "phone") || '',
email => $form->get($prefix . "email", "email") || '',
organization => $form->get($prefix . "organization") || '',
);
##Label is optional in the form, but required for the UI and API.
@ -559,6 +611,80 @@ sub www_ajaxSave {
#-------------------------------------------------------------------
=head2 www_ajaxSearch ( )
Gets a JSON object with addresses returned based on the search
parameters from the form.
=cut
sub www_ajaxSearch {
my $self = shift;
my $session = $self->session;
my $form = $session->form;
my $name = $form->get('name');
my $fields = {
'address.firstName' => (split(" ",$name))[0] || "",
'address.lastName' => (split(" ",$name))[1] || "",
'address.organization' => $form->get('organization') || "",
'address.address1' => $form->get('address1') || "",
'address.address2' => $form->get('address2') || "",
'address.address3' => $form->get('address3') || "",
'address.city' => $form->get('city') || "",
'address.state' => $form->get('state') || "",
'address.code' => $form->get('zipcode') || "",
'address.country' => $form->get('country') || "",
'address.email' => $form->get('email') || "",
'address.phoneNumber' => $form->get('phone') || "",
};
my $clause = [];
my $params = [];
foreach my $field (keys %$fields) {
my $field_value = $fields->{$field};
if($field_value) {
$field = join('.', map { $session->db->quote_identifier($_) } split(/\./, $field));
$field_value = $field_value."%";
push(@$clause,qq{$field like ?});
push(@$params,$field_value);
}
}
my $admin = WebGUI::Shop::Admin->new($session);
unless ($session->user->isAdmin || $admin->canManage || $admin->isCashier) {
push(@$clause,qq{users.userId=?});
push(@$params,$session->user->getId);
}
my $where = "";
$where = "where ".join(" and ",@$clause) if scalar(@$clause);
my $query = qq{
select
users.username,
address.*
from
address
join addressBook on address.addressBookId = addressBook.addressBookId
join users on addressBook.userId = users.userId
$where
limit 3
};
my $sth = $session->db->read($query,$params);
my $var = [];
while (my $hash = $sth->hashRef) {
push(@$var,$hash);
}
$session->response->content_type('text/plain');
return JSON->new->encode($var);
}
#-------------------------------------------------------------------
=head2 www_deleteAddress ( )
Deletes an address from the book.
@ -567,7 +693,10 @@ Deletes an address from the book.
sub www_deleteAddress {
my $self = shift;
$self->getAddress($self->session->form->get("addressId"))->delete;
my $address = $self->getAddress($self->session->form->get("addressId"));
if (defined $address && !$address->isProfile) {
$address->delete;
}
return $self->www_view;
}
@ -726,8 +855,20 @@ sub www_editAddressSave {
$self->addAddress(\%addressData);
}
else {
$self->getAddress($form->get('addressId'))->update(\%addressData);
my $addressId = $form->get('addressId');
my $address = $self->getAddress($addressId);
$address->update(\%addressData);
if($address->isProfile) {
my $u = WebGUI::User->new($self->session, $self->get("userId"));
my $address_mappings = $self->getProfileAddressMappings;
foreach my $field (keys %$address_mappings) {
my $addr_field = $address_mappings->{$field};
$u->profileField($field,$address->get($addr_field));
}
}
}
#profile fields updated in WebGUI::Shop::Address->update
return $self->www_view;
}
@ -758,12 +899,12 @@ sub www_view {
return $self->www_editAddress;
}
foreach my $address (@availableAddresses) {
push(@addresses, {
%{$address->get},
address => $address->getHtmlFormatted,
isDefault => ($self->get('defaultAddressId') eq $address->getId),
deleteButton =>
WebGUI::Form::formHeader( $session )
deleteButton => $address->get("isProfile") ? undef : WebGUI::Form::formHeader( $session )
. WebGUI::Form::hidden( $session, { name => 'shop', value => 'address' } )
. WebGUI::Form::hidden( $session, { name => 'method', value => 'deleteAddress' } )
. WebGUI::Form::hidden( $session, { name => 'addressId', value => $address->getId } )

View file

@ -766,8 +766,11 @@ sub requiresShipping {
my $self = shift;
# Look for recurring items in the cart
foreach my $item (@{ $self->getItems }) {
return 1 if $item->getSku->isShippingRequired;
ITEM: foreach my $item (@{ $self->getItems }) {
my $sku = $item->getSku;
next ITEM unless $sku;
return 1 if $sku->isShippingRequired;
}
# No recurring items in cart so return false
@ -816,10 +819,6 @@ sub updateFromForm {
$item->update({shippingAddressId => $itemAddressId});
}
}
if ($self->hasMixedItems) {
my $i18n = WebGUI::International->new($self->session, "Shop");
$self->error($i18n->get('mixed items warning'));
}
my @cartItemIds = $form->process('remove_item', 'checkList');
foreach my $cartItemId (@cartItemIds) {
@ -827,6 +826,12 @@ sub updateFromForm {
$item->remove if ! Exception::Class->caught();
}
##Remove the items BEFORE we check to see if there are duplicates.
if ($self->hasMixedItems) {
my $i18n = WebGUI::International->new($self->session, "Shop");
$self->error($i18n->get('mixed items warning'));
}
##Visitor cannot have an address book, or set a payment gateway, so skip the rest of this.
return 1 if $session->user->isVisitor;
@ -1082,6 +1087,10 @@ sub www_view {
return $session->style->userStyle($template->process(\%var));
}
if ($self->hasMixedItems) {
$self->error($i18n->get('mixed items warning'));
}
my %var = (
%{$self->get},
formHeader => WebGUI::Form::formHeader($session, { extras => q|id="wgCartId"|, })
@ -1105,7 +1114,6 @@ sub www_view {
shippableItemsInCart => $self->requiresShipping,
);
# get the shipping address
my $address = eval { $self->getShippingAddress };
if (my $e = WebGUI::Error->caught("WebGUI::Error::ObjectNotFound") && $self->shippingAddressId) {
@ -1113,6 +1121,13 @@ sub www_view {
$self->update({shippingAddressId=>''});
}
#get the billing address
my $billingAddress = eval { $self->getBillingAddress };
if (my $e = WebGUI::Error->caught("WebGUI::Error::ObjectNotFound") && $self->get('billingAddressId')) {
# choose another address cuz we've got a problem
$self->update({billingAddressId=>''});
}
# generate template variables for the items in the cart
my @items = ();
tie my %addressOptions, 'Tie::IxHash';
@ -1274,9 +1289,11 @@ sub www_view {
$addressBook->appendAddressFormVars(\%var, 'shipping_', $shippingAddressData);
$addressBook->appendAddressFormVars(\%var, 'billing_', $billingAddressData);
my $has_billing_addr = $self->get('billingAddressId') ? 1 : 0;
$var{sameShippingAsBilling} = WebGUI::Form::yesNo($session, {
name => 'sameShippingAsBilling',
value => $self->billingAddressId && $self->billingAddressId eq $self->shippingAddressId,
value => (($has_billing_addr && $self->billingAddressId eq $self->shippingAddressId) || !$has_billing_addr),
});
}

View file

@ -114,6 +114,7 @@ sub getDrivers {
my $self = shift;
my %drivers = ();
CLASS: foreach my $class (@{$self->session->config->get('paymentDrivers')}) {
$self->session->log->warn($class);
my $driverName = eval { WebGUI::Pluggable::instanciate($class, 'getName', [ $self->session ])};
if ($@) {
$self->session->log->warn("Error loading $class: $@");

View file

@ -0,0 +1,227 @@
package WebGUI::Shop::PayDriver::CreditCard;
use strict;
use Readonly;
=head1 NAME
WebGUI::Shop::PayDriver::CreditCard
=head2 DESCRIPTION
A base class for credit card payment drivers. They all need pretty much the
same information, the only difference is the servers you talk to. Leaves you
to handle recurring payments, processPayment, www_edit, and whatever else you
want to - but the user-facing code is pretty much taken care of.
=head2 METHODS
The following methods are available from this class.
=cut
use Moose;
use WebGUI::Definition::Shop;
extends 'WebGUI::Shop::PayDriver';
Readonly my $I18N => 'PayDriver_CreditCard';
define pluginName => 'Credit Card Base Class';
property useCVV2 => (
fieldType => 'yesNo',
label => ['use cvv2', $I18N],
hoverHelp => ['use cvv2 help', $I18N],
);
property credentialsTemplateId => (
fieldType => 'template',
label => ['credentials template', $I18N],
hoverHelp => ['credentials template help', $I18N],
namespace => 'Shop/Credentials',
default => 'itransact_credentials1',
);
#-------------------------------------------------------------------
sub _monthYear {
my $session = shift;
my $form = $session->form;
tie my %months, "Tie::IxHash";
tie my %years, "Tie::IxHash";
%months = map { sprintf( '%02d', $_ ) => sprintf( '%02d', $_ ) } 1 .. 12;
%years = map { $_ => $_ } 2004 .. 2099;
my $monthYear =
WebGUI::Form::selectBox( $session, {
name => 'expMonth',
options => \%months,
value => [ $form->process("expMonth") ]
})
. " / "
. WebGUI::Form::selectBox( $session, {
name => 'expYear',
options => \%years,
value => [ $form->process("expYear") ]
});
return $monthYear;
}
#-------------------------------------------------------------------
=head2 appendCredentialVars
Add template vars for www_getCredentials. Override this to add extra fields.
=cut
sub appendCredentialVars {
my ($self, $var) = @_;
my $session = $self->session;
my $u = $session->user;
my $form = $session->form;
my $i18n = WebGUI::International->new($session, $I18N);
$var->{formHeader} = WebGUI::Form::formHeader($session)
. $self->getDoFormTags('pay');
$var->{formFooter} = WebGUI::Form::formFooter();
my @fieldLoop;
# Credit card information
$var->{cardNumberField} = WebGUI::Form::text($session, {
name => 'cardNumber',
value => $self->session->form->process("cardNumber"),
});
$var->{monthYearField} = WebGUI::Form::readOnly($session, {
value => _monthYear( $session ),
});
$var->{cvv2Field} = WebGUI::Form::integer($session, {
name => 'cvv2',
value => $self->session->form->process("cvv2"),
}) if $self->get('useCVV2');
$var->{checkoutButton} = WebGUI::Form::submit($session, {
value => $i18n->get('checkout button', 'Shop'),
});
return;
}
#-------------------------------------------------------------------
=head2 processCredentials
Process the form where credentials (name, address, phone number and credit card information)
are entered.
=cut
sub processCredentials {
my $self = shift;
my $session = $self->session;
my $form = $session->form;
my $i18n = WebGUI::International->new($session, $I18N);
my @error;
# Check credit card data
push @error, $i18n->get( 'invalid card number' ) unless $form->integer('cardNumber');
push @error, $i18n->get( 'invalid cvv2' ) if ($self->get('useCVV2') && !$form->integer('cvv2'));
# Check if expDate and expYear have sane values
my ($currentYear, $currentMonth) = $self->session->datetime->localtime;
my $expires = $form->integer( 'expYear' ) . sprintf '%02d', $form->integer( 'expMonth' );
my $now = $currentYear . sprintf '%02d', $currentMonth;
push @error, $i18n->get('invalid expiration date') unless $expires =~ m{^\d{6}$};
push @error, $i18n->get('expired expiration date') unless $expires >= $now;
return \@error if scalar @error;
# Everything ok process the actual data
$self->{ _cardData } = {
acct => $form->integer( 'cardNumber' ),
expMonth => $form->integer( 'expMonth' ),
expYear => $form->integer( 'expYear' ),
cvv2 => $form->integer( 'cvv2' ),
};
return;
}
#-------------------------------------------------------------------
=head2 www_getCredentials ( $errors )
Build a templated form for asking the user for their credentials.
=head3 $errors
An array reference of errors to show the user.
=cut
sub www_getCredentials {
my $self = shift;
my $errors = shift;
my $session = $self->session;
my $form = $session->form;
my $i18n = WebGUI::International->new($session, $I18N);
my $var = {};
# Process form errors
$var->{errors} = [];
if ($errors) {
$var->{error_message} = $i18n->get('error occurred message');
foreach my $error (@{ $errors} ) {
push @{ $var->{errors} }, { error => $error };
}
}
$self->appendCredentialVars($var);
$self->appendCartVariables($var);
my $template = WebGUI::Asset::Template->new($session, $self->get("credentialsTemplateId"));
my $output;
if (defined $template) {
$template->prepare;
$output = $template->process($var);
}
else {
$output = $i18n->get('template gone');
}
return $session->style->userStyle($output);
}
#-------------------------------------------------------------------
=head2 www_pay
Makes sure that the user has all the requirements for checking out, including
getting credentials, it processes the transaction and then displays a thank
you screen.
=cut
sub www_pay {
my $self = shift;
my $session = $self->session;
# Check whether the user filled in the checkout form and process those.
my $credentialsErrors = $self->processCredentials;
# Go back to checkout form if credentials are not ok
return $self->www_getCredentials( $credentialsErrors ) if $credentialsErrors;
# Payment time!
my $transaction = $self->processTransaction( );
if ($transaction->get('isSuccessful')) {
return $transaction->thankYou();
}
# Payment has failed...
return $self->displayPaymentError($transaction);
}
1;

View file

@ -0,0 +1,256 @@
package WebGUI::Shop::PayDriver::CreditCard::AuthorizeNet;
use strict;
use base qw/WebGUI::Shop::PayDriver::CreditCard/;
use DateTime;
use Readonly;
use Business::OnlinePayment;
use Moose;
use WebGUI::Definition::Shop;
extends 'WebGUI::Shop::PayDriver::CreditCard';
Readonly my $I18N => 'PayDriver_AuthorizeNet';
define pluginName => ['name', $I18N];
property login => (
fieldType => 'text',
label => ['login', $I18N],
hoverHelp => ['login help', $I18N],
);
property transaction_key => (
fieldType => 'text',
label => ['transaction key', $I18N],
hoverHelp => ['transaction key help', $I18N],
);
property testMode => (
fieldType => 'YesNo',
label => ['test mode', $I18N],
hoverHelp => ['test mode help', $I18N],
);
=head1 NAME
WebGUI::Shop::PayDriver::CreditCard::AuthorizeNet
=head1 DESCRIPTION
Payment driver that uses Business::OnlinePayment to process transactions
through Authorize.net
=head1 SYNOPSIS
# in webgui config file...
"paymentDrivers" : [
"WebGUI::Shop::PayDriver::Cash",
"WebGUI::Shop::PayDriver::CreditCard::AuthorizeNet",
...
],
=head1 METHODS
The following methods are available from this class:
=cut
#-------------------------------------------------------------------
=head2 appendCredentialVars ( var )
Overridden to add the card type field
=cut
sub appendCredentialVars {
my ( $self, $var ) = @_;
my $session = $self->session;
my $i18n = WebGUI::International->new( $session, $I18N );
$self->SUPER::appendCredentialVars($var);
$var->{cardTypeField} = WebGUI::Form::selectBox(
$session, {
name => 'cardType',
options => { map { $_ => $_ } ( 'Visa', 'MasterCard', 'American Express', 'Discover', ) },
}
);
return;
} ## end sub appendCredentialVars
#-------------------------------------------------------------------
=head2 cancelRecurringPayment ( transaction )
Cancels a recurring transaction. Returns an array containing ( isSuccess, gatewayStatus, gatewayError).
=head3 transaction
The instanciated recurring transaction object.
=cut
sub cancelRecurringPayment {
my ( $self, $transaction ) = @_;
my $session = $self->session;
my $tx = $self->gatewayObject;
$tx->content(
subscription => $transaction->get('transactionCode'),
login => $self->get('login'),
password => $self->get('transaction_key'),
action => 'Cancel Recurring Authorization',
);
$tx->submit;
return $self->gatewayResponse($tx);
}
#-------------------------------------------------------------------
=head2 gatewayObject ( params )
Returns a Business::OnlinePayment object, possibly with options set from the
paydriver properties. params can be a hashref of the options that would
normally be passed to tx->content, in which case these will be passed along.
=cut
sub gatewayObject {
my ( $self, $params ) = @_;
my $tx = Business::OnlinePayment->new('AuthorizeNet');
if ( $self->get('testMode') ) {
# Yes, we need to do both these things. The BOP interfaces tend to
# ony honor one or the other of them.
$tx->test_transaction(1);
$tx->server('test.authorize.net');
}
$tx->content(%$params) if $params;
return $tx;
}
#-------------------------------------------------------------------
=head2 gatewayResponse ( tx )
Returns the various responses required by the PayDriver interface from the
passed Business::OnlinePayment object.
=cut
sub gatewayResponse {
my ( $self, $tx ) = @_;
return ( $tx->is_success, $tx->order_number, $tx->result_code, $tx->error_message );
}
#-------------------------------------------------------------------
sub handlesRecurring {1}
#-------------------------------------------------------------------
=head2 paymentParams
Returns a hashref of the billing address and card information, translated into
a form that Business::OnlinePayment likes
=cut
sub paymentParams {
my $self = shift;
my $card = $self->{_cardData};
my $bill = $self->getCart->getBillingAddress->get();
my %params = (
type => $card->{type},
login => $self->get('login'),
transaction_key => $self->get('transaction_key'),
first_name => $bill->{firstName},
last_name => $bill->{lastName},
address => $bill->{address1},
city => $bill->{city},
state => $bill->{state},
zip => $bill->{code},
card_number => $card->{acct},
expiration => sprintf '%2d/%2d',
@{$card}{ 'expMonth', 'expYear' },
);
$params{cvv2} = $card->{cvv2} if $self->get('useCVV2');
return \%params;
} ## end sub paymentParams
#-------------------------------------------------------------------
sub processCredentials {
my $self = shift;
my $session = $self->session;
my $i18n = WebGUI::International->new( $session, $I18N );
my $error = $self->SUPER::processCredentials;
my $type = $session->form->process('cardType');
unless ($type) {
$error ||= [];
push @$error, $i18n->get('invalid cardType');
}
return $error if defined $error;
$self->{_cardData}->{type} = $type;
return;
} ## end sub processCredentials
#-------------------------------------------------------------------
sub processPayment {
my ( $self, $transaction ) = @_;
my $params = $self->paymentParams;
if ( $transaction->isRecurring ) {
my $items = $transaction->getItems;
if ( @$items > 1 ) {
WebGUI::Error::InvalidParam->throw(
error => 'This payment gateway can only handle one recurring item at a time' );
}
my $item = $items->[0];
my $sku = $item->getSku;
my %translateInterval = (
Weekly => '7 days',
BiWeekly => '14 days',
FourWeekly => '28 days',
Monthly => '1 month',
Quarterly => '3 months',
HalfYearly => '6 months',
Yearly => '12 months',
);
# BOP::AuthorizeNet::ARB has an API that's inconsistant with the AIM
# api -- it wants password instead of transaction_key. Go figure.
$params->{password} = delete $params->{transaction_key};
$params->{action} = 'Recurring Authorization';
$params->{interval} = $translateInterval{ $sku->getRecurInterval };
$params->{start} = DateTime->today->ymd;
$params->{periods} = '9999'; # magic value that means 'never stop'
$params->{description} = $item->get('configuredTitle');
} ## end if ( $transaction->isRecurring)
else {
$params->{action} = 'Normal Authorization';
}
$params->{amount} = $transaction->get('amount');
my $tx = $self->gatewayObject($params);
$tx->submit;
return $self->gatewayResponse($tx);
} ## end sub processPayment
1;

View file

@ -19,6 +19,14 @@ Package WebGUI::Test::MockAsset
=head1 DESCRIPTION
Creates fake WebGUI::Asset objects and sets them up to be returned by WebGUI::Asset's normal constructors.
Most of the time, you'll be mocking templates to read which variables are sent to their
templates. Here's how to do that:
my $mockAsset = WebGUI::Test::MockAsset->new('WebGUI::Asset::Template');
$mockAsset->mock_id($template_id_to_mock);
my $templateVars;
$templateMock->mock('process', sub { $templateVars = $_[1]; } );
$templateMock->set_true('prepare', sub { } );
=head1 METHODS

View file

@ -981,20 +981,17 @@ sub isInGroup {
### Check stow before we check the cache. Stow is in memory and much faster
my $stow = $session->stow->get("isInGroup", { noclone => 1 }) || {};
return $stow->{$uid}->{$gid} if (exists $stow->{$uid}->{$gid});
### Don't bother checking File Cache if we already have a stow for this group.
### We can find what we need there and save ourselves a bunch of time
my $cache = undef;
my $groupMembers = undef;
unless ($stow->{$uid}->{$gid}) {
$groupMembers = $session->cache->get("groupMembers".$gid) || {};
#If we have this user's membership cached, return what we have stored
if (exists $groupMembers->{$uid}) {
return $groupMembers->{$uid}->{isMember} if (!$self->isVisitor);
return $groupMembers->{$uid}->{$session->getId}->{isMember} #Include the session check for visitors
}
}
my $cache = undef;
my $groupMembers = $session->cache->get("groupMembers".$gid) || {};
#If we have this user's membership cached, return what we have stored
if (exists $groupMembers->{$uid}) {
return $groupMembers->{$uid}->{isMember} if (!$self->isVisitor);
return $groupMembers->{$uid}->{$session->getId}->{isMember} if exists $groupMembers->{$uid}->{$session->getId}; #Include the session check for visitors
}
### Instantiate the group
my $group = WebGUI::Group->new($session,$gid);
if ( !$group ) {
@ -1004,7 +1001,7 @@ sub isInGroup {
#Check the group for membership
my $isInGroup = $group->hasUser($self);
#Write what we found to file cache
$group->cacheGroupings( $self, $isInGroup, $groupMembers );
return $isInGroup;
@ -1475,8 +1472,8 @@ sub update {
delete $properties->{privacyFields};
# $self->{_user} contains all fields in `users` table
my @userFields = ();
my @userValues = ();
my @userFields = ();
my @userValues = ();
for my $key ( keys %{$self->{_user}} ) {
if ( exists $properties->{$key} ) {
# Delete the value because it's not a profile field
@ -1487,15 +1484,16 @@ sub update {
}
}
# No matter what we update properties
my $userFields = join ", ", @userFields;
my $userFields = join ", ", @userFields;
$db->write(
"UPDATE users SET $userFields WHERE userId=?",
[@userValues, $self->{_userId}]
);
# Everything else must be a profile field
my @profileFields = ();
my @profileValues = ();
my @profileFields = ();
my @profileValues = ();
for my $key ( keys %{$properties} ) {
if (!exists $self->{_profile}{$key} && !WebGUI::ProfileField->exists($session,$key)) {
$self->session->log->warn("No such profile field: $key");
@ -1506,7 +1504,7 @@ sub update {
$self->{_profile}->{$key} = $properties->{ $key };
}
if ( @profileFields ) {
my $profileFields = join ", ", @profileFields;
my $profileFields = join ", ", @profileFields;
$db->write(
"UPDATE userProfileData SET $profileFields WHERE userId=?",
[@profileValues, $self->{_userId}]

View file

@ -76,6 +76,29 @@ These methods are available from this class:
#-------------------------------------------------------------------
=head2 changeWorkflow ( $workflowId, $instance, $skipDelete )
Kicks a new workflow in a new instance with the same object the current
instance has, deleting the old instance unless you say otherwise.
=cut
sub changeWorkflow {
my ($self, $workflowId, $instance, $skipDelete) = @_;
WebGUI::Workflow::Instance->create(
$self->session, {
workflowId => $workflowId,
methodName => $instance->get('methodName'),
className => $instance->get('className'),
parameters => $instance->get('parameters'),
priority => $instance->get('priority'),
}
)->start(1);
$instance->delete() unless $skipDelete;
}
#-------------------------------------------------------------------
=head2 cleanup ( )
Override this activity to add a cleanup routine to be run if an instance

View file

@ -194,7 +194,13 @@ sub processRecurrence {
$event->generateRecurrence($d);
}
$versionTag->commit;
##If nothing needed to happen, then don't keep the tag around.
if ($versionTag->getAssetCount > 0) {
$versionTag->commit;
}
else {
$versionTag->rollback;
}
return $time_limit ? 1 : 0;
} ## end sub processRecurrence

View file

@ -101,7 +101,7 @@ sub execute {
if ($versionTag->getAssetCount) {
# if there's only one asset in the tag, we might as well give them a direct link to it
my $asset = $versionTag->getAssets->[0];
$urlOfSingleAsset = "\n\n".$self->session->url->getSiteURL().$asset->getUrl("func=view;revision=".$asset->get("revisionDate"));
$urlOfSingleAsset = $self->session->url->getSiteURL().$asset->getUrl("func=view;revision=".$asset->get("revisionDate"));
}
my $var = {
message => $self->get('message'),

View file

@ -0,0 +1,270 @@
package WebGUI::Workflow::Activity::WaitForUserConfirmation;
use warnings;
use strict;
use base 'WebGUI::Workflow::Activity';
use WebGUI::Asset::Template;
use WebGUI::International;
use WebGUI::Inbox::Message;
use WebGUI::Macro;
use Kwargs;
use Tie::IxHash;
#-----------------------------------------------------------------
=head2 confirm ( $instance, $token )
Returns true (and sets the workflow as done) if the token matches the one we
generated for the email.
=cut
sub confirm {
my ($self, $instance, $token) = @_;
my $id = $self->getId;
return 0 unless $token eq $instance->getScratch("$id-token");
$instance->setScratch("$id-status", 'done');
return 1;
}
#-----------------------------------------------------------------
=head2 definition ( )
See WebGUI::Workflow::Activity::definition for details.
=cut
sub definition {
my ($class, $session, $def) = @_;
my $i18n = WebGUI::International->new(
$session, 'Activity_WaitForUserConfirmation'
);
tie my %props, 'Tie::IxHash', (
emailFrom => {
fieldType => 'user',
defaultValue => 3,
},
emailSubject => {
fieldType => 'text',
defaultValue => 'Confirmation Email',
},
template => {
fieldType => 'textarea',
defaultValue => $i18n->get('your template goes here'),
},
templateParser => {
fieldType => 'templateParser',
defaultValue => $session->config->get('defaultTemplateParser'),
},
okMessage => {
fieldType => 'HTMLArea',
},
waitBetween => {
fieldType => 'interval',
defaultValue => 60*5
},
expireAfter => {
fieldType => 'interval',
defaultValue => 60*60*24*7,
},
doOnExpire => {
fieldType => 'workflow',
type => 'WebGUI::User',
none => 1,
}
);
for my $key (keys %props) {
$props{$key}{label} = $i18n->get("$key label");
$props{$key}{hoverHelp} = $i18n->get("$key hoverHelp");
}
push @$def, {
name => $i18n->get('topicName'),
properties => \%props,
};
return $class->SUPER::definition( $session, $def );
}
#-----------------------------------------------------------------
=head2 execute ( )
See WebGUI::Workflow::Activity::execute for details.
=cut
sub execute {
my ($self, $object, $instance) = @_;
my $id = $self->getId;
my $statk = "$id-status";
my $start = "$id-started";
my $status = $instance->getScratch($statk);
my $subject = $self->get('emailSubject');
my $parser = $self->get('templateParser');
WebGUI::Macro::process(\$subject);
my $body = WebGUI::Asset::Template->processRaw(
$self->session,
$self->get('template'),
$self->getTemplateVariables($object, $instance),
$parser,
);
WebGUI::Macro::process(\$body);
unless ($status) {
$instance->setScratch($start => $self->now);
$self->sendEmail(
from => $self->get('emailFrom'),
to => $object->userId,
subject => $subject,
body => $body,
);
$instance->setScratch($statk => 'waiting');
return $self->wait;
}
return $self->COMPLETE if $status eq 'done' || $status eq 'expired';
if ($status eq 'waiting') {
my $end = $instance->getScratch($start) + $self->get('expireAfter');
if ($self->now > $end) {
$self->expire($instance);
$instance->setScratch($statk => 'expired');
return $self->COMPLETE;
}
return $self->wait;
}
$self->session->log->error("Unknown status: $status");
return $self->ERROR;
}
#-----------------------------------------------------------------
=head2 expire ( $instance )
Deletes the workflow instance and kicks off a configured workflow if there is
one.
=cut
sub expire {
my ($self, $instance) = @_;
if (my $id = $self->get('doOnExpire')) {
$self->changeWorkflow($id, $instance);
}
else {
$instance->delete();
}
}
#-----------------------------------------------------------------
=head2 getTemplateVariables ( $object, $instance )
Returns the variables to be used in rendering the email template.
=cut
sub getTemplateVariables {
my ($self, $object, $instance) = @_;
my $user = $object->get;
# Kill all humans. I means references. Currently there seems to be a bug
# in _rewriteVars in some of the template plugins that disallows us from
# using arrayrefs with just strings in them, which is a common occurrence
# in profile fields. When that bug gets fixed, we can (and should) take
# this out.
delete @{$user}{grep {ref $user->{$_} } keys %$user};
return {
user => $user,
link => $self->link($instance),
}
}
#-----------------------------------------------------------------
=head2 link ( $instance )
Returns the URL that needs to be visited by the user.
=cut
sub link {
my ($self, $instance) = @_;
my $url = $self->session->url;
my $aid = $self->getId;
my $iid = $instance->getId;
my $token = $instance->getScratch("$aid-token");
$instance->setScratch("$aid-token", $token = $self->token) unless $token;
my $path = $url->page(
"op=confirmUserEmail;instanceId=$iid;token=$token;activityId=$aid"
);
return $url->getSiteURL . $url->gateway($path);
}
#-----------------------------------------------------------------
=head2 now ( )
Just returns the current time, nice for testing.
=cut
sub now { time }
#-----------------------------------------------------------------
=head2 sendEmail ( { from, to, subject, body } )
Takes a user to send email from, to, with a subject and a body all as
keywords. Mostly here for testing, it just calls
WebGUI::Inbox::Message->create() with proper arguments. 'from' and 'to' are
userIds, not user objects.
=cut
sub sendEmail {
my ($self, $from, $to, $subject, $body) = kwn @_, 1,
qw(from to subject body);
WebGUI::Inbox::Message->create(
$self->session, {
message => $body,
subject => $subject,
status => 'pending',
userId => $to,
sentBy => $from,
}
);
}
#-----------------------------------------------------------------
=head2 token ( )
Returns a random string to use as a token in the confirmation link
=cut
sub token {
my $self = shift;
$self->session->id->generate;
}
#-----------------------------------------------------------------
=head2 wait ( )
Waits for the configured waitBetween interval.
=cut
sub wait {
my $self = shift;
return $self->WAITING($self->get('waitBetween'));
}
1;

View file

@ -99,6 +99,12 @@ our $I18N = {
lastUpdated => 1230844137,
},
'Return to Account' => {
message => q{Return to Account},
context => q{label for templates that want to provide a link back to the main account page},
lastUpdated => 1230844137,
},
};
1;

View file

@ -0,0 +1,74 @@
package WebGUI::i18n::English::Activity_WaitForUserConfirmation;
use strict;
our $I18N = {
'doOnExpire hoverHelp' => {
message => q{Workflow to run after the waiting period has expired.},
lastUpdated => 1311365415,
},
'doOnExpire label' => {
message => q{Do On Expire},
lastUpdated => 1311365395,
},
'emailFrom hoverHelp' => {
message => q{Which user should the confirmation email be from?},
lastUpdated => 1311363981,
},
'emailFrom label' => {
message => q{Email From},
lastUpdated => 1311363958,
},
'emailSubject label' => {
message => q{Email Subject},
lastUpdated => 1311363994,
},
'expireAfter hoverHelp' => {
message => q{How long should we wait for the user to respond?},
lastUpdated => 1311363900,
},
'expireAfter label' => {
message => q{Expire After},
lastUpdated => 1311363885,
},
'okMessage label' => {
message => q{Confirmation Message},
lastUpdated => 1311612584,
},
'okMessage hoverHelp' => {
message => q{Message to display to the user when he clicks the confirm link},
lastUpdated => 1311612632,
},
'template hoverHelp' => {
message => q{Raw template code for the body of the email goes here.},
lastUpdated => 1311364201,
},
'template label' => {
message => q{Template},
lastUpdated => 1311364181,
},
'templateParser label' => {
message => q{Template Parser},
lastUpdated => 1311364015,
},
'topicName' => {
message => q{Wait For User Confirmation},
lastUpdated => 1311364913,
},
'waitBetween hoverHelp' => {
message => q{How long should we wait in between checks to see if the user has clicked the link?},
lastUpdated => 1311363934,
},
'waitBetween label' => {
message => q{Wait Interval},
lastUpdated => 1311363920,
},
'your template goes here' => {
message => q{Your template goes here!},
lastUpdated => 1311365274,
},
};
1;
#vim:ft=perl

View file

@ -2307,6 +2307,12 @@ normal templates.|,
context => q{Error message when trying to add too many tickets to a badge},
},
'clear form' => {
message => q|Clear|,
lastUpdated => 0,
context => q|a button on the add badge to clear the form|,
},
};
1;

View file

@ -74,6 +74,18 @@ our $I18N = {
context => q{Format for a column with a date},
},
"format textarea" => {
message => q{Textarea},
lastUpdated => 0,
context => q{Format for a textarea column},
},
"format htmlarea" => {
message => q{HTMLarea},
lastUpdated => 0,
context => q{Format for an HTMLarea column},
},
"add column" => {
message => q{Add Column},
lastUpdated => 0,
@ -152,6 +164,23 @@ our $I18N = {
context => q{The name of a newly added value to a column},
},
"data error" => {
message => q{Data error.},
lastUpdated => 0,
context => q{Message to display when DataTable has data error},
},
"sort ascending" => {
message => q{Click to sort ascending},
lastUpdated => 0,
context => q{Message to display in tooltip to sort Column in ascending order},
},
"sort descending" => {
message => q{Click to sort descending},
lastUpdated => 0,
context => q{Message to display in tooltip to sort Column in descending order},
},
};
1;

View file

@ -0,0 +1,50 @@
package WebGUI::i18n::English::PayDriver_AuthorizeNet;
use strict;
our $I18N = {
'cardType' => {
message => q{Card Type},
lastUpdated => 1101772177,
context => q{Form label in the checkout form of the AuthorizeNet module.},
},
'login' => {
message => q{API Login},
lastUpdated => 1247613128,
context => q{Form label in the configuration form of the AuthorizeNet module.},
},
'login help' => {
message => q{The API login id for your Authorize.net account},
lastUpdated => 1247613146,
context => q{Hover help for the login field of the AuthorizeNet module},
},
'name' => {
message => q{Credit Card (Authorize.net)},
lastUpdated => 0,
context => q{Name of the Authorize.net module},
},
'test mode' => {
message => q{Test Mode},
lastUpdated => 0,
context => q{Form label for test mode toggle in AuthroizeNet module},
},
'test mode help' => {
message => q{Whether calls using this gateway should be made in test mode},
lastUpdated => 0,
context => q{Hover help for test mode form field},
},
'transaction key' => {
message => q{Transaction Key},
lastUpdated => 1247613060,
context => q{Form label in the configuration form of the AuthorizeNet module.},
},
'transaction key help' => {
message => q{The Transaction Key for your Authorize.net account},
lastUpdated => 1247613119,
context => q{Hover help for the password field of the AuthorizeNet module},
},
};
1;
#vim:ft=perl

View file

@ -0,0 +1,161 @@
package WebGUI::i18n::English::PayDriver_CreditCard;
use strict;
our $I18N = {
'cardNumber' => {
message => q|Credit card number|,
lastUpdated => 1101772177,
context => q|Form label in the checkout form of the Credit Card module.|
},
'credentials template' => {
message => q|Credentials Template|,
lastUpdated => 0,
context => q|Form label in the configuration form of the Credit Card module.|
},
'credentials template help' => {
message => q|Pick a template to display the form where the user will enter in their billing information and credit card information.|,
lastUpdated => 0,
context => q|Hover help for the credentials template field in the configuration form of the Credit Card module.|
},
'cvv2' => {
message => q|Verification number (ie. CVV2)|,
lastUpdated => 1101772182,
context => q|Form label in the checkout form of the Credit Card module.|
},
'error occurred message' => {
message => q|The following errors occurred:|,
lastUpdated => 0,
context => q|The message that tell the user that there were some errors in their submitted credentials.|,
},
'expiration date' => {
message => q|Expiration date|,
lastUpdated => 1101772180,
context => q|Form label in the checkout form of the Credit Card module.|
},
'expired expiration date' => {
message => q|The expiration date on your card has already passed.|,
lastUpdated => 0,
context => q|An error indicating that an an expired card was used.|
},
'invalid firstName' => {
message => q|You have to enter a valid first name.|,
lastUpdated => 0,
context => q|An error indicating that an invalid first name has been entered.|
},
'invalid lastName' => {
message => q|You have to enter a valid last name.|,
lastUpdated => 0,
context => q|An error indicating that an invalid last name has been entered.|
},
'invalid address' => {
message => q|You have to enter a valid address.|,
lastUpdated => 0,
context => q|An error indicating that an invalid street has been entered.|
},
'invalid city' => {
message => q|You have to enter a valid city.|,
lastUpdated => 0,
context => q|An error indicating that an invalid city has been entered.|
},
'invalid zip' => {
message => q|You have to enter a valid zipcode.|,
lastUpdated => 0,
context => q|An error indicating that an invalid zipcode has been entered.|
},
'invalid email' => {
message => q|You have to enter a valid email address.|,
lastUpdated => 0,
context => q|An error indicating that an invalid email address has been entered.|
},
'invalid card number' => {
message => q|You have to enter a valid credit card number.|,
lastUpdated => 0,
context => q|An error indicating that an invalid credit card number has been entered.|
},
'invalid cvv2' => {
message => q|You have to enter a valid card security code (ie. cvv2).|,
lastUpdated => 0,
context => q|An error indicating that an invalid card security code has been entered.|
},
'invalid expiration date' => {
message => q|You have to enter a valid expiration date.|,
lastUpdated => 0,
context => q|An error indicating that an invalid expiration date has been entered.|
},
'template gone' => {
message => q|The template for entering in credentials has been deleted. Please notify the site administrator.|,
lastUpdated => 0,
context => q|Error message when the getCredentials template cannot be accessed.|
},
'use cvv2' => {
message => q|Use CVV2|,
lastUpdated => 0,
context => q|Form label in the configuration form of the Credit Card module.|
},
'use cvv2 help' => {
message => q|Set this option to yes if you want to use CVV2.|,
lastUpdated => 0,
context => q|Form label in the configuration form of the Credit Card module.|
},
'edit credentials template' => {
message => q|Edit Credentials Template|,
lastUpdated => 0,
context => q|Title of the help page.|
},
'edit credentials template help' => {
message => q|This template is used to display a form to the user where they can enter in contact and credit card billing information.|,
lastUpdated => 0,
context => q|Title of the help page.|
},
'errors help' => {
message => q{A template loop containing a list of errors from processing the form.},
lastUpdated => 0,
context => q{Template variable help.},
},
'error help' => {
message => q{One error from the errors loop. It will have minimal markup.},
lastUpdated => 0,
context => q{Template variable help.},
},
'addressField help' => {
message => q{A single text field for the user to enter in their street address.},
lastUpdated => 0,
context => q{Template variable help.},
},
'emailField help' => {
message => q{A single text field for the user to enter in their email address.},
lastUpdated => 1231192368,
context => q{Template variable help.},
},
'cardNumberField help' => {
message => q{A single text field for the user to enter in their credit card number.},
lastUpdated => 0,
context => q{Template variable help.},
},
'monthYearField help' => {
message => q{A combination form field for the user to enter in the month and year of the expiration date for the credit card.},
lastUpdated => 0,
context => q{Template variable help.},
},
'cvv2Field help' => {
message => q{A single text field for the user to enter in their credit card verification number. If the PayDriver is not configured to use CVV2, then this field will be empty.},
lastUpdated => 0,
context => q{Template variable help.},
},
'checkoutButton help' => {
message => q{A button with an internationalized label to submit the form and continue the checkout process.},
lastUpdated => 0,
context => q{Template variable help.},
},
'fields help' => {
message => q{A loop of all the available fields for convenience. Each
entry in the loop contains name (field name), label (an internationalized
label for the field), and field (the same as in stateField, cityField, etc).},
lastUpdated => 0,
},
};
1;

View file

@ -4776,6 +4776,18 @@ Users may override this setting in their profile.
context => 'Choose, as in to select from a set of options',
},
'Enable Users after Anonymous Registration?' => {
message => 'Enable Users after Anonymous Registration?',
lastUpdated => 1311618346,
},
'enableUsersAfterAnonymousRegistration help' => {
message => 'If this is off, '
. 'users must be manually activated by a workflow or an admin.',
lastUpdated => 1311618419,
},
};
1;

View file

@ -109,7 +109,8 @@ checkModule("XML::FeedPP", 0.40 );
checkModule("XML::FeedPP::MediaRSS", 0.02 );
checkModule("JSON", 2.12 );
checkModule("JSON::Any", 1.22 );
checkModule("Config::JSON", '1.5000' );
checkModule("JSON::PP", 0.00 );
checkModule("Config::JSON", "1.3.1" );
checkModule("Text::CSV_XS", "0.64" );
checkModule("Net::CIDR::Lite", 0.20 );
checkModule("Finance::Quote", 1.15 );
@ -154,6 +155,8 @@ checkModule("MooseX::NonMoose", '0.07' );
checkModule("MooseX::Storage::Format::JSON","0.27" );
checkModule("namespace::autoclean", "0.09" );
checkModule("Business::PayPal::API", "0.62" );
checkModule("Business::OnlinePayment", "3.01" );
checkModule("Business::OnlinePayment::AuthorizeNet", "3.21" );
checkModule("Locales", "0.10" );
checkModule("Test::Harness", "3.17" );
checkModule("DateTime::Event::ICal", "0.10" );
@ -176,6 +179,7 @@ checkModule('Starman', '0.2010', 2);
checkModule('App::Cmd', '0.311' );
checkModule('Devel::StackTrace', '1.27' );
checkModule('Devel::StackTrace::WithLexicals', '0.03' );
checkModule('Kwargs', );
checkModule('Data::ICal', '0.16' );
checkModule('common::sense', '3.2' );
checkModule('Geo::Coder::Googlev3', '0.07' );

View file

@ -365,7 +365,7 @@ user will be set to. It can be overridden in the import file for
specific users.
You can specify a unique expiration date for a group by adding it
after the group ID, seperated by a colon. The date/time should be in
after the group ID, separated by a colon. The date/time should be in
"YYYY-MM-DD HH:NN:SS" format.
groupId:2000-01-01 01:00:00,groupId2:2001-01-02 02:00:00

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show more