Merge remote branch 'main/WebGUI8' into WebGUI8
This commit is contained in:
commit
546932869a
156 changed files with 5488 additions and 582 deletions
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
BIN
docs/upgrades/packages-7.10.21/default_forum_notification.wgpkg
Normal file
BIN
docs/upgrades/packages-7.10.21/default_forum_notification.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.10.22/default_emsbadge.wgpkg
Normal file
BIN
docs/upgrades/packages-7.10.22/default_emsbadge.wgpkg
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
docs/upgrades/packages-7.10.23/stockdatatmpl000000001.wgpkg
Normal file
BIN
docs/upgrades/packages-7.10.23/stockdatatmpl000000001.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.9.34-7.10.22/merged.wgpkg
Normal file
BIN
docs/upgrades/packages-7.9.34-7.10.22/merged.wgpkg
Normal file
Binary file not shown.
146
docs/upgrades/upgrade_7.10.20-7.10.21.pl
Normal file
146
docs/upgrades/upgrade_7.10.20-7.10.21.pl
Normal 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
|
||||
198
docs/upgrades/upgrade_7.10.21-7.10.22.pl
Normal file
198
docs/upgrades/upgrade_7.10.21-7.10.22.pl
Normal 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
|
||||
141
docs/upgrades/upgrade_7.10.22-7.10.23.pl
Normal file
141
docs/upgrades/upgrade_7.10.22-7.10.23.pl
Normal 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
|
||||
561
docs/upgrades/upgrade_7.9.34-7.10.22.pl
Normal file
561
docs/upgrades/upgrade_7.9.34-7.10.22.pl
Normal 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
|
||||
|
|
@ -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" : [
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
package WebGUI;
|
||||
|
||||
|
||||
our $VERSION = '8.0.0';
|
||||
our $STATUS = 'beta';
|
||||
|
||||
|
||||
=head1 LEGAL
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ has method => (
|
|||
|
||||
has uid => (
|
||||
is => 'rw',
|
||||
default => 'view',
|
||||
default => '',
|
||||
);
|
||||
|
||||
has bare => (
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
||||
|
|
|
|||
|
|
@ -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")),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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});
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
145
lib/WebGUI/Content/PDFGenerator.pm
Normal file
145
lib/WebGUI/Content/PDFGenerator.pm
Normal 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;
|
||||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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') );
|
||||
|
|
|
|||
|
|
@ -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'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@ sub getOperations {
|
|||
'ajaxDeleteUser' => 'User',
|
||||
'ajaxUpdateUser' => 'User',
|
||||
'becomeUser' => 'User',
|
||||
'confirmUserEmail' => 'User',
|
||||
'deleteUser' => 'User',
|
||||
'editUser' => 'User',
|
||||
'editUserSave' => 'User',
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 } )
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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: $@");
|
||||
|
|
|
|||
227
lib/WebGUI/Shop/PayDriver/CreditCard.pm
Normal file
227
lib/WebGUI/Shop/PayDriver/CreditCard.pm
Normal 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;
|
||||
|
||||
256
lib/WebGUI/Shop/PayDriver/CreditCard/AuthorizeNet.pm
Normal file
256
lib/WebGUI/Shop/PayDriver/CreditCard/AuthorizeNet.pm
Normal 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;
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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}]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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'),
|
||||
|
|
|
|||
270
lib/WebGUI/Workflow/Activity/WaitForUserConfirmation.pm
Normal file
270
lib/WebGUI/Workflow/Activity/WaitForUserConfirmation.pm
Normal 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;
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
74
lib/WebGUI/i18n/English/Activity_WaitForUserConfirmation.pm
Normal file
74
lib/WebGUI/i18n/English/Activity_WaitForUserConfirmation.pm
Normal 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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
50
lib/WebGUI/i18n/English/PayDriver_AuthorizeNet.pm
Normal file
50
lib/WebGUI/i18n/English/PayDriver_AuthorizeNet.pm
Normal 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
|
||||
161
lib/WebGUI/i18n/English/PayDriver_CreditCard.pm
Normal file
161
lib/WebGUI/i18n/English/PayDriver_CreditCard.pm
Normal 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;
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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' );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
393
share/create.sql
393
share/create.sql
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
Loading…
Add table
Add a link
Reference in a new issue