Merge branch 'master' of git@github.com:plainblack/webgui
This commit is contained in:
commit
fa40b99182
52 changed files with 3081 additions and 3155 deletions
|
|
@ -1,3 +1,23 @@
|
|||
7.8.2
|
||||
- fixed #11098: Leaving a version tag makes everyone leave
|
||||
- fixed #11096: Error on deleting FAQ(CS)-item
|
||||
- fixed #11060: Some tables have latin1 as the default character set
|
||||
- fixed #11089: No message body in Notification
|
||||
- fixed #2569: robots.txt issues
|
||||
- fixed #11104: Wrong name for request tracker post form template
|
||||
- fixed #11077: Untested result in WebGUI::Storage->getFiles
|
||||
- fixed #11080: Asset Manage Crumb Trail flyout menu
|
||||
- fixed #10874: EMS Schedule displaying incorrectly
|
||||
- fixed #10956: Account, Profile system bad rendering with lots of
|
||||
- fixed #11112: story archive RSS feed
|
||||
- added Insurance estimator for the USPS shipping driver
|
||||
- fixed #11121: Syndicated Content search terms require both title and description match
|
||||
- fixed #11057: Deleting wiki attachments
|
||||
- fixed #11122: Survey icon is missing from admin console
|
||||
- fixed #11107: linked image with caption
|
||||
- fixed #10914: Shop: No email notifications sent when the cart has net value 0
|
||||
- fixed #11126: WebGUI database has varchar fields
|
||||
|
||||
7.8.1
|
||||
- mark $session->datetime->time as deprecated and remove its use from core code
|
||||
- fixed: Wikis broken by 7.8.0 upgrade
|
||||
|
|
@ -41,6 +61,8 @@
|
|||
- fixed #11049: form caching incorrectly
|
||||
- fixed #11088: i18n Survey Section Information
|
||||
- fixed #11087: SC asset repeats its own description in feeds
|
||||
- fixed #10916: png icon
|
||||
- fixed #11100: syncToCdn's help is not proper POD
|
||||
|
||||
7.8.0
|
||||
- upgraded YUI to 2.8.0r4
|
||||
|
|
|
|||
2322
docs/create.sql
2322
docs/create.sql
File diff suppressed because one or more lines are too long
|
|
@ -11,10 +11,26 @@ save you many hours of grief.
|
|||
--------------------------------------------------------------------
|
||||
|
||||
* The EventManagementSystem schedule template was accidently given
|
||||
the same namespace as the main EMS template. This allowed the
|
||||
wrong template to be chosen for the main EMS template and the
|
||||
schedule template. The upgrade from 7.8.0 to 7.8.1 will attempt
|
||||
to fix this when default templates have been used.
|
||||
the same namespace as the main EMS template. This allowed the
|
||||
wrong template to be chosen for the main EMS template and the
|
||||
schedule template. The upgrade from 7.8.0 to 7.8.1 will attempt
|
||||
to fix this when default templates have been used.
|
||||
|
||||
* In the past, it was possible to leave WebguiRoot undefined
|
||||
or incorrectly specified, and WebGUI would still function. It
|
||||
must now be properly specified, which means it must be configured
|
||||
in the global Apache section (outside any VirtualHost or
|
||||
Directory sections) and point to the correct WebGUI root
|
||||
directory. For example:
|
||||
PerlSetVar WebguiRoot /data/WebGUI
|
||||
|
||||
* WebGUI creates thumbnails for uploaded images. The name for
|
||||
those thumbnail files is created by prepending "thumb-" to the
|
||||
name of the file. If a file that start with "thumb-" is created
|
||||
then WebGUI would throw an error. Starting with 7.8.1, files
|
||||
that start with "thumb-" will be renamed by removing that
|
||||
prefix from the filename.
|
||||
|
||||
|
||||
7.8.0
|
||||
--------------------------------------------------------------------
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
BIN
docs/upgrades/packages-7.8.2/request-tracker-template2.wgpkg
Normal file
BIN
docs/upgrades/packages-7.8.2/request-tracker-template2.wgpkg
Normal file
Binary file not shown.
BIN
docs/upgrades/packages-7.8.2/robots.txt.wgpkg
Normal file
BIN
docs/upgrades/packages-7.8.2/robots.txt.wgpkg
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
docs/upgrades/packages-7.8.2/root_import_article.wgpkg
Normal file
BIN
docs/upgrades/packages-7.8.2/root_import_article.wgpkg
Normal file
Binary file not shown.
|
|
@ -137,18 +137,38 @@ sub moveCalendarFeedsToJSON {
|
|||
sub removeOrphanedVersionTags {
|
||||
my $session = shift;
|
||||
print "\tRemoving orphan version tags (this may take a while)... " unless $quiet;
|
||||
|
||||
# Get all Version Tag ids
|
||||
my %tags = map { $_ => 1 } @{$session->db->buildArrayRef("SELECT tagId FROM assetVersionTag")};
|
||||
#print "\nSite has " . keys(%tags) . " Version Tags in total\n" unless $quiet;
|
||||
|
||||
# Get all Version Tags with associated assetData
|
||||
my %tags_with_data = map { $_ => 1 } @{$session->db->buildArrayRef("SELECT tagId FROM assetData")};
|
||||
#print "* " . keys(%tags_with_data) . " with associated assetData\n" unless $quiet;
|
||||
|
||||
# Figure out the set of ophans
|
||||
my @orphans = grep { !$tags_with_data{$_} } keys %tags;
|
||||
#print "* " . scalar(@orphans) . " orphans\n" unless $quiet;
|
||||
|
||||
# Sanity check
|
||||
if (keys(%tags) - keys(%tags_with_data) != scalar(@orphans)) { die "Something is broken in your Version Tag table" }
|
||||
|
||||
my $sth = $session->db->read(
|
||||
"SELECT tagId FROM assetVersionTag",
|
||||
);
|
||||
while ( my ($tagId) = $sth->array ) {
|
||||
if ( !$session->db->quickScalar(
|
||||
"SELECT COUNT(*) FROM assetData WHERE tagId=?",
|
||||
[ $tagId ]
|
||||
) ) {
|
||||
my $tag = WebGUI::VersionTag->new( $session, $tagId );
|
||||
$tag->rollback;
|
||||
# Remove the orphans
|
||||
my $count = 0;
|
||||
for my $tagId (@orphans) {
|
||||
|
||||
# Progress
|
||||
if ($count % 100 == 0) { print '*' unless $quiet; }
|
||||
|
||||
# Double-check on reduced set (remove to speed up even further)
|
||||
if ( $session->db->quickScalar("SELECT COUNT(*) FROM assetData WHERE tagId=?", [ $tagId ]) ) {
|
||||
die "Version Tag was supposed to be an orphan, but had assetData: $tagId";
|
||||
}
|
||||
|
||||
my $tag = WebGUI::VersionTag->new( $session, $tagId );
|
||||
$tag->rollback;
|
||||
|
||||
$count++;
|
||||
}
|
||||
|
||||
print "DONE!\n" unless $quiet;
|
||||
|
|
|
|||
256
docs/upgrades/upgrade_7.8.1-7.8.2.pl
Normal file
256
docs/upgrades/upgrade_7.8.1-7.8.2.pl
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
|
||||
#-------------------------------------------------------------------
|
||||
# Please read the legal notices (docs/legal.txt) and the license
|
||||
# (docs/license.txt) that came with this distribution before using
|
||||
# this software.
|
||||
#-------------------------------------------------------------------
|
||||
# http://www.plainblack.com info@plainblack.com
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
our ($webguiRoot);
|
||||
|
||||
BEGIN {
|
||||
$webguiRoot = "../..";
|
||||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Storage;
|
||||
use WebGUI::Asset;
|
||||
use WebGUI::Shop::Pay;
|
||||
use WebGUI::Shop::PayDriver;
|
||||
|
||||
my $toVersion = '7.8.2';
|
||||
my $quiet; # this line required
|
||||
|
||||
|
||||
my $session = start(); # this line required
|
||||
|
||||
fixTableDefaultCharsets($session);
|
||||
correctWikiAttachmentPermissions( $session );
|
||||
transactionsNotifications( $session );
|
||||
fixBadVarCharColumns ( $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 fixTableDefaultCharsets {
|
||||
my $session = shift;
|
||||
my $db = $session->db;
|
||||
print "\tFixing default character set on tables... " unless $quiet;
|
||||
my @tables = qw(
|
||||
Carousel Collaboration DataTable Map MapPoint MatrixListing
|
||||
MatrixListing_attribute Story StoryArchive StoryTopic
|
||||
Survey_questionTypes Survey_test ThingyRecord ThingyRecord_record
|
||||
adSkuPurchase assetAspectComments assetAspectRssFeed
|
||||
filePumpBundle inbox_messageState taxDriver tax_eu_vatNumbers
|
||||
template_attachments
|
||||
);
|
||||
for my $table (@tables) {
|
||||
$db->write(
|
||||
sprintf('ALTER TABLE %s DEFAULT CHARACTER SET = ?', $db->dbh->quote_identifier($table)),
|
||||
['utf8'],
|
||||
);
|
||||
}
|
||||
my $db_name = $db->dbh->{Name};
|
||||
my $database = (split /[;:]/, $db_name)[0];
|
||||
while ( $db_name =~ /([^=;:]+)=([^;:]+)/msxg ) {
|
||||
if ( $1 eq 'db' || $1 eq 'database' || $1 eq 'dbname' ) {
|
||||
$database = $2;
|
||||
last;
|
||||
}
|
||||
}
|
||||
$session->db->write(sprintf 'ALTER DATABASE %s DEFAULT CHARACTER SET utf8', $db->dbh->quote_identifier($database));
|
||||
|
||||
print "Done.\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
sub correctWikiAttachmentPermissions {
|
||||
my $session = shift;
|
||||
print "\tCorrect group edit permission on wiki page attachments... " unless $quiet;
|
||||
my $root = WebGUI::Asset->getRoot($session);
|
||||
my $pageIterator = $root->getLineageIterator(
|
||||
['descendants'],
|
||||
{
|
||||
includeOnlyClasses => ['WebGUI::Asset::WikiPage'],
|
||||
}
|
||||
);
|
||||
PAGE: while (my $wikiPage = $pageIterator->()) {
|
||||
my $wiki = $wikiPage->getWiki;
|
||||
next PAGE unless $wiki && $wiki->get('allowAttachments') && $wikiPage->getChildCount;
|
||||
foreach my $attachment (@{ $wikiPage->getLineage(['children'])}) {
|
||||
$attachment->update({ groupIdEdit => $wiki->get('groupToEditPages') });
|
||||
}
|
||||
}
|
||||
print "Done.\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
sub transactionsNotifications {
|
||||
my $session = shift;
|
||||
print "\tMove Shop notifications from PayDriver to Transactions... " unless $quiet;
|
||||
my $pay = WebGUI::Shop::Pay->new($session);
|
||||
my $gateways = $pay->getPaymentGateways;
|
||||
my $defaultNotificationGroup = '3';
|
||||
my $defaultTemplate = 'bPz1yk6Y9uwMDMBcmMsSCg';
|
||||
if (@{ $gateways }) {
|
||||
my $firstGateway = $gateways->[0];
|
||||
$defaultNotificationGroup = $firstGateway->get('saleNotificationGroupId');
|
||||
$defaultTemplate = $firstGateway->get('receiptEmailTemplateId' );
|
||||
foreach my $gateway (@{ $gateways }) {
|
||||
my $properties = $gateway->get();
|
||||
delete $properties->{ saleNotificationGroupId };
|
||||
delete $properties->{ receiptEmailTemplateId };
|
||||
$gateway->update($properties);
|
||||
}
|
||||
}
|
||||
$session->setting->add('shopSaleNotificationGroupId', $defaultNotificationGroup);
|
||||
$session->setting->add('shopReceiptEmailTemplateId', $defaultTemplate);
|
||||
print "Done.\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
sub fixBadVarCharColumns {
|
||||
my $session = shift;
|
||||
print "\tGive all revisionDate columns the correct definition... " unless $quiet;
|
||||
my @dataSets = (
|
||||
[ 'AdSku', 'assetId', "CHAR(22) BINARY NOT NULL" ],
|
||||
[ 'AdSku', 'purchaseTemplate', "CHAR(22) BINARY NOT NULL" ],
|
||||
[ 'AdSku', 'manageTemplate', "CHAR(22) BINARY NOT NULL" ],
|
||||
[ 'AdSku', 'adSpace', "CHAR(22) BINARY NOT NULL" ],
|
||||
[ 'AdSku', 'clickDiscounts', "CHAR(22) DEFAULT NULL" ],
|
||||
[ 'AdSku', 'impressionDiscounts', "CHAR(22) DEFAULT NULL" ],
|
||||
[ 'Collaboration', 'replyRichEditor', "CHAR(22) BINARY DEFAULT 'PBrichedit000000000002'" ],
|
||||
[ 'Collaboration', 'replyFilterCode', "CHAR(30) BINARY DEFAULT 'javascript'" ],
|
||||
[ 'DataForm', 'htmlAreaRichEditor', "CHAR(22) BINARY DEFAULT '**Use_Default_Editor**'" ],
|
||||
[ 'MapPoint', 'website', "CHAR(22) BINARY DEFAULT NULL" ],
|
||||
[ 'MapPoint', 'address1', "CHAR(22) BINARY DEFAULT NULL" ],
|
||||
[ 'MapPoint', 'address2', "CHAR(22) BINARY DEFAULT NULL" ],
|
||||
[ 'MapPoint', 'city', "CHAR(22) BINARY DEFAULT NULL" ],
|
||||
[ 'MapPoint', 'state', "CHAR(22) BINARY DEFAULT NULL" ],
|
||||
[ 'MapPoint', 'zipCode', "CHAR(22) BINARY DEFAULT NULL" ],
|
||||
[ 'MapPoint', 'country', "CHAR(22) BINARY DEFAULT NULL" ],
|
||||
[ 'MapPoint', 'phone', "CHAR(22) BINARY DEFAULT NULL" ],
|
||||
[ 'MapPoint', 'fax', "CHAR(22) BINARY DEFAULT NULL" ],
|
||||
[ 'MapPoint', 'email', "CHAR(22) BINARY DEFAULT NULL" ],
|
||||
[ 'Survey', 'onSurveyEndWorkflowId',"CHAR(22) BINARY DEFAULT NULL" ],
|
||||
[ 'Survey_questionTypes', 'questionType', "CHAR(56) NOT NULL" ],
|
||||
[ 'bucketLog', 'userId', "CHAR(22) BINARY NOT NULL" ],
|
||||
[ 'bucketLog', 'Bucket', "CHAR(22) BINARY NOT NULL" ],
|
||||
[ 'deltaLog', 'userId', "CHAR(22) BINARY NOT NULL" ],
|
||||
[ 'deltaLog', 'assetId', "CHAR(22) BINARY NOT NULL" ],
|
||||
[ 'deltaLog', 'url', "CHAR(255) NOT NULL" ],
|
||||
[ 'passiveAnalyticsStatus', 'userId', "CHAR(255) NOT NULL" ],
|
||||
[ 'passiveLog', 'url', "CHAR(255) NOT NULL" ],
|
||||
[ 'passiveLog', 'userId', "CHAR(22) BINARY NOT NULL" ],
|
||||
[ 'passiveLog', 'assetId', "CHAR(22) BINARY NOT NULL" ],
|
||||
[ 'passiveLog', 'sessionId', "CHAR(22) BINARY NOT NULL" ],
|
||||
);
|
||||
foreach my $dataSet (@dataSets) {
|
||||
$session->db->write(sprintf "ALTER TABLE `%s` MODIFY COLUMN `%s` %s", @{ $dataSet });
|
||||
}
|
||||
print "Done.\n" unless $quiet;
|
||||
}
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add a package to the import node
|
||||
sub addPackage {
|
||||
my $session = shift;
|
||||
my $file = shift;
|
||||
|
||||
# Make a storage location for the package
|
||||
my $storage = WebGUI::Storage->createTemp( $session );
|
||||
$storage->addFileFromFilesystem( $file );
|
||||
|
||||
# Import the package into the import node
|
||||
my $package = eval { WebGUI::Asset->getImportNode($session)->importPackage( $storage, { overwriteLatest => 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.";
|
||||
}
|
||||
|
||||
# Turn off the package flag, and set the default flag for templates added
|
||||
my $assetIds = $package->getLineage( ['self','descendants'] );
|
||||
for my $assetId ( @{ $assetIds } ) {
|
||||
my $asset = WebGUI::Asset->newByDynamicClass( $session, $assetId );
|
||||
if ( !$asset ) {
|
||||
print "Couldn't instantiate asset with ID '$assetId'. Please check package '$file' for corruption.\n";
|
||||
next;
|
||||
}
|
||||
my $properties = { isPackage => 0 };
|
||||
if ($asset->isa('WebGUI::Asset::Template')) {
|
||||
$properties->{isDefault} = 1;
|
||||
}
|
||||
$asset->update( $properties );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub start {
|
||||
my $configFile;
|
||||
$|=1; #disable output buffering
|
||||
GetOptions(
|
||||
'configFile=s'=>\$configFile,
|
||||
'quiet'=>\$quiet
|
||||
);
|
||||
my $session = WebGUI::Session->open($webguiRoot,$configFile);
|
||||
$session->user({userId=>3});
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Upgrade to ".$toVersion});
|
||||
return $session;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub finish {
|
||||
my $session = shift;
|
||||
updateTemplates($session);
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->commit;
|
||||
$session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".time().")");
|
||||
$session->close();
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub updateTemplates {
|
||||
my $session = shift;
|
||||
return undef unless (-d "packages-".$toVersion);
|
||||
print "\tUpdating packages.\n" unless ($quiet);
|
||||
opendir(DIR,"packages-".$toVersion);
|
||||
my @files = readdir(DIR);
|
||||
closedir(DIR);
|
||||
my $newFolder = undef;
|
||||
foreach my $file (@files) {
|
||||
next unless ($file =~ /\.wgpkg$/);
|
||||
# Fix the filename to include a path
|
||||
$file = "packages-" . $toVersion . "/" . $file;
|
||||
addPackage( $session, $file );
|
||||
}
|
||||
}
|
||||
|
||||
#vim:ft=perl
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package WebGUI;
|
||||
|
||||
|
||||
our $VERSION = '7.8.1';
|
||||
our $VERSION = '7.8.2';
|
||||
our $STATUS = 'beta';
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1222,19 +1222,20 @@ An integer indicating either thumbss up (+1) or thumbs down (-1)
|
|||
=cut
|
||||
|
||||
sub rate {
|
||||
my $self = shift;
|
||||
my $self = shift;
|
||||
my $rating = shift;
|
||||
return undef unless ($rating == -1 || $rating == 1);
|
||||
return undef if $self->hasRated;
|
||||
my $session = $self->session;
|
||||
$self->insertUserPostRating($rating);
|
||||
$self->recalculatePostRating();
|
||||
my $thread = $self->getThread;
|
||||
$thread->updateThreadRating();
|
||||
if ($self->session->setting->get("useKarma")
|
||||
&& $self->session->user->karma > $thread->getParent->get('karmaSpentToRate')) {
|
||||
$self->session->user->karma(-$self->getThread->getParent->get("karmaSpentToRate"), "Rated Post ".$self->getId, "Rated a CS Post.");
|
||||
my $u = WebGUI::User->new($self->session, $self->get("ownerUserId"));
|
||||
$u->karma($self->getThread->getParent->get("karmaRatingMultiplier"), "Post ".$self->getId." Rated by ".$self->session->user->userId, "Had post rated.");
|
||||
if ($session->setting->get("useKarma")
|
||||
&& $session->user->karma > $thread->getParent->get('karmaSpentToRate')) {
|
||||
$session->user->karma(-$thread->getParent->get("karmaSpentToRate"), "Rated Post ".$self->getId, "Rated a CS Post.");
|
||||
my $u = WebGUI::User->new($session, $self->get("ownerUserId"));
|
||||
$u->karma($thread->getParent->get("karmaRatingMultiplier"), "Post ".$self->getId." Rated by ".$session->user->userId, "Had post rated.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -974,15 +974,17 @@ sub updateThreadRating {
|
|||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
|
||||
my $calcRating = 0;
|
||||
my $postIds = $self->getLineage(["descendants","self"], {
|
||||
includeOnlyClasses => ["WebGUI::Asset::Post","WebGUI::Asset::Post::Thread"],
|
||||
includeArchived => 1,
|
||||
});
|
||||
|
||||
$calcRating += $session->db->quickScalar(
|
||||
"SELECT SUM(rating) FROM Post_rating WHERE assetId IN (".$session->db->quoteAndJoin($postIds).")"
|
||||
);
|
||||
my $calcRating = 0;
|
||||
if (scalar @{ $postIds }) {
|
||||
$calcRating += $session->db->quickScalar(
|
||||
"SELECT SUM(rating) FROM Post_rating WHERE assetId IN (".$session->db->quoteAndJoin($postIds).")"
|
||||
);
|
||||
}
|
||||
|
||||
$self->update({
|
||||
threadRating => $calcRating
|
||||
|
|
@ -991,7 +993,8 @@ sub updateThreadRating {
|
|||
my $parent = $self->getParent;
|
||||
if (defined $parent) {
|
||||
$parent->recalculateRating;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
$self->session->errorHandler->error("Couldn't get parent for thread ".$self->getId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -537,7 +537,7 @@ sub getRssData {
|
|||
my $self = shift;
|
||||
my $data = {
|
||||
title => $self->get('headline') || $self->getTitle,
|
||||
description => $self->get('subtitle'),
|
||||
description => $self->get('story'),
|
||||
'link' => $self->getUrl,
|
||||
author => $self->get('byline'),
|
||||
date => $self->get('lastModified'),
|
||||
|
|
|
|||
|
|
@ -398,21 +398,22 @@ Extends the master method to handle properties and attachments.
|
|||
=cut
|
||||
|
||||
sub processPropertiesFromFormPost {
|
||||
my $self = shift;
|
||||
$self->next::method(@_);
|
||||
my $actionTaken = ($self->session->form->process("assetId") eq "new") ? "Created" : "Edited";
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
$self->next::method(@_);
|
||||
my $actionTaken = ($session->form->process("assetId") eq "new") ? "Created" : "Edited";
|
||||
my $wiki = $self->getWiki;
|
||||
my $properties = {
|
||||
groupIdView => $wiki->get('groupIdView'),
|
||||
groupIdEdit => $wiki->get('groupToAdminister'),
|
||||
actionTakenBy => $self->session->user->userId,
|
||||
actionTaken => $actionTaken,
|
||||
};
|
||||
my $properties = {
|
||||
groupIdView => $wiki->get('groupIdView'),
|
||||
groupIdEdit => $wiki->get('groupToAdminister'),
|
||||
actionTakenBy => $self->session->user->userId,
|
||||
actionTaken => $actionTaken,
|
||||
};
|
||||
|
||||
if ($wiki->canAdminister) {
|
||||
$properties->{isProtected} = $self->session->form->get("isProtected");
|
||||
$properties->{isFeatured} = $self->session->form->get("isFeatured");
|
||||
}
|
||||
if ($wiki->canAdminister) {
|
||||
$properties->{isProtected} = $session->form->get("isProtected");
|
||||
$properties->{isFeatured} = $session->form->get("isFeatured");
|
||||
}
|
||||
|
||||
$self->update($properties);
|
||||
|
||||
|
|
@ -421,17 +422,17 @@ sub processPropertiesFromFormPost {
|
|||
maxImageSize => $wiki->get('maxImageSize'),
|
||||
thumbnailSize => $wiki->get('thumbnailSize'),
|
||||
};
|
||||
my @attachments = $self->session->form->param("attachments");
|
||||
my @attachments = $session->form->param("attachments");
|
||||
my @tags = ();
|
||||
foreach my $assetId (@attachments) {
|
||||
my $asset = WebGUI::Asset->newByDynamicClass($self->session, $assetId);
|
||||
my $asset = WebGUI::Asset->newByDynamicClass($session, $assetId);
|
||||
if (defined $asset) {
|
||||
unless ($asset->get("parentId") eq $self->getId) {
|
||||
$asset->setParent($self);
|
||||
$asset->update({
|
||||
ownerUserId => $self->get("ownerUserId"),
|
||||
groupIdEdit => $self->get("groupIdEdit"),
|
||||
groupIdView => $self->get("groupIdView"),
|
||||
ownerUserId => $self->get( "ownerUserId" ),
|
||||
groupIdEdit => $wiki->get( "groupToEditPages" ),
|
||||
groupIdView => $self->get( "groupIdView" ),
|
||||
});
|
||||
}
|
||||
$asset->applyConstraints($options);
|
||||
|
|
|
|||
|
|
@ -692,15 +692,18 @@ test suite.
|
|||
|
||||
sub getAdminConsole {
|
||||
my $self = shift;
|
||||
my $ac = WebGUI::AdminConsole->new( $self->session, 'Survey' );
|
||||
my $i18n = WebGUI::International->new($self->session, "Asset_Survey");
|
||||
$ac->addSubmenuItem($self->session->url->page("func=edit"), WebGUI::International->new($self->session, "WebGUI")->get(575));
|
||||
$ac->addSubmenuItem($self->session->url->page("func=editSurvey"), $i18n->get('edit survey'));
|
||||
$ac->addSubmenuItem($self->session->url->page("func=takeSurvey"), $i18n->get('take survey'));
|
||||
$ac->addSubmenuItem($self->session->url->page("func=graph"), $i18n->get('visualize'));
|
||||
$ac->addSubmenuItem($self->session->url->page("func=editTestSuite"), $i18n->get("test suite"));
|
||||
$ac->addSubmenuItem($self->session->url->page("func=runTests"), $i18n->get("run all tests"));
|
||||
$ac->addSubmenuItem($self->session->url->page("func=runTests;format=tap"), $i18n->get("run all tests") . " (TAP)");
|
||||
my $ac = $self->SUPER::getAdminConsole;
|
||||
unless ($self->{_modifiedAdminConsole}) {
|
||||
my $i18n = WebGUI::International->new($self->session, "Asset_Survey");
|
||||
$ac->addSubmenuItem($self->session->url->page("func=edit"), WebGUI::International->new($self->session, "WebGUI")->get(575));
|
||||
$ac->addSubmenuItem($self->session->url->page("func=editSurvey"), $i18n->get('edit survey'));
|
||||
$ac->addSubmenuItem($self->session->url->page("func=takeSurvey"), $i18n->get('take survey'));
|
||||
$ac->addSubmenuItem($self->session->url->page("func=graph"), $i18n->get('visualize'));
|
||||
$ac->addSubmenuItem($self->session->url->page("func=editTestSuite"), $i18n->get("test suite"));
|
||||
$ac->addSubmenuItem($self->session->url->page("func=runTests"), $i18n->get("run all tests"));
|
||||
$ac->addSubmenuItem($self->session->url->page("func=runTests;format=tap"), $i18n->get("run all tests") . " (TAP)");
|
||||
$self->{_modifiedAdminConsole} = 1;
|
||||
}
|
||||
return $ac;
|
||||
}
|
||||
|
||||
|
|
@ -2002,6 +2005,7 @@ sub prepareShowSurveyTemplate {
|
|||
$section->{allowBackBtn} = $self->get('allowBackBtn');
|
||||
|
||||
my $out = $self->processTemplate( $section, $self->get('surveyQuestionsId') );
|
||||
WebGUI::Macro::process($self->session, \$out);
|
||||
|
||||
$self->session->http->setMimeType('application/json');
|
||||
return to_json( { type => 'displayquestions', section => $section, questions => $questions, html => $out } );
|
||||
|
|
|
|||
|
|
@ -165,15 +165,17 @@ sub generateFeed {
|
|||
if ($self->get('hasTerms') ne '') {
|
||||
my @terms = split /,\s*/, $self->get('hasTerms'); # get the list of terms
|
||||
my $termRegex = join("|", map quotemeta($_), @terms); # turn the terms into a regex string
|
||||
my @items = $feed->match_item(title=>qr/$termRegex/msi, description=>qr/$termRegex/msi);
|
||||
my @items = $feed->match_item(title => qr/$termRegex/msi);
|
||||
push @items, $feed->match_item(description => qr/$termRegex/msi);
|
||||
$feed->clear_item;
|
||||
$feed->uniq_item;
|
||||
foreach my $item (@items) {
|
||||
$feed->add_item($item);
|
||||
}
|
||||
}
|
||||
|
||||
# sort them by date
|
||||
$feed->sort_item();
|
||||
# sort them by date and remove any duplicate from the OR based term matching above
|
||||
$feed->normalize();
|
||||
|
||||
# limit the feed to the maximum number of headlines (or the feed generator limit).
|
||||
$feed->limit_item($limit);
|
||||
|
|
|
|||
|
|
@ -599,14 +599,18 @@ sub _splitMysql
|
|||
(\d+) # Month
|
||||
\D*
|
||||
(\d+) # Day
|
||||
\D*
|
||||
(\d+) # Hours
|
||||
\D*
|
||||
(\d+) # Minutes
|
||||
\D*
|
||||
(\d+) # Seconds
|
||||
(?: \D*
|
||||
(\d+) # Hours
|
||||
\D*
|
||||
(\d+) # Minutes
|
||||
\D*
|
||||
(\d+) # Seconds
|
||||
)?
|
||||
}x;
|
||||
|
||||
foreach my $unit (qw/hour minute second/) {
|
||||
$hash{$unit} = 0 if ($hash{$unit} eq '');
|
||||
}
|
||||
return %hash;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ is updated.
|
|||
|
||||
=head3 users
|
||||
|
||||
An array reference containing a list of users.
|
||||
An array reference containing a list of userIds.
|
||||
|
||||
=head3 expireOffset
|
||||
|
||||
|
|
|
|||
|
|
@ -115,7 +115,8 @@ sub addHeaderField {
|
|||
my $self = shift;
|
||||
my $name = shift;
|
||||
my $value = shift;
|
||||
$self->getMimeEntity->head->add($name, $value);
|
||||
#$self->getMimeEntity->head->add($name, $value);
|
||||
$self->getMimeEntity->head->add($name, encode('MIME-Q', $value));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -464,7 +464,7 @@ A reference to the current session.
|
|||
|
||||
sub www_leaveVersionTag {
|
||||
my $session = shift;
|
||||
WebGUI::VersionTag->getWorking($session)->clearWorking;
|
||||
WebGUI::VersionTag->getWorking($session)->leaveTag;
|
||||
return www_manageVersions($session);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -194,6 +194,19 @@ sub www_editSettings {
|
|||
label => $i18n->get("my purchases detail template"),
|
||||
hoverHelp => $i18n->get("my purchases detail template help"),
|
||||
);
|
||||
$form->template(
|
||||
name => 'receiptEmailTemplateId',
|
||||
namespace => "Shop/EmailReceipt",
|
||||
label => $i18n->get("receipt email template"),
|
||||
hoverHelp => $i18n->get("receipt email template help"),
|
||||
defaultValue => 'bPz1yk6Y9uwMDMBcmMsSCg',
|
||||
);
|
||||
$form->group(
|
||||
name => 'saleNotificationGroupId',
|
||||
label => $i18n->get("sale notification group"),
|
||||
hoverHelp => $i18n->get("sale notification group help"),
|
||||
defaultValue => '3',
|
||||
);
|
||||
$form->submit;
|
||||
return $ac->render($form->print, $i18n->get("shop settings"));
|
||||
}
|
||||
|
|
@ -213,12 +226,12 @@ sub www_editSettingsSave {
|
|||
|
||||
# Save shop templates
|
||||
foreach my $template (qw(shopMyPurchasesDetailTemplateId shopMyPurchasesTemplateId
|
||||
shopCartTemplateId shopAddressBookTemplateId shopAddressTemplateId)) {
|
||||
shopCartTemplateId shopAddressBookTemplateId shopAddressTemplateId shopReceiptEmailTemplateId)) {
|
||||
$setting->set($template, $form->get($template, "template"));
|
||||
}
|
||||
|
||||
# Save group settings
|
||||
foreach my $group (qw(groupIdCashier groupIdAdminCommerce)) {
|
||||
foreach my $group (qw(groupIdCashier groupIdAdminCommerce shopSaleNotificationGroupId)) {
|
||||
$setting->set($group, $form->get($group, "group"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -413,6 +413,7 @@ sub www_selectPaymentGateway {
|
|||
my $transaction = WebGUI::Shop::Transaction->create($session, {cart => $cart});
|
||||
$transaction->completePurchase('zero', 'success', 'success');
|
||||
$cart->onCompletePurchase;
|
||||
$transaction->sendNotifications();
|
||||
return $transaction->thankYou();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -237,19 +237,6 @@ sub definition {
|
|||
hoverHelp => $i18n->get('who can use help'),
|
||||
defaultValue => 7,
|
||||
},
|
||||
receiptEmailTemplateId => {
|
||||
fieldType => 'template',
|
||||
namespace => "Shop/EmailReceipt",
|
||||
label => $i18n->get("receipt email template"),
|
||||
hoverHelp => $i18n->get("receipt email template help"),
|
||||
defaultValue => 'bPz1yk6Y9uwMDMBcmMsSCg',
|
||||
},
|
||||
saleNotificationGroupId => {
|
||||
fieldType => 'group',
|
||||
label => $i18n->get("sale notification group"),
|
||||
hoverHelp => $i18n->get("sale notification group help"),
|
||||
defaultValue => '3',
|
||||
},
|
||||
);
|
||||
|
||||
my %properties = (
|
||||
|
|
@ -662,7 +649,7 @@ sub processTransaction {
|
|||
if ($success) {
|
||||
$transaction->completePurchase($transactionCode, $statusCode, $statusMessage);
|
||||
$cart->onCompletePurchase;
|
||||
$self->sendNotifications($transaction);
|
||||
$transaction->sendNotifications();
|
||||
}
|
||||
else {
|
||||
$transaction->denyPurchase($transactionCode, $statusCode, $statusMessage);
|
||||
|
|
@ -680,49 +667,6 @@ Accessor for the session object. Returns the session object.
|
|||
|
||||
=cut
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 sendNotifications ( transaction )
|
||||
|
||||
Sends out a receipt and a sale notification to the buyer and the store owner respectively.
|
||||
|
||||
=cut
|
||||
|
||||
sub sendNotifications {
|
||||
my ($self, $transaction) = @_;
|
||||
my $session = $self->session;
|
||||
my $i18n = WebGUI::International->new($session, 'PayDriver');
|
||||
my $url = $session->url;
|
||||
my $var = $transaction->getTransactionVars;
|
||||
|
||||
# render
|
||||
my $template = WebGUI::Asset::Template->new( $session, $self->get("receiptEmailTemplateId") );
|
||||
my $inbox = WebGUI::Inbox->new($session);
|
||||
my $receipt = $template->process( $var );
|
||||
WebGUI::Macro::process($session, \$receipt);
|
||||
|
||||
# purchase receipt
|
||||
$inbox->addMessage( {
|
||||
message => $receipt,
|
||||
subject => $i18n->get('receipt subject') . ' ' . $transaction->get('orderNumber'),
|
||||
userId => $transaction->get('userId'),
|
||||
status => 'completed',
|
||||
} );
|
||||
|
||||
# shop owner notification
|
||||
# Shop owner uses method=view rather than method=viewMy
|
||||
$var->{viewDetailUrl} = $url->page( 'shop=transaction;method=view;transactionId='.$transaction->getId, 1 );
|
||||
my $notification = $template->process( $var );
|
||||
WebGUI::Macro::process($session, \$notification);
|
||||
$inbox->addMessage( {
|
||||
message => $notification,
|
||||
subject => $i18n->get('a sale has been made') . ' ' . $transaction->get('orderNumber'),
|
||||
groupId => $self->get('saleNotificationGroupId'),
|
||||
status => 'unread',
|
||||
} );
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 update ( $options )
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ sub calculate {
|
|||
}
|
||||
##Summarize costs from returned data
|
||||
$cost = $self->_calculateFromXML($xmlData, @shippableUnits);
|
||||
$cost += $self->_calculateInsurance(@shippableUnits);
|
||||
return $cost;
|
||||
}
|
||||
|
||||
|
|
@ -208,6 +209,74 @@ sub _calculateFromXML {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 _calculateInsurance ( @shippableUnits )
|
||||
|
||||
Takes data from the USPS and returns the calculated shipping price.
|
||||
|
||||
=head3 @shippableUnits
|
||||
|
||||
The set of shippable units, which are required to do quantity and cost lookups.
|
||||
|
||||
=cut
|
||||
|
||||
sub _calculateInsurance {
|
||||
my ($self, @shippableUnits) = @_;
|
||||
my $insuranceCost = 0;
|
||||
return $insuranceCost unless $self->get('addInsurance') && $self->get('insuranceRates');
|
||||
my @insuranceTable = _parseInsuranceRates($self->get('insuranceRates'));
|
||||
##Sort by decreasing value for easy post processing
|
||||
@insuranceTable = sort { $a->[0] <=> $b->[0] } @insuranceTable;
|
||||
foreach my $package (@shippableUnits) {
|
||||
my $value = 0;
|
||||
ITEM: foreach my $item (@{ $package }) {
|
||||
$value += $item->getSku->getPrice() * $item->get('quantity');
|
||||
}
|
||||
my $pricePoint;
|
||||
POINT: foreach my $point (@insuranceTable) {
|
||||
if ($value < $point->[0]) {
|
||||
$pricePoint = $point;
|
||||
last POINT;
|
||||
}
|
||||
}
|
||||
if (!defined $pricePoint) {
|
||||
$pricePoint = $insuranceTable[-1];
|
||||
}
|
||||
$insuranceCost += $pricePoint->[1];
|
||||
}
|
||||
return $insuranceCost;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 _parseInsuranceRates ( $rates )
|
||||
|
||||
Take the user entered data, a string, and turn it into an array.
|
||||
|
||||
=head3 $rates
|
||||
|
||||
The rate data entered by the user. One set of data per line. Each line has the value of
|
||||
shipment, a colon, and the cost of insuring a shipment of that value.
|
||||
|
||||
=cut
|
||||
|
||||
sub _parseInsuranceRates {
|
||||
my $rates = shift;
|
||||
$rates =~ tr/\r//d;
|
||||
my $number = qr/\d+(?:\.\d+)?/;
|
||||
my $rate = qr{ \s* $number \s* : \s* $number \s* }x;
|
||||
return () if ($rates !~ m{ \A (?: $rate \r?\n )* $rate (?:\r\n)? \Z }x);
|
||||
my @lines = split /\n/, $rates;
|
||||
my @table = ();
|
||||
foreach my $line (@lines) {
|
||||
$line =~ s/\s+//g;
|
||||
my ($value, $cost) = split /:/, $line;
|
||||
push @table, [ $value, $cost ];
|
||||
}
|
||||
return @table;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 definition ( $session )
|
||||
|
||||
This subroutine returns an arrayref of hashrefs, used to validate data put into
|
||||
|
|
@ -262,6 +331,18 @@ sub definition {
|
|||
options => \%shippingTypes,
|
||||
defaultValue => 'PARCEL',
|
||||
},
|
||||
addInsurance => {
|
||||
fieldType => 'yesNo',
|
||||
label => $i18n->get('add insurance'),
|
||||
hoverHelp => $i18n->get('add insurance help'),
|
||||
defaultValue => 0,
|
||||
},
|
||||
insuranceRates => {
|
||||
fieldType => 'textarea',
|
||||
label => $i18n->get('insurance rates'),
|
||||
hoverHelp => $i18n->get('insurance rates help'),
|
||||
defaultValue => "50:1.75\n100:2.25",
|
||||
},
|
||||
##Note, if a flat fee is added to this driver, then according to the license
|
||||
##terms the website must display a note to the user (shop customer) that additional
|
||||
##fees have been added.
|
||||
|
|
|
|||
|
|
@ -619,6 +619,48 @@ sub newByGatewayId {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 sendNotifications ( transaction )
|
||||
|
||||
Sends out a receipt and a sale notification to the buyer and the store owner respectively.
|
||||
|
||||
=cut
|
||||
|
||||
sub sendNotifications {
|
||||
my ($self) = @_;
|
||||
my $session = $self->session;
|
||||
my $i18n = WebGUI::International->new($session, 'PayDriver');
|
||||
my $url = $session->url;
|
||||
my $var = $self->getTransactionVars;
|
||||
|
||||
# render
|
||||
my $template = WebGUI::Asset::Template->new( $session, $session->setting->get("shopReceiptEmailTemplateId") );
|
||||
my $inbox = WebGUI::Inbox->new($session);
|
||||
my $receipt = $template->process( $var );
|
||||
WebGUI::Macro::process($session, \$receipt);
|
||||
|
||||
# purchase receipt
|
||||
$inbox->addMessage( {
|
||||
message => $receipt,
|
||||
subject => $i18n->get('receipt subject') . ' ' . $self->get('orderNumber'),
|
||||
userId => $self->get('userId'),
|
||||
status => 'completed',
|
||||
} );
|
||||
|
||||
# shop owner notification
|
||||
# Shop owner uses method=view rather than method=viewMy
|
||||
$var->{viewDetailUrl} = $url->page( 'shop=transaction;method=view;transactionId='.$self->getId, 1 );
|
||||
my $notification = $template->process( $var );
|
||||
WebGUI::Macro::process($session, \$notification);
|
||||
$inbox->addMessage( {
|
||||
message => $notification,
|
||||
subject => $i18n->get('a sale has been made') . ' ' . $self->get('orderNumber'),
|
||||
groupId => $session->setting->get('shopSaleNotificationGroupId'),
|
||||
status => 'unread',
|
||||
} );
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 thankYou ()
|
||||
|
||||
Displays the default thank you page.
|
||||
|
|
|
|||
|
|
@ -381,6 +381,7 @@ sub addFileFromFormPost {
|
|||
next
|
||||
if ($upload->size > 1024 * $self->session->setting->get("maxAttachmentSize"));
|
||||
$clientFilename =~ s/.*[\/\\]//;
|
||||
$clientFilename =~ s/^thumb-//;
|
||||
my $type = $self->getFileExtension($clientFilename);
|
||||
if (isIn($type, qw(pl perl sh cgi php asp html htm))) { # make us safe from malicious uploads
|
||||
$clientFilename =~ s/\./\_/g;
|
||||
|
|
@ -509,6 +510,7 @@ deletion of this location's files, to CDN queue.
|
|||
sub clear {
|
||||
my $self = shift;
|
||||
my $dir = $self->getPathClassDir;
|
||||
return undef if !defined $dir;
|
||||
my $errors;
|
||||
CHILD: while (my $child = $dir->next()) {
|
||||
my $rel = $child->relative($dir);
|
||||
|
|
@ -1054,6 +1056,7 @@ sub getFiles {
|
|||
my $self = shift;
|
||||
my $showAll = shift;
|
||||
my $dir = $self->getPathClassDir;
|
||||
return [] if ! defined $dir;
|
||||
my $dirStr = $dir->stringify;
|
||||
my @list;
|
||||
$dir->recurse(
|
||||
|
|
@ -1174,6 +1177,10 @@ sub getPathClassDir {
|
|||
return undef;
|
||||
}
|
||||
my $dir = Path::Class::Dir->new($self->session->config->get("uploadsPath"), @{ $self->{_pathParts} });
|
||||
if (! -e $dir->stringify) {
|
||||
$self->_addError("directory for storage location ". $self->getId." does not exist");
|
||||
return undef;
|
||||
}
|
||||
return $dir;
|
||||
}
|
||||
|
||||
|
|
@ -1660,6 +1667,7 @@ sub setPrivileges {
|
|||
my $editGroup = shift;
|
||||
|
||||
my $dirObj = $self->getPathClassDir();
|
||||
return undef if ! defined $dirObj;
|
||||
$dirObj->recurse(
|
||||
callback => sub {
|
||||
my $obj = shift;
|
||||
|
|
|
|||
|
|
@ -515,6 +515,20 @@ sub getWorking {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 leaveTag ( )
|
||||
|
||||
Make the user leave their current tag.
|
||||
|
||||
=cut
|
||||
|
||||
sub leaveTag {
|
||||
my $self = shift;
|
||||
$self->session->scratch->delete('versionTag');
|
||||
$self->session->stow->delete("versionTag");
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 lock ( )
|
||||
|
||||
Sets this version tag up so no more revisions may be applied to it.
|
||||
|
|
|
|||
|
|
@ -15,12 +15,6 @@ our $I18N = {
|
|||
context => q|commerce setting|
|
||||
},
|
||||
|
||||
'sale notification group' => {
|
||||
message => q|Sale Notification Group|,
|
||||
lastUpdated => 0,
|
||||
context => q|commerce setting|
|
||||
},
|
||||
|
||||
'error processing payment' => {
|
||||
message => q|Error Processing Payment|,
|
||||
lastUpdated => 0,
|
||||
|
|
@ -33,24 +27,6 @@ our $I18N = {
|
|||
context => q|the description on the error screen|
|
||||
},
|
||||
|
||||
'sale notification group help' => {
|
||||
message => q|Who should be notified of new transactions?|,
|
||||
lastUpdated => 0,
|
||||
context => q|commerce setting help|
|
||||
},
|
||||
|
||||
'receipt email template' => {
|
||||
message => q|Receipt Email Template|,
|
||||
lastUpdated => 0,
|
||||
context => q|commerce setting|
|
||||
},
|
||||
|
||||
'receipt email template help' => {
|
||||
message => q|Which template should be used to generate an email that will be sent to the user to acknowledge their purchase?|,
|
||||
lastUpdated => 0,
|
||||
context => q|commerce setting help|
|
||||
},
|
||||
|
||||
'label' => {
|
||||
message => q|Label|,
|
||||
lastUpdated => 0,
|
||||
|
|
|
|||
|
|
@ -94,6 +94,30 @@ our $I18N = {
|
|||
context => q|Label for a type of shipping from the USPS.|,
|
||||
},
|
||||
|
||||
'add insurance' => {
|
||||
message => q|Ship with insurance?|,
|
||||
lastUpdated => 1253988886,
|
||||
context => q|Label for the edit screen.|,
|
||||
},
|
||||
|
||||
'add insurance help' => {
|
||||
message => q|If set to yes, the shipping plugin will ask the USPS for the cost of insuring this shipment. The cost will be added to the total cost of shipping. If insurance is not available, then the option to use this driver will not be presented to the user.|,
|
||||
lastUpdated => 1253988884,
|
||||
context => q|Label for a type of shipping from the USPS.|,
|
||||
},
|
||||
|
||||
'insurance rates' => {
|
||||
message => q|Insurance Rate Table|,
|
||||
lastUpdated => 1253988886,
|
||||
context => q|Label for the edit screen.|,
|
||||
},
|
||||
|
||||
'insurance rates help' => {
|
||||
message => q|Enter in one field per line with the format, value:cost.<br />value is the value of the contents.<br />cost is the cost of insurance at that value.<br />value and cost should look like numbers with a decimal point, like 0.50 or 1.00|,
|
||||
lastUpdated => 1253988884,
|
||||
context => q|Help for the insurance rate field.|,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -1671,6 +1671,31 @@ our $I18N = {
|
|||
context => q|Label to make the user choose a shipping method|,
|
||||
},
|
||||
|
||||
'receipt email template' => {
|
||||
message => q|Receipt Email Template|,
|
||||
lastUpdated => 0,
|
||||
context => q|commerce setting|
|
||||
},
|
||||
|
||||
'receipt email template help' => {
|
||||
message => q|Which template should be used to generate an email that will be sent to the user to acknowledge their purchase?|,
|
||||
lastUpdated => 0,
|
||||
context => q|commerce setting help|
|
||||
},
|
||||
|
||||
'sale notification group' => {
|
||||
message => q|Sale Notification Group|,
|
||||
lastUpdated => 0,
|
||||
context => q|commerce setting|
|
||||
},
|
||||
|
||||
'sale notification group help' => {
|
||||
message => q|Who should be notified of new transactions?|,
|
||||
lastUpdated => 0,
|
||||
context => q|commerce setting help|
|
||||
},
|
||||
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ use Fcntl ':flock';
|
|||
use Getopt::Long;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Storage;
|
||||
use Pod::Usage;
|
||||
|
||||
my $configFile;
|
||||
my $help;
|
||||
|
|
@ -32,17 +33,11 @@ GetOptions(
|
|||
'override' => \$override,
|
||||
'migrate' => \$migrate,
|
||||
'quiet' => \$quiet,
|
||||
'h|help' => \$help,
|
||||
);
|
||||
|
||||
if ( $configFile eq "" ) {
|
||||
printHelp();
|
||||
exit 4;
|
||||
}
|
||||
|
||||
if ($help) {
|
||||
printHelp();
|
||||
exit 2;
|
||||
}
|
||||
pod2usage( { verbose => 2, exitval => 2, } ) if $help;
|
||||
pod2usage( { exitval => 4, } ) unless $configFile;
|
||||
|
||||
# don't want two copies of this to run simultaneously
|
||||
unless ( flock( DATA, LOCK_EX | LOCK_NB ) ) {
|
||||
|
|
@ -50,54 +45,6 @@ unless ( flock( DATA, LOCK_EX | LOCK_NB ) ) {
|
|||
exit 3;
|
||||
}
|
||||
|
||||
sub printHelp {
|
||||
print <<STOP;
|
||||
|
||||
Usage: perl $0 --configfile=<webguiConfig>
|
||||
|
||||
--configFile WebGUI config file.
|
||||
|
||||
Options:
|
||||
|
||||
--override This utility is designed to be run as
|
||||
a privileged user on Linux style systems.
|
||||
If you wish to run this utility without
|
||||
being the super user, then use this flag,
|
||||
but note that it may not work as
|
||||
intended.
|
||||
|
||||
--migrate Migrate entirety of uploads directory to CDN.
|
||||
Ignore the CDN queue and sync everything.
|
||||
|
||||
--help Display this help message and exit.
|
||||
|
||||
--quiet Disable output unless there's an error.
|
||||
|
||||
EXIT STATUS
|
||||
|
||||
The following exit values are returned:
|
||||
|
||||
0
|
||||
Successful execution.
|
||||
|
||||
1
|
||||
Only super user may run the script.
|
||||
|
||||
2
|
||||
Help requested.
|
||||
|
||||
3
|
||||
Only one instance of this script can run at a time.
|
||||
|
||||
4
|
||||
Error during invocation of the command.
|
||||
|
||||
5
|
||||
Content Delivery Network (CDN) is not enabled.
|
||||
|
||||
STOP
|
||||
} ## end sub printHelp
|
||||
|
||||
if ( !( $^O =~ /^Win/i ) && $> != 0 && !$override ) {
|
||||
print "You must be the super user to use this utility.\n";
|
||||
exit 1;
|
||||
|
|
@ -213,3 +160,91 @@ sub syncUploads {
|
|||
__DATA__
|
||||
This exists so flock() code above works.
|
||||
DO NOT REMOVE THIS DATA SECTION.
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
syncToCdn - WebGUI interface to a Content Delivery Network.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
syncToCdn.pl --configFile config.conf
|
||||
[--override]
|
||||
[--migrate]
|
||||
[--quiet]
|
||||
|
||||
syncToCdn.pl --help
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This WebGUI utility script displays the amount of disk space used by
|
||||
an asset and it's descendants. It has been modeled after the *nix 'du'
|
||||
utility.
|
||||
|
||||
=over
|
||||
|
||||
=item B<--configFile config.conf>
|
||||
|
||||
The WebGUI config file to use. Only the file name needs to be specified,
|
||||
since it will be looked up inside WebGUI's configuration directory.
|
||||
This parameter is required.
|
||||
|
||||
=item B<--override>
|
||||
|
||||
This utility is designed to be run as a privileged user on Linux style
|
||||
systems. If you wish to run this utility without being the super user,
|
||||
then use this flag, but note that it may not work as intended.
|
||||
|
||||
=item B<--migrate>
|
||||
|
||||
Migrate entirety of uploads directory to CDN. Ignore the CDN queue and
|
||||
sync everything.
|
||||
|
||||
=item B<--quiet>
|
||||
|
||||
Disable output unless there is an error.
|
||||
|
||||
=item B<--help>
|
||||
|
||||
Shows this documentation, then exits.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXIT CODES
|
||||
|
||||
The following exit values are returned:
|
||||
|
||||
=over 4
|
||||
|
||||
=item 0
|
||||
|
||||
Successful execution.
|
||||
|
||||
=item 1
|
||||
|
||||
Only super user may run the script.
|
||||
|
||||
=item 2
|
||||
|
||||
Help requested.
|
||||
|
||||
=item 3
|
||||
|
||||
Only one instance of this script can run at a time.
|
||||
|
||||
=item 4
|
||||
|
||||
Error during invocation of the command.
|
||||
|
||||
=item 5
|
||||
|
||||
Content Delivery Network (CDN) is not enabled.
|
||||
|
||||
=back
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Copyright 2001-2009 Plain Black Corporation.
|
||||
|
||||
=cut
|
||||
|
|
|
|||
|
|
@ -935,10 +935,12 @@ like($message, qr/Exported $numberCreatedAll pages/, "... returns correct messag
|
|||
$extrasSymlink = Path::Class::File->new($exportPath, $extrasUrl);
|
||||
$uploadsSymlink = Path::Class::File->new($exportPath, $uploadsUrl);
|
||||
|
||||
ok(-e $extrasSymlink->absolute->stringify, "exportAsHtml writes extras symlink");
|
||||
ok(-e $extrasSymlink->absolute->stringify, "exportAsHtml writes extras symlink")
|
||||
or diag "link not found at " . $extrasSymlink->absolute;
|
||||
is(readlink $extrasSymlink->absolute->stringify, $extrasPath, "exportAsHtml extras symlink points to right place");
|
||||
|
||||
ok(-e $uploadsSymlink->absolute->stringify, "exportAsHtml writes uploads symlink");
|
||||
ok(-e $uploadsSymlink->absolute->stringify, "exportAsHtml writes uploads symlink")
|
||||
or diag "link not found at " . $uploadsSymlink->absolute;
|
||||
is(readlink $uploadsSymlink->absolute->stringify, $uploadsPath, "exportAsHtml uploads symlink points to right place");
|
||||
|
||||
# next, make sure the root URL symlinking works.
|
||||
|
|
@ -946,6 +948,7 @@ eval { ($message) = $parent->exportAsHtml( { userId => 3, depth => 99, rootUr
|
|||
my $rootUrlSymlink = Path::Class::File->new($exportPath, 'index.html');
|
||||
is($@, '', 'exportAsHtml does not throw an error when linking root URL');
|
||||
like($message, qr/Exported $numberCreatedAll pages/, "... returns correct message");
|
||||
ok(-l $rootUrlSymlink->absolute->stringify, "... writes root URL symlink");
|
||||
ok(-l $rootUrlSymlink->absolute->stringify, "... writes root URL symlink")
|
||||
or diag "link not found at " . $rootUrlSymlink->absolute;
|
||||
is(readlink $rootUrlSymlink->absolute->stringify, WebGUI::Asset->getDefault($session)->exportGetUrlAsPath->absolute->stringify, "... root URL symlink points to right place");
|
||||
|
||||
|
|
|
|||
64
t/Asset/Post/Thread.t
Normal file
64
t/Asset/Post/Thread.t
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
|
||||
#-------------------------------------------------------------------
|
||||
# Please read the legal notices (docs/legal.txt) and the license
|
||||
# (docs/license.txt) that came with this distribution before using
|
||||
# this software.
|
||||
#-------------------------------------------------------------------
|
||||
# http://www.plainblack.com info@plainblack.com
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
use FindBin;
|
||||
use strict;
|
||||
use lib "$FindBin::Bin/../../lib";
|
||||
use WebGUI::Test;
|
||||
use WebGUI::Session;
|
||||
use Test::More tests => 2; # increment this value for each test you create
|
||||
use Test::MockObject::Extends;
|
||||
use WebGUI::Asset::Wobject::Collaboration;
|
||||
use WebGUI::Asset::Post::Thread;
|
||||
|
||||
my $session = WebGUI::Test->session;
|
||||
|
||||
# Do our work in the import node
|
||||
my $node = WebGUI::Asset->getImportNode($session);
|
||||
|
||||
# Grab a named version tag
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Collab setup"});
|
||||
addToCleanup($versionTag);
|
||||
|
||||
# Need to create a Collaboration system in which the post lives.
|
||||
my @addArgs = ( undef, undef, { skipAutoCommitWorkflows => 1, skipNotification => 1 } );
|
||||
my $collab = $node->addChild({className => 'WebGUI::Asset::Wobject::Collaboration', editTimeout => '1'}, @addArgs);
|
||||
|
||||
|
||||
# finally, add the post to the collaboration system
|
||||
my $props = {
|
||||
className => 'WebGUI::Asset::Post::Thread',
|
||||
content => 'hello, world!',
|
||||
ownerUserId => 1,
|
||||
};
|
||||
|
||||
my $thread = $collab->addChild($props, @addArgs);
|
||||
|
||||
$versionTag->commit();
|
||||
|
||||
# Test for a sane object type
|
||||
isa_ok($thread, 'WebGUI::Asset::Post::Thread');
|
||||
|
||||
my $env = $session->env;
|
||||
$env = Test::MockObject::Extends->new($env);
|
||||
|
||||
my %mockEnv = (
|
||||
REMOTE_ADDR => '192.168.0.2',
|
||||
);
|
||||
|
||||
$env->mock('get', sub { return $mockEnv{$_[1]}});
|
||||
|
||||
$session->user({userId => 3});
|
||||
$thread->rate(1);
|
||||
$thread->trash;
|
||||
is($thread->get('threadRating'), 0, 'trash does not die, and updates the threadRating to 0');
|
||||
|
||||
# vim: syntax=perl filetype=perl
|
||||
|
|
@ -122,6 +122,7 @@ $story = $archive->addChild({
|
|||
title => 'Story 1',
|
||||
subtitle => 'The story of a CMS',
|
||||
byline => 'JT Smith',
|
||||
story => 'WebGUI was originally called Web Done Right.',
|
||||
});
|
||||
|
||||
isa_ok($story, 'WebGUI::Asset::Story', 'Created a Story asset');
|
||||
|
|
@ -276,7 +277,7 @@ cmp_deeply(
|
|||
$story->getRssData,
|
||||
{
|
||||
title => 'Story 1',
|
||||
description => 'The story of a CMS',
|
||||
description => 'WebGUI was originally called Web Done Right.',
|
||||
'link' => re('story-1$'),
|
||||
author => 'JT Smith',
|
||||
date => $story->get('lastModified'),
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use lib "$FindBin::Bin/../lib";
|
|||
|
||||
use WebGUI::Test;
|
||||
use WebGUI::Session;
|
||||
use Test::More tests => 18; # increment this value for each test you create
|
||||
use Test::More tests => 17; # increment this value for each test you create
|
||||
use WebGUI::Asset::Wobject::WikiMaster;
|
||||
use WebGUI::Asset::WikiPage;
|
||||
|
||||
|
|
@ -25,15 +25,16 @@ my $session = WebGUI::Test->session;
|
|||
my $node = WebGUI::Asset->getImportNode($session);
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Wiki Test"});
|
||||
WebGUI::Test->tagsToRollback($versionTag);
|
||||
addToCleanup($versionTag);
|
||||
|
||||
my $wiki = $node->addChild({className=>'WebGUI::Asset::Wobject::WikiMaster'});
|
||||
$versionTag->commit;
|
||||
my $wikipage = $wiki->addChild({className=>'WebGUI::Asset::WikiPage'});
|
||||
my $wikipage = $wiki->addChild({className=>'WebGUI::Asset::WikiPage'}, undef, undef, {skipAutoCommitWorkflows => 1});
|
||||
|
||||
# Wikis create and autocommit a version tag when a child is added. Lets get the name so we can roll it back.
|
||||
my $secondVersionTag = WebGUI::VersionTag->new($session,$wikipage->get("tagId"));
|
||||
WebGUI::Test->tagsToRollback($secondVersionTag );
|
||||
$secondVersionTag->commit;
|
||||
addToCleanup($secondVersionTag );
|
||||
|
||||
# Test for sane object types
|
||||
isa_ok($wiki, 'WebGUI::Asset::Wobject::WikiMaster');
|
||||
|
|
@ -85,11 +86,3 @@ $comments = $wikipage->get('comments');
|
|||
is($comments->[0]{comment}, $secondComment, "you can delete a comment");
|
||||
is($wikipage->get('averageCommentRating'), 1, 'average rating is adjusted after deleting a comment');
|
||||
|
||||
|
||||
##################
|
||||
|
||||
TODO: {
|
||||
local $TODO = "Tests to make later";
|
||||
ok(0, 'Lots and lots to do');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ cmp_deeply(
|
|||
|
||||
$session->user({userId => 3});
|
||||
my $json = $matrix->www_getCompareFormData('score');
|
||||
diag $session->getId;
|
||||
note $session->getId;
|
||||
|
||||
my $compareFormData = JSON->new->decode($json);
|
||||
|
||||
|
|
|
|||
|
|
@ -266,6 +266,7 @@ like($storage->getFileContentsAsScalar($filename), qr{
|
|||
|
||||
}
|
||||
|
||||
$survey->getAdminConsole();
|
||||
my $adminConsole = $survey->getAdminConsole();
|
||||
cmp_deeply(
|
||||
$adminConsole->{_submenuItem},
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@ use Data::Dumper;
|
|||
|
||||
use WebGUI::Test;
|
||||
use WebGUI::Session;
|
||||
use Test::More tests => 20; # increment this value for each test you create
|
||||
use Test::More tests => 21; # increment this value for each test you create
|
||||
use Test::Deep;
|
||||
use WebGUI::Asset::Wobject::SyndicatedContent;
|
||||
use XML::FeedPP;
|
||||
use WebGUI::Cache;
|
||||
|
||||
my $session = WebGUI::Test->session;
|
||||
my %var;
|
||||
|
|
@ -36,7 +38,7 @@ my $node = WebGUI::Asset->getImportNode($session);
|
|||
# Create a version tag to work in
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"SyndicatedContent Test"});
|
||||
WebGUI::Test->tagsToRollback($versionTag);
|
||||
addToCleanup($versionTag);
|
||||
my $syndicated_content = $node->addChild({className=>'WebGUI::Asset::Wobject::SyndicatedContent'});
|
||||
|
||||
##############################
|
||||
|
|
@ -138,3 +140,39 @@ EOFEED
|
|||
|
||||
my $vars = $syndicated_content->getTemplateVariables($feed);
|
||||
ok( defined $vars->{item_loop}->[0]->{description}, 'getTemplateVariables: description is not undefined');
|
||||
|
||||
####################################################################
|
||||
#
|
||||
# generateFeed, hasTerms
|
||||
#
|
||||
####################################################################
|
||||
|
||||
my $tbbUrl = 'http://www.plainblack.com/tbb.rss';
|
||||
$syndicated_content->update({
|
||||
rssUrl => $tbbUrl,
|
||||
hasTerms => 'WebGUI',
|
||||
});
|
||||
|
||||
my $cache = WebGUI::Cache->new($session, $tbbUrl, 'RSS');
|
||||
open my $rssFile, '<', WebGUI::Test->getTestCollateralPath('tbb.rss')
|
||||
or die "Unable to get RSS file";
|
||||
my $rssContent = do { local $/; <$rssFile>; };
|
||||
close $rssFile;
|
||||
$cache->set($rssContent, 60);
|
||||
|
||||
my $filteredFeed = $syndicated_content->generateFeed();
|
||||
|
||||
use Data::Dumper;
|
||||
diag Dumper($filteredFeed->get_item());
|
||||
|
||||
cmp_deeply(
|
||||
[ map { $_->title } $filteredFeed->get_item() ],
|
||||
[
|
||||
'Google Picasa Plugin for WebGUI Gallery',
|
||||
'WebGUI Roadmap',
|
||||
'WebGUI 8 Performance',
|
||||
],
|
||||
'generateFeed: filters items based on the terms being in title, or description'
|
||||
);
|
||||
|
||||
$cache->delete;
|
||||
|
|
|
|||
10
t/DateTime.t
10
t/DateTime.t
|
|
@ -26,7 +26,7 @@ my $session = WebGUI::Test->session;
|
|||
|
||||
# put your tests here
|
||||
|
||||
plan tests => 23;
|
||||
plan tests => 25;
|
||||
|
||||
my $timeZoneUser = addUser($session);
|
||||
|
||||
|
|
@ -76,6 +76,14 @@ my $dt1970 = WebGUI::DateTime->new($session, 0);
|
|||
isa_ok($dt1970, 'WebGUI::DateTime', 'constructed with 0');
|
||||
is($dt1970->epoch, 0, '... uses 0 for epoch');
|
||||
|
||||
my $bday = WebGUI::DateTime->new($session, '2001-08-16');
|
||||
isa_ok($bday, 'WebGUI::DateTime', 'constructed with mysql date, no time');
|
||||
is(
|
||||
$bday->epoch,
|
||||
WebGUI::DateTime->new($session, WebGUI::Test->webguiBirthday)->truncate( to => 'day')->epoch,
|
||||
'... has correct epoch'
|
||||
);
|
||||
|
||||
sub addUser {
|
||||
my $session = shift;
|
||||
my $user = WebGUI::User->new($session, "new");
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use Test::More;
|
|||
use Test::Deep;
|
||||
use Data::Dumper;
|
||||
use MIME::Parser;
|
||||
use Encode qw/decode/;
|
||||
use Encode qw/decode encode/;
|
||||
|
||||
use WebGUI::Test;
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ if ( $@ ) { diag( "Can't prepare mail server: $@" ) }
|
|||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
|
||||
plan tests => 16; # Increment this number for each test you create
|
||||
plan tests => 17; # Increment this number for each test you create
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Test create
|
||||
|
|
@ -115,6 +115,18 @@ is( $mime->parts(0)->as_string =~ m/\n/, $newlines,
|
|||
"addHtmlRaw should add newlines after 78 characters",
|
||||
);
|
||||
|
||||
use utf8;
|
||||
$mail = WebGUI::Mail::Send->create( $session, {
|
||||
to => 'norton@localhost',
|
||||
subject => "H\x{00C4}ufige Fragen",
|
||||
});
|
||||
$mail->addHeaderField('List-ID', "H\x{00C4}ufige Fragen");
|
||||
my $messageId = $mail->queue;
|
||||
diag $messageId;
|
||||
my $dbMail = WebGUI::Mail::Send->retrieve($session, $messageId);
|
||||
diag ref $dbMail;
|
||||
is($dbMail->getMimeEntity->head->get('List-ID'), "=?UTF-8?Q?H=C3=84ufige=20Fragen?=\n", 'addHeaderField: handles utf-8 correctly');
|
||||
|
||||
# TODO: Test that addHtml creates a body with the right content type
|
||||
my $smtpServerOk = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -93,19 +93,6 @@ cmp_deeply (
|
|||
hoverHelp => ignore(),
|
||||
defaultValue => 7,
|
||||
},
|
||||
receiptEmailTemplateId => {
|
||||
fieldType => 'template',
|
||||
label => ignore(),
|
||||
hoverHelp => ignore(),
|
||||
defaultValue => 'bPz1yk6Y9uwMDMBcmMsSCg',
|
||||
namespace => 'Shop/EmailReceipt',
|
||||
},
|
||||
saleNotificationGroupId => {
|
||||
fieldType => 'group',
|
||||
label => ignore(),
|
||||
hoverHelp => ignore(),
|
||||
defaultValue => 3,
|
||||
},
|
||||
}
|
||||
} ],
|
||||
,
|
||||
|
|
@ -286,7 +273,7 @@ my @forms = HTML::Form->parse($html, 'http://www.webgui.org');
|
|||
is (scalar @forms, 1, 'getEditForm generates just 1 form');
|
||||
|
||||
my @inputs = $forms[0]->inputs;
|
||||
is (scalar @inputs, 14, 'getEditForm: the form has 14 controls');
|
||||
is (scalar @inputs, 11, 'getEditForm: the form has 11 controls');
|
||||
|
||||
my @interestingFeatures;
|
||||
foreach my $input (@inputs) {
|
||||
|
|
@ -342,18 +329,6 @@ cmp_deeply(
|
|||
name => '__groupToUse_isIn',
|
||||
type => 'hidden',
|
||||
},
|
||||
{
|
||||
name => 'receiptEmailTemplateId',
|
||||
type => 'option',
|
||||
},
|
||||
{
|
||||
name => 'saleNotificationGroupId',
|
||||
type => 'option',
|
||||
},
|
||||
{
|
||||
name => '__saleNotificationGroupId_isIn',
|
||||
type => 'hidden',
|
||||
},
|
||||
],
|
||||
'getEditForm made the correct form with all the elements'
|
||||
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ my @forms = HTML::Form->parse($html, 'http://www.webgui.org');
|
|||
is (scalar @forms, 1, 'getEditForm generates just 1 form');
|
||||
|
||||
my @inputs = $forms[0]->inputs;
|
||||
is (scalar @inputs, 20, 'getEditForm: the form has 20 controls');
|
||||
is (scalar @inputs, 17, 'getEditForm: the form has 17 controls');
|
||||
|
||||
my @interestingFeatures;
|
||||
foreach my $input (@inputs) {
|
||||
|
|
@ -428,18 +428,6 @@ cmp_deeply(
|
|||
name => '__groupToUse_isIn',
|
||||
type => 'hidden',
|
||||
},
|
||||
{
|
||||
name => 'receiptEmailTemplateId',
|
||||
type => 'option',
|
||||
},
|
||||
{
|
||||
name => 'saleNotificationGroupId',
|
||||
type => 'option',
|
||||
},
|
||||
{
|
||||
name => '__saleNotificationGroupId_isIn',
|
||||
type => 'hidden',
|
||||
},
|
||||
{
|
||||
name => 'pspid',
|
||||
type => 'text',
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ use Data::Dumper;
|
|||
use WebGUI::Test; # Must use this before any other WebGUI modules
|
||||
use WebGUI::Session;
|
||||
|
||||
plan tests => 46;
|
||||
plan tests => 64;
|
||||
use_ok('WebGUI::Shop::ShipDriver::USPS')
|
||||
or die 'Unable to load module WebGUI::Shop::ShipDriver::USPS';
|
||||
|
||||
|
|
@ -42,8 +42,16 @@ $session->user({user => $user});
|
|||
# put your tests here
|
||||
|
||||
|
||||
my $storage;
|
||||
my ($driver, $cart);
|
||||
my ($driver2, $cart);
|
||||
my $insuranceTable = <<EOTABLE;
|
||||
5:1.00
|
||||
10:2.00
|
||||
15:3.00
|
||||
20:4.00
|
||||
25:5.00
|
||||
30:6.00
|
||||
EOTABLE
|
||||
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
|
||||
my $home = WebGUI::Asset->getDefault($session);
|
||||
|
|
@ -92,8 +100,16 @@ my $nivBible = $bible->setCollateral('variantsJSON', 'variantId', 'new',
|
|||
}
|
||||
);
|
||||
|
||||
my $gospels = $bible->setCollateral('variantsJSON', 'variantId', 'new',
|
||||
{
|
||||
shortdesc => 'Gospels from the new Testament',
|
||||
price => 1.50, varSku => 'gospels',
|
||||
weight => 2.0, quantity => 999999,
|
||||
}
|
||||
);
|
||||
|
||||
$versionTag->commit;
|
||||
WebGUI::Test->tagsToRollback($versionTag);
|
||||
addToCleanup($versionTag);
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
|
|
@ -133,10 +149,11 @@ my $options = {
|
|||
enabled => 1,
|
||||
};
|
||||
|
||||
$driver = WebGUI::Shop::ShipDriver::USPS->create($session, $options);
|
||||
$driver2 = WebGUI::Shop::ShipDriver::USPS->create($session, $options);
|
||||
addToCleanup($driver2);
|
||||
|
||||
isa_ok($driver, 'WebGUI::Shop::ShipDriver::USPS');
|
||||
isa_ok($driver, 'WebGUI::Shop::ShipDriver');
|
||||
isa_ok($driver2, 'WebGUI::Shop::ShipDriver::USPS');
|
||||
isa_ok($driver2, 'WebGUI::Shop::ShipDriver');
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
|
|
@ -152,13 +169,13 @@ is (WebGUI::Shop::ShipDriver::USPS->getName($session), 'U.S. Postal Service', 'g
|
|||
#
|
||||
#######################################################################
|
||||
|
||||
my $driverId = $driver->getId;
|
||||
$driver->delete;
|
||||
my $driverId = $driver2->getId;
|
||||
$driver2->delete;
|
||||
|
||||
my $count = $session->db->quickScalar('select count(*) from shipper where shipperId=?',[$driverId]);
|
||||
is($count, 0, 'delete deleted the object');
|
||||
|
||||
undef $driver;
|
||||
undef $driver2;
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
|
|
@ -166,11 +183,12 @@ undef $driver;
|
|||
#
|
||||
#######################################################################
|
||||
|
||||
$driver = WebGUI::Shop::ShipDriver::USPS->create($session, {
|
||||
my $driver = WebGUI::Shop::ShipDriver::USPS->create($session, {
|
||||
label => 'Shipping from Shawshank',
|
||||
enabled => 1,
|
||||
shipType => 'PARCEL',
|
||||
});
|
||||
addToCleanup($driver);
|
||||
|
||||
eval { $driver->calculate() };
|
||||
$e = Exception::Class->caught();
|
||||
|
|
@ -199,6 +217,7 @@ cmp_deeply(
|
|||
);
|
||||
|
||||
$cart = WebGUI::Shop::Cart->newBySession($session);
|
||||
addToCleanup($cart);
|
||||
my $addressBook = $cart->getAddressBook;
|
||||
my $workAddress = $addressBook->addAddress({
|
||||
label => 'work',
|
||||
|
|
@ -283,6 +302,22 @@ $driver->update($properties);
|
|||
$rockHammer->addToCart($rockHammer->getCollateral('variantsJSON', 'variantId', $smallHammer));
|
||||
my @shippableUnits = $driver->_getShippableUnits($cart);
|
||||
|
||||
$properties = $driver->get();
|
||||
$properties->{addInsurance} = 1;
|
||||
$properties->{insuranceRates} = $insuranceTable;
|
||||
$driver->update($properties);
|
||||
|
||||
is($driver->_calculateInsurance(@shippableUnits), 2, '_calculateInsurance: one item in cart with quantity=1, calculates insurance');
|
||||
|
||||
$properties->{addInsurance} = 0;
|
||||
$driver->update($properties);
|
||||
is($driver->_calculateInsurance(@shippableUnits), 0, '_calculateInsurance: returns 0 if insurance is not enabled');
|
||||
|
||||
$properties->{addInsurance} = 1;
|
||||
$properties->{insuranceRates} = '';
|
||||
$driver->update($properties);
|
||||
is($driver->_calculateInsurance(@shippableUnits), 0, '_calculateInsurance: returns 0 if rates are not set');
|
||||
|
||||
my $xml = $driver->buildXML($cart, @shippableUnits);
|
||||
like($xml, qr/<RateV3Request USERID="[^"]+"/, 'buildXML: checking userId is an attribute of the RateV3Request tag');
|
||||
like($xml, qr/<Package ID="0"/, 'buildXML: checking ID is an attribute of the Package tag');
|
||||
|
|
@ -359,8 +394,10 @@ is($cost, 5.25, '_calculateFromXML calculates shipping cost correctly for 1 item
|
|||
|
||||
$bibleItem = $bible->addToCart($bible->getCollateral('variantsJSON', 'variantId', $nivBible));
|
||||
@shippableUnits = $driver->_getShippableUnits($cart);
|
||||
$xml = $driver->buildXML($cart, @shippableUnits);
|
||||
|
||||
is(calculateInsurance($driver), 7, '_calculateInsurance: two items in cart with quantity=1, calculates insurance');
|
||||
|
||||
$xml = $driver->buildXML($cart, @shippableUnits);
|
||||
$xmlData = XMLin( $xml,
|
||||
KeepRoot => 1,
|
||||
ForceArray => ['Package'],
|
||||
|
|
@ -458,6 +495,8 @@ is($cost, 12.25, '_calculateFromXML calculates shipping cost correctly for 2 ite
|
|||
$bibleItem->setQuantity(2);
|
||||
@shippableUnits = $driver->_getShippableUnits($cart);
|
||||
|
||||
is(calculateInsurance($driver), 8, '_calculateInsurance: two items in cart with quantity=2, calculates insurance');
|
||||
|
||||
$cost = $driver->_calculateFromXML({
|
||||
Package => [
|
||||
{
|
||||
|
|
@ -481,6 +520,7 @@ is($cost, 19.25, '_calculateFromXML calculates shipping cost correctly for 2 ite
|
|||
$rockHammer2 = $rockHammer->addToCart($rockHammer->getCollateral('variantsJSON', 'variantId', $bigHammer));
|
||||
$rockHammer2->update({shippingAddressId => $wucAddress->getId});
|
||||
@shippableUnits = $driver->_getShippableUnits($cart);
|
||||
is(calculateInsurance($driver), 12, '_calculateInsurance: calculates insurance');
|
||||
$xml = $driver->buildXML($cart, @shippableUnits);
|
||||
|
||||
$xmlData = XMLin( $xml,
|
||||
|
|
@ -575,6 +615,12 @@ SKIP: {
|
|||
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# Test Priority shipping setup
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
$cart->empty;
|
||||
$properties = $driver->get();
|
||||
$properties->{shipType} = 'PRIORITY';
|
||||
|
|
@ -637,6 +683,12 @@ SKIP: {
|
|||
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# Test EXPRESS shipping setup
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
$properties = $driver->get();
|
||||
$properties->{shipType} = 'EXPRESS';
|
||||
$driver->update($properties);
|
||||
|
|
@ -695,6 +747,11 @@ SKIP: {
|
|||
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# Test PRIORITY VARIABLE shipping setup
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
$properties = $driver->get();
|
||||
$properties->{shipType} = 'PRIORITY VARIABLE';
|
||||
|
|
@ -754,16 +811,60 @@ SKIP: {
|
|||
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# _calculateInsurance edge case
|
||||
#
|
||||
#######################################################################
|
||||
$cart->empty;
|
||||
$bible->addToCart($bible->getCollateral('variantsJSON', 'variantId', $gospels));
|
||||
@shippableUnits = $driver->_getShippableUnits($cart);
|
||||
is(calculateInsurance($driver), 1, '_calculateInsurance: calculates insurance using the first bin');
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# _parseInsuranceRates
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
my @rates;
|
||||
@rates = WebGUI::Shop::ShipDriver::USPS::_parseInsuranceRates("");
|
||||
cmp_deeply(\@rates, [], '_parseInsuranceRates: empty string returns empty array');
|
||||
@rates = WebGUI::Shop::ShipDriver::USPS::_parseInsuranceRates();
|
||||
cmp_deeply(\@rates, [], '_parseInsuranceRates: undef returns empty array');
|
||||
@rates = WebGUI::Shop::ShipDriver::USPS::_parseInsuranceRates("2");
|
||||
cmp_deeply(\@rates, [], '... bad rates #1');
|
||||
@rates = WebGUI::Shop::ShipDriver::USPS::_parseInsuranceRates(":2");
|
||||
cmp_deeply(\@rates, [], '... bad rates #2');
|
||||
@rates = WebGUI::Shop::ShipDriver::USPS::_parseInsuranceRates("a:b");
|
||||
cmp_deeply(\@rates, [], '... bad rates #3');
|
||||
@rates = WebGUI::Shop::ShipDriver::USPS::_parseInsuranceRates("2:2");
|
||||
cmp_deeply(\@rates, [ ['2', '2'] ], '... one line of good rates');
|
||||
@rates = WebGUI::Shop::ShipDriver::USPS::_parseInsuranceRates("2.0:2.0");
|
||||
cmp_deeply(\@rates, [ ['2.0', '2.0'] ], '... one line of good rates with decimal points');
|
||||
@rates = WebGUI::Shop::ShipDriver::USPS::_parseInsuranceRates("2.0:2.0\n");
|
||||
cmp_deeply(\@rates, [ ['2.0', '2.0'] ], '... one line of good rates with newline');
|
||||
@rates = WebGUI::Shop::ShipDriver::USPS::_parseInsuranceRates("2.0:2.0\r\n");
|
||||
cmp_deeply(\@rates, [ ['2.0', '2.0'] ], '... one line of good rates with cr/newline');
|
||||
@rates = WebGUI::Shop::ShipDriver::USPS::_parseInsuranceRates("2.0 : 2.0\r\n");
|
||||
cmp_deeply(\@rates, [ ['2.0', '2.0'] ], '... one line of good rates with cr/newline and spaces');
|
||||
@rates = WebGUI::Shop::ShipDriver::USPS::_parseInsuranceRates(" 2.0 : 2.0 \r\n");
|
||||
cmp_deeply(\@rates, [ ['2.0', '2.0'] ], '... one line of good rates with cr/newline and more spaces');
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Cleanup
|
||||
END {
|
||||
if (defined $driver && $driver->isa('WebGUI::Shop::ShipDriver')) {
|
||||
$driver->delete;
|
||||
}
|
||||
if (defined $cart && $cart->isa('WebGUI::Shop::Cart')) {
|
||||
my $addressBook = $cart->getAddressBook();
|
||||
$addressBook->delete if $addressBook;
|
||||
$cart->delete;
|
||||
}
|
||||
|
||||
sub calculateInsurance {
|
||||
my $driver = shift;
|
||||
my $properties = $driver->get();
|
||||
$properties->{addInsurance} = 1;
|
||||
$properties->{insuranceRates} = $insuranceTable;
|
||||
$driver->update($properties);
|
||||
|
||||
my $insurance = $driver->_calculateInsurance(@shippableUnits);
|
||||
|
||||
$properties->{addInsurance} = 0;
|
||||
$driver->update($properties);
|
||||
|
||||
return $insurance;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ use Test::Deep;
|
|||
use WebGUI::Test; # Must use this before any other WebGUI modules
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Shop::Transaction;
|
||||
use WebGUI::Inbox;
|
||||
use Clone qw/clone/;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Init
|
||||
|
|
@ -30,7 +32,7 @@ my $session = WebGUI::Test->session;
|
|||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
|
||||
plan tests => 68; # Increment this number for each test you create
|
||||
plan tests => 77; # Increment this number for each test you create
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# put your tests here
|
||||
|
|
@ -64,6 +66,7 @@ my $transaction = WebGUI::Shop::Transaction->create($session,{
|
|||
paymentDriverLabel => 'kkk',
|
||||
taxes => 7,
|
||||
});
|
||||
addToCleanup($transaction);
|
||||
|
||||
# objects work
|
||||
isa_ok($transaction, "WebGUI::Shop::Transaction");
|
||||
|
|
@ -223,15 +226,72 @@ TODO: {
|
|||
ok(0, 'test keywords');
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# sendNotification
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
my $shopUser = WebGUI::User->create($session);
|
||||
$shopUser->username('shopUser');
|
||||
my $shopGroup = WebGUI::Group->new($session, 'new');
|
||||
my $shopAdmin = WebGUI::User->create($session);
|
||||
$shopUser->username('shopAdmin');
|
||||
$shopGroup->addUsers([$shopAdmin->getId]);
|
||||
addToCleanup($shopUser, $shopAdmin, $shopGroup);
|
||||
$session->setting->set('shopSaleNotificationGroupId', $shopGroup->getId);
|
||||
$session->user({userId => $shopUser->getId});
|
||||
|
||||
my $trans = WebGUI::Shop::Transaction->create($session, {});
|
||||
ok($trans->can('sendNotifications'), 'sendNotifications: valid method for transactions');
|
||||
addToCleanup($trans);
|
||||
|
||||
##Disable sending email
|
||||
my $sendmock = Test::MockObject->new( {} );
|
||||
$sendmock->set_isa('WebGUI::Mail::Send');
|
||||
$sendmock->set_true('addText', 'send', 'addHeaderField', 'addHtml', 'queue', 'addFooter');
|
||||
local *WebGUI::Mail::Send::create;
|
||||
$sendmock->fake_module('WebGUI::Mail::Send',
|
||||
create => sub { return $sendmock },
|
||||
);
|
||||
|
||||
#1234567890123456789012#
|
||||
my $templateId = 'SHOP_NOTIFICATION_____';
|
||||
|
||||
my $templateMock = Test::MockObject->new({});
|
||||
$templateMock->set_isa('WebGUI::Asset::Template');
|
||||
$templateMock->set_always('getId', $templateId);
|
||||
my @templateVars;
|
||||
$templateMock->mock('process', sub { push @templateVars, clone $_[1]; } );
|
||||
|
||||
$session->setting->set('shopReceiptEmailTemplateId', $templateId);
|
||||
|
||||
{
|
||||
WebGUI::Test->mockAssetId($templateId, $templateMock);
|
||||
$trans->sendNotifications;
|
||||
is(@templateVars, 2, '... called template->process twice');
|
||||
my $inbox = WebGUI::Inbox->new($session);
|
||||
my $userMessages = $inbox->getMessagesForUser($shopUser);
|
||||
my $adminMessages = $inbox->getMessagesForUser($shopAdmin);
|
||||
is(@{ $userMessages }, 1, '... sent one message to shop user');
|
||||
is(@{ $adminMessages }, 1, '... sent one message to shop admin, via shopSaleNotificationGroupId');
|
||||
like($userMessages->[0]->get('subject'), qr/^Receipt for Order #/, '... subject for user email okay');
|
||||
like($adminMessages->[0]->get('subject'), qr/^A sale has been made/, '... subject for admin email okay');
|
||||
like($templateVars[0]->{viewDetailUrl}, qr/shop=transaction;method=viewMy;/, '... viewDetailUrl okay for user');
|
||||
like($templateVars[1]->{viewDetailUrl}, qr/shop=transaction;method=view;/ , '... viewDetailUrl okay for admin');
|
||||
WebGUI::Test->unmockAssetId($templateId);
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# delete
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
$transaction->delete;
|
||||
is($session->db->quickScalar("select transactionId from transaction where transactionId=?",[$transaction->getId]), undef, "can delete transactions");
|
||||
is($session->db->quickScalar("select count(*) from transaction where transactionId=?",[$transaction->getId]),
|
||||
0, "delete: deleted transaction");
|
||||
is($session->db->quickScalar("select count(*) from transactionItem where transactionId=?",[$transaction->getId]),
|
||||
0, "... deleted transactionItems associated with this transaction");
|
||||
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Cleanup
|
||||
END {
|
||||
$session->db->write('delete from transaction');
|
||||
$session->db->write('delete from transactionItem');
|
||||
}
|
||||
|
|
|
|||
80
t/Storage.t
80
t/Storage.t
|
|
@ -32,7 +32,7 @@ my $cwd = Cwd::cwd();
|
|||
|
||||
my ($extensionTests, $fileIconTests) = setupDataDrivenTests($session);
|
||||
|
||||
my $numTests = 127; # increment this value for each test you create
|
||||
my $numTests = 134; # increment this value for each test you create
|
||||
plan tests => $numTests + scalar @{ $extensionTests } + scalar @{ $fileIconTests };
|
||||
|
||||
my $uploadDir = $session->config->get('uploadsPath');
|
||||
|
|
@ -54,6 +54,7 @@ my $storage1 = WebGUI::Storage->get($session);
|
|||
is( $storage1, undef, "get requires id to be passed");
|
||||
|
||||
$storage1 = WebGUI::Storage->get($session, 'foobar');
|
||||
addToCleanup($storage1);
|
||||
|
||||
isa_ok( $storage1, "WebGUI::Storage", "storage will accept non GUID arguments");
|
||||
is ( $storage1->getId, 'foobar', 'getId returns the requested GUID');
|
||||
|
|
@ -80,7 +81,7 @@ $guidDir->mkpath();
|
|||
ok(-e $guidDir->stringify, 'created GUID storage location for backwards compatibility testing');
|
||||
|
||||
my $guidStorage = WebGUI::Storage->get($session, $newGuid);
|
||||
WebGUI::Test->storagesToDelete($guidStorage);
|
||||
addToCleanup($guidStorage);
|
||||
isa_ok($guidStorage, 'WebGUI::Storage');
|
||||
is($guidStorage->getId, $newGuid, 'GUID storage has correct id');
|
||||
is($guidStorage->getDirectoryId, $newGuid, '... getDirectoryId');
|
||||
|
|
@ -115,7 +116,7 @@ undef $storage1;
|
|||
|
||||
$storage1 = WebGUI::Storage->get($session, 'notAGUID');
|
||||
my $storage2 = WebGUI::Storage->get($session, 'notAGoodId');
|
||||
WebGUI::Test->storagesToDelete($storage2);
|
||||
addToCleanup($storage2);
|
||||
|
||||
ok(! $storage2->getErrorCount, 'No errors due to a shared common root');
|
||||
|
||||
|
|
@ -147,7 +148,7 @@ CHECKDIR: while ($dirOpt = pop @dirOptions) {
|
|||
last CHECKDIR if !-e $dir3;
|
||||
}
|
||||
my $storage3 = WebGUI::Storage->get($session, $dirOpt);
|
||||
WebGUI::Test->storagesToDelete($storage3);
|
||||
addToCleanup($storage3);
|
||||
|
||||
is( $storage3->getErrorCount, 1, 'Error during creation of object due to short GUID');
|
||||
|
||||
|
|
@ -223,6 +224,7 @@ foreach my $extTest (@{ $extensionTests }) {
|
|||
####################################################
|
||||
|
||||
my $fileStore = WebGUI::Storage->create($session);
|
||||
addToCleanup($fileStore);
|
||||
cmp_bag($fileStore->getFiles(1), ['.'], 'Starting with an empty storage object, no files in here except for . ');
|
||||
$fileStore->addFileFromScalar('.dotfile', 'dot file');
|
||||
cmp_bag($fileStore->getFiles(), [ ], 'getFiles() by default does not return dot files');
|
||||
|
|
@ -302,25 +304,26 @@ ok(
|
|||
####################################################
|
||||
|
||||
my $copiedStorage = $storage1->copy();
|
||||
addToCleanup($copiedStorage);
|
||||
cmp_bag($copiedStorage->getFiles(), $storage1->getFiles(), 'copy: both storage objects have the same files');
|
||||
|
||||
my $secondCopy = WebGUI::Storage->create($session);
|
||||
addToCleanup($secondCopy);
|
||||
$storage1->copy($secondCopy);
|
||||
cmp_bag($secondCopy->getFiles(), $storage1->getFiles(), 'copy: passing explicit variable');
|
||||
|
||||
my $s3copy = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($s3copy);
|
||||
addToCleanup($s3copy);
|
||||
my @filesToCopy = qw/WebGUI.pm testfile-hash-renamed.file/;
|
||||
$storage1->copy($s3copy, [@filesToCopy]);
|
||||
cmp_bag($s3copy->getFiles(), [ @filesToCopy ], 'copy: passing explicit variable and files to copy');
|
||||
{
|
||||
my $deepStorage = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($deepStorage);
|
||||
addToCleanup($deepStorage);
|
||||
my $deepDir = $deepStorage->getPathClassDir();
|
||||
my $deepDeepDir = $deepDir->subdir('deep');
|
||||
my $errorStr;
|
||||
my @foo = $deepDeepDir->mkpath({ error => \$errorStr } );
|
||||
note explain \@foo;
|
||||
$deepStorage->addFileFromScalar('deep/file', 'deep file');
|
||||
cmp_bag(
|
||||
$deepStorage->getFiles('all'),
|
||||
|
|
@ -328,7 +331,7 @@ cmp_bag($s3copy->getFiles(), [ @filesToCopy ], 'copy: passing explicit variable
|
|||
'... storage setup for deep clear test'
|
||||
);
|
||||
my $deepCopy = $deepStorage->copy();
|
||||
WebGUI::Test->storagesToDelete($deepCopy);
|
||||
addToCleanup($deepCopy);
|
||||
cmp_bag(
|
||||
$deepCopy->getFiles('all'),
|
||||
[ '.', 'deep', 'deep/file' ],
|
||||
|
|
@ -351,7 +354,7 @@ cmp_bag($storage1->getFiles, [$filename], 'deleteFile: storage1 has only 1 file'
|
|||
|
||||
##Test for out of object file deletion
|
||||
my $hackedStore = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($hackedStore);
|
||||
addToCleanup($hackedStore);
|
||||
$hackedStore->addFileFromScalar('fileToHack', 'Can this file be deleted from another object?');
|
||||
ok(-e $hackedStore->getPath('fileToHack'), 'set up a file for deleteFile to try and delete illegally');
|
||||
my $hackedPath = '../../../'.$hackedStore->getPathFrag().'/fileToHack';
|
||||
|
|
@ -365,6 +368,7 @@ ok(-e $hackedStore->getPath('fileToHack'), 'deleteFile did not delete the file i
|
|||
####################################################
|
||||
|
||||
my $tempStor = WebGUI::Storage->createTemp($session);
|
||||
addToCleanup($tempStor);
|
||||
|
||||
isa_ok( $tempStor, "WebGUI::Storage", "createTemp creates WebGUI::Storage object");
|
||||
is (substr($tempStor->getPathFrag, 0, 5), 'temp/', '... puts stuff in the temp directory');
|
||||
|
|
@ -379,6 +383,7 @@ is($tempStor->getHexId, $session->id->toHex($tempStor->getId), '... returns the
|
|||
####################################################
|
||||
|
||||
my $tarStorage = $copiedStorage->tar('tar.tar');
|
||||
addToCleanup($tarStorage);
|
||||
isa_ok( $tarStorage, "WebGUI::Storage", "tar: returns a WebGUI::Storage object");
|
||||
is (substr($tarStorage->getPathFrag, 0, 5), 'temp/', 'tar: puts stuff in the temp directory');
|
||||
cmp_bag($tarStorage->getFiles(), [ 'tar.tar' ], 'tar: storage contains only the tar file');
|
||||
|
|
@ -391,6 +396,7 @@ isnt($tarStorage->getPath, $copiedStorage->getPath, 'tar did not reuse the same
|
|||
####################################################
|
||||
|
||||
my $untarStorage = $tarStorage->untar('tar.tar');
|
||||
addToCleanup($untarStorage);
|
||||
isa_ok( $untarStorage, "WebGUI::Storage", "untar: returns a WebGUI::Storage object");
|
||||
is (substr($untarStorage->getPathFrag, 0, 5), 'temp/', 'untar: puts stuff in the temp directory');
|
||||
##Note, getFiles will NOT recurse, so do not use a deep directory structure here
|
||||
|
|
@ -431,7 +437,7 @@ cmp_bag(
|
|||
|
||||
{
|
||||
my $deepStorage = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($deepStorage);
|
||||
addToCleanup($deepStorage);
|
||||
my $deepDir = $deepStorage->getPathClassDir();
|
||||
my $deepDeepDir = $deepDir->subdir('deep');
|
||||
my $errorStr;
|
||||
|
|
@ -461,13 +467,23 @@ is($fileStore->addFileFromFormPost(), '', 'addFileFromFormPost returns empty str
|
|||
|
||||
$session->http->setStatus(200);
|
||||
$session->request->upload('files', []);
|
||||
is($fileStore->addFileFromFormPost('files'), undef, 'addFileFromFormPost returns empty string when asking for a form variable with no files attached');
|
||||
my $formStore = WebGUI::Storage->create($session);
|
||||
addToCleanup($formStore);
|
||||
is($formStore->addFileFromFormPost('files'), undef, 'addFileFromFormPost returns empty string when asking for a form variable with no files attached');
|
||||
|
||||
$session->request->uploadFiles(
|
||||
'oneFile',
|
||||
[ WebGUI::Test->getTestCollateralPath('WebGUI.pm') ],
|
||||
);
|
||||
is($fileStore->addFileFromFormPost('oneFile'), 'WebGUI.pm', 'Return the name of the uploaded file');
|
||||
is($formStore->addFileFromFormPost('oneFile'), 'WebGUI.pm', '... returns the name of the uploaded file');
|
||||
cmp_bag($formStore->getFiles, [ qw/WebGUI.pm/ ], '... adds the file to the storage location');
|
||||
|
||||
$session->request->uploadFiles(
|
||||
'thumbFile',
|
||||
[ WebGUI::Test->getTestCollateralPath('thumb-thumb.gif') ],
|
||||
);
|
||||
is($formStore->addFileFromFormPost('thumbFile'), 'thumb.gif', '... strips thumb- prefix from files');
|
||||
cmp_bag($formStore->getFiles, [ qw/WebGUI.pm thumb.gif/ ], '... adds the file to the storage location');
|
||||
|
||||
####################################################
|
||||
#
|
||||
|
|
@ -486,7 +502,7 @@ foreach my $iconTest (@{ $fileIconTests }) {
|
|||
####################################################
|
||||
|
||||
my $shallowStorage = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($shallowStorage);
|
||||
addToCleanup($shallowStorage);
|
||||
$shallowStorage->setPrivileges(3,3,3);
|
||||
my $shallowDir = $shallowStorage->getPathClassDir();
|
||||
ok(-e $shallowDir->file('.wgaccess')->stringify, 'setPrivilege: .wgaccess file created in shallow storage');
|
||||
|
|
@ -496,7 +512,7 @@ is ($privs, "3\n3\n3", '... correct group contents');
|
|||
$shallowStorage->deleteFile('.wgaccess');
|
||||
|
||||
my $deepStorage = WebGUI::Storage->create($session);
|
||||
WebGUI::Test->storagesToDelete($deepStorage);
|
||||
addToCleanup($deepStorage);
|
||||
my $deepDir = $deepStorage->getPathClassDir();
|
||||
my $deepDeepDir = $deepDir->subdir('deep');
|
||||
my $errorStr;
|
||||
|
|
@ -533,6 +549,7 @@ $session->config->set('cdn', $cdnCfg);
|
|||
my $cdnUrl = $cdnCfg->{'url'};
|
||||
my $cdnUlen = length $cdnUrl;
|
||||
my $cdnStorage = WebGUI::Storage->create($session);
|
||||
addToCleanup($cdnStorage);
|
||||
# Functional URL before sync done
|
||||
my $hexId = $session->id->toHex($cdnStorage->getId);
|
||||
my $initUrl = join '/', $uploadUrl, $cdnStorage->getPathFrag;
|
||||
|
|
@ -596,6 +613,7 @@ $mockEnv{HTTPS} = undef;
|
|||
is ($cdnStorage->getUrl, $locUrl, 'CDN: getUrl: cleartext request to not use sslUrl');
|
||||
# Copy
|
||||
my $cdnCopy = $cdnStorage->copy;
|
||||
addToCleanup($cdnCopy);
|
||||
my $qcp = $cdnCfg->{'queuePath'} . '/' . $session->id->toHex($cdnCopy->getId);
|
||||
ok (-e $qcp, 'CDN: queue file created when storage location copied');
|
||||
my $dotcp = $cdnCopy->getPath . '/.cdn';
|
||||
|
|
@ -624,6 +642,23 @@ undef $cdnStorage;
|
|||
$session->config->delete('cdn');
|
||||
|
||||
|
||||
####################################################
|
||||
#
|
||||
# Test what happens when the directory for a
|
||||
# storage object does not exist.
|
||||
#
|
||||
####################################################
|
||||
|
||||
my $zombieStorage = WebGUI::Storage->create($session);
|
||||
addToCleanup($zombieStorage);
|
||||
my $zombieDir = $zombieStorage->getPathClassDir;
|
||||
$zombieDir->remove;
|
||||
|
||||
is( $zombieStorage->getPathClassDir, undef, 'bad storage: getPathClassDir returns undef');
|
||||
cmp_deeply( $zombieStorage->getFiles, [], '... getFiles returns an empty array ref');
|
||||
cmp_deeply( $zombieStorage->setPrivileges, undef, '... setPrivileges returns undef');
|
||||
cmp_deeply( $zombieStorage->clear, undef, '... setPrivileges returns undef');
|
||||
|
||||
####################################################
|
||||
#
|
||||
# Make sure after all this that our CWD is still the same
|
||||
|
|
@ -694,20 +729,3 @@ sub setupDataDrivenTests {
|
|||
|
||||
return ($extensionTests, $fileIconTests)
|
||||
}
|
||||
|
||||
####################################################
|
||||
#
|
||||
# END block, clean-up after yourself
|
||||
#
|
||||
####################################################
|
||||
|
||||
END {
|
||||
foreach my $stor (
|
||||
$storage1, $copiedStorage,
|
||||
$secondCopy, $tempStor, $tarStorage,
|
||||
$untarStorage, $fileStore,
|
||||
$cdnStorage, $cdnCopy,
|
||||
) {
|
||||
ref $stor eq "WebGUI::Storage" and $stor->delete;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use lib "$FindBin::Bin/lib";
|
|||
use WebGUI::Test;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::VersionTag;
|
||||
use Test::More tests => 68; # increment this value for each test you create
|
||||
use Test::More tests => 74; # increment this value for each test you create
|
||||
|
||||
my $session = WebGUI::Test->session;
|
||||
|
||||
|
|
@ -379,6 +379,38 @@ $adminUserTag->rollback();
|
|||
setSiteVersionTagMode($session, q{multiPerUser});
|
||||
setUserVersionTagMode($user, q{inherited});
|
||||
|
||||
my $andySession = WebGUI::Test->newSession();
|
||||
my $redSession = WebGUI::Test->newSession();
|
||||
|
||||
my $andy = WebGUI::User->create($andySession);
|
||||
my $red = WebGUI::User->create($redSession);
|
||||
addToCleanup($andy, $red);
|
||||
|
||||
my $andyTag = WebGUI::VersionTag->getWorking($andySession);
|
||||
addToCleanup($andyTag);
|
||||
my $redTag = WebGUI::VersionTag->new($redSession, $andyTag->getId);
|
||||
$redTag->setWorking();
|
||||
is($andyTag->getId, $redTag->getId, 'users share the same version tag');
|
||||
|
||||
$andyTag->leaveTag;
|
||||
{
|
||||
my $andyTagCheck = WebGUI::VersionTag->getWorking($andySession, 'nocreate');
|
||||
is($andyTagCheck, undef, 'leaveTag: user andy does not have tag');
|
||||
my $redTagCheck = WebGUI::VersionTag->getWorking($redSession, 'nocreate');
|
||||
isa_ok($redTagCheck, 'WebGUI::VersionTag', '... user red does');
|
||||
is($redTagCheck->getId, $redTag->getId, '... user red still has the same tag as before');
|
||||
}
|
||||
|
||||
my $andyTag2 = WebGUI::VersionTag->new($session, $redTag->getId);
|
||||
$andyTag2->clearWorking;
|
||||
{
|
||||
my $andyTagCheck = WebGUI::VersionTag->getWorking($andySession, 'nocreate');
|
||||
is($andyTagCheck, undef, 'clearWorking: user andy does not have tag');
|
||||
my $redSession2 = $redSession->duplicate;
|
||||
addToCleanup($redSession2);
|
||||
my $redTagCheck = WebGUI::VersionTag->getWorking($redSession2, 'nocreate');
|
||||
is($redTagCheck, undef, 'red does not either');
|
||||
}
|
||||
|
||||
# Local variables:
|
||||
# mode: cperl
|
||||
|
|
|
|||
|
|
@ -74,8 +74,6 @@ our @EXPORT_OK = qw(session config);
|
|||
my $CLASS = __PACKAGE__;
|
||||
|
||||
my @guarded;
|
||||
our @checkCount;
|
||||
our %initCounts;
|
||||
|
||||
sub import {
|
||||
our $CONFIG_FILE = $ENV{ WEBGUI_CONFIG };
|
||||
|
|
@ -101,22 +99,34 @@ sub import {
|
|||
|
||||
if ($ENV{WEBGUI_TEST_DEBUG}) {
|
||||
##Offset Sessions, and Scratch by 1 because 1 will exist at the start
|
||||
@checkCount = (
|
||||
Sessions => userSession => 1,
|
||||
Scratch => userSessionScratch => 1,
|
||||
Users => users => 0,
|
||||
Groups => groups => 0,
|
||||
mailQ => mailQueue => 0,
|
||||
Tags => assetVersionTag => 0,
|
||||
Assets => assetData => 0,
|
||||
Workflows => Workflow => 0,
|
||||
Carts => cart => 0,
|
||||
my @checkCount = (
|
||||
Sessions => 'userSession',
|
||||
Scratch => 'userSessionScratch',
|
||||
Users => 'users',
|
||||
Groups => 'groups',
|
||||
mailQ => 'mailQueue',
|
||||
Tags => 'assetVersionTag',
|
||||
Assets => 'assetData',
|
||||
Workflows => 'Workflow',
|
||||
Carts => 'cart',
|
||||
Transactions => 'transaction',
|
||||
'Transaction Items' => 'transactionItem',
|
||||
'Ship Drivers' => 'shipper',
|
||||
);
|
||||
for ( my $i = 0; $i < @checkCount; $i += 3) {
|
||||
my %initCounts;
|
||||
for ( my $i = 0; $i < @checkCount; $i += 2) {
|
||||
my ($label, $table) = @checkCount[$i, $i+1];
|
||||
$initCounts{$table} = $session->db->quickScalar('SELECT COUNT(*) FROM ' . $table);
|
||||
}
|
||||
push @guarded, Scope::Guard->new(sub {
|
||||
for ( my $i = 0; $i < @checkCount; $i += 2) {
|
||||
my ($label, $table) = @checkCount[$i, $i+1];
|
||||
my $quant = $session->db->quickScalar('SELECT COUNT(*) FROM ' . $table);
|
||||
my $delta = $quant - $initCounts{$table};
|
||||
if ($delta) {
|
||||
$CLASS->builder->diag(sprintf '%-10s: %4d (delta %+d)', $label, $quant, $delta);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -133,25 +143,15 @@ sub cleanup {
|
|||
pop @guarded
|
||||
while @guarded;
|
||||
|
||||
if ( my $session = $CLASS->session ) {
|
||||
$session->var->end;
|
||||
my $db = delete $session->{_db};
|
||||
$session->close;
|
||||
##Do this absolutely last, so that there's no session or other object pieces left over.
|
||||
if ($ENV{WEBGUI_TEST_DEBUG}) {
|
||||
for ( my $i = 0; $i < @checkCount; $i += 3) {
|
||||
my ($label, $table, $offset) = @checkCount[$i, $i+1, $i+2];
|
||||
my $quant = $db->quickScalar('SELECT COUNT(*) FROM ' . $table);
|
||||
my $delta = $quant - $initCounts{$table} + $offset;
|
||||
if ($delta) {
|
||||
$CLASS->builder->diag(sprintf '%-10s: %4d (delta %+d)', $label, $quant, $delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
$db->disconnect;
|
||||
if ( our $SESSION ) {
|
||||
$SESSION->var->end;
|
||||
$SESSION->close;
|
||||
undef $SESSION;
|
||||
}
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 newSession ( $noCleanup )
|
||||
|
||||
Builds a WebGUI session object for testing.
|
||||
|
|
@ -162,8 +162,6 @@ If true, the session won't be registered for automatic deletion.
|
|||
|
||||
=cut
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
sub newSession {
|
||||
my $noCleanup = shift;
|
||||
my $pseudoRequest = WebGUI::PseudoRequest->new;
|
||||
|
|
@ -176,6 +174,8 @@ sub newSession {
|
|||
}
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 mockAssetId ( $assetId, $object )
|
||||
|
||||
Causes WebGUI::Asset->new* initializers to return the specified
|
||||
|
|
@ -767,6 +767,9 @@ were passed in. Currently able to destroy:
|
|||
WebGUI::User
|
||||
WebGUI::VersionTag
|
||||
WebGUI::Workflow
|
||||
WebGUI::Shop::Cart
|
||||
WebGUI::Shop::ShipDriver
|
||||
WebGUI::Shop::Transaction
|
||||
|
||||
Example call:
|
||||
|
||||
|
|
@ -835,14 +838,21 @@ Example call:
|
|||
);
|
||||
|
||||
my %cleanup = (
|
||||
'WebGUI::User' => 'delete',
|
||||
'WebGUI::Group' => 'delete',
|
||||
'WebGUI::Storage' => 'delete',
|
||||
'WebGUI::Shop::Cart' => 'delete',
|
||||
'WebGUI::Asset' => 'purge',
|
||||
'WebGUI::VersionTag' => 'rollback',
|
||||
'WebGUI::Workflow' => 'delete',
|
||||
'WebGUI::Session' => sub {
|
||||
'WebGUI::User' => 'delete',
|
||||
'WebGUI::Group' => 'delete',
|
||||
'WebGUI::Storage' => 'delete',
|
||||
'WebGUI::Asset' => 'purge',
|
||||
'WebGUI::VersionTag' => 'rollback',
|
||||
'WebGUI::Workflow' => 'delete',
|
||||
'WebGUI::Shop::Transaction' => 'delete',
|
||||
'WebGUI::Shop::ShipDriver' => 'delete',
|
||||
'WebGUI::Shop::Cart' => sub {
|
||||
my $cart = shift;
|
||||
my $addressBook = $cart->getAddressBook();
|
||||
$addressBook->delete if $addressBook; ##Should we call cleanupGuard instead???
|
||||
$cart->delete;
|
||||
},
|
||||
'WebGUI::Session' => sub {
|
||||
my $session = shift;
|
||||
$session->var->end;
|
||||
$session->close;
|
||||
|
|
|
|||
40
t/supporting_collateral/tbb.rss
Normal file
40
t/supporting_collateral/tbb.rss
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>The Black Blog</title>
|
||||
<link>/tbb</link>
|
||||
<copyright /><pubDate>Mon, 12 Oct 2009 11:54:28 -0500</pubDate>
|
||||
<description /><item><title>Google Picasa Plugin for WebGUI Gallery</title>
|
||||
<link>http://www.plainblack.com/tbb/google-picasa-plugin-for-webgui-gallery</link>
|
||||
<author>JT</author>
|
||||
<epochDate>1254854387</epochDate>
|
||||
<guid isPermaLink="true">http://www.plainblack.com/tbb/google-picasa-plugin-for-webgui-gallery</guid>
|
||||
<pubDate>Tue, 06 Oct 2009 13:39:47 -0500</pubDate>
|
||||
<userDefined1 /><userDefined2 /><userDefined3 /><userDefined4 /><userDefined5 /><description>Today we unveil the Google Picasa plugin for WebGUI Gallery.</description>
|
||||
</item>
|
||||
<item><title>WebGUI Roadmap</title>
|
||||
<link>http://www.plainblack.com/tbb/webgui-roadmap</link>
|
||||
<author>JT</author>
|
||||
<epochDate>1254325377</epochDate>
|
||||
<guid isPermaLink="true">http://www.plainblack.com/tbb/webgui-roadmap</guid>
|
||||
<pubDate>Wed, 30 Sep 2009 10:42:57 -0500</pubDate>
|
||||
<userDefined1 /><userDefined2 /><userDefined3 /><userDefined4 /><userDefined5 /><description>The new roadmap is online.</description>
|
||||
</item>
|
||||
<item><title>WebGUI 8 Performance</title>
|
||||
<link>http://www.plainblack.com/tbb/webgui-8-performance</link>
|
||||
<author>JT</author>
|
||||
<epochDate>1254236976</epochDate>
|
||||
<guid isPermaLink="true">http://www.plainblack.com/tbb/webgui-8-performance</guid>
|
||||
<pubDate>Tue, 29 Sep 2009 10:09:36 -0500</pubDate>
|
||||
<userDefined1 /><userDefined2 /><userDefined3 /><userDefined4 /><userDefined5 /><description>WebGUI 8 is going to be the fastest version of WebGUI ever released.</description>
|
||||
</item>
|
||||
<item><title>I have arrived in Lisboa!</title>
|
||||
<link>http://www.plainblack.com/tbb/i-have-arrived-in-lisboa</link>
|
||||
<author>JT</author>
|
||||
<epochDate>1249140064</epochDate>
|
||||
<guid isPermaLink="true">http://www.plainblack.com/tbb/i-have-arrived-in-lisboa</guid>
|
||||
<pubDate>Sat, 01 Aug 2009 10:21:04 -0500</pubDate>
|
||||
<userDefined1 /><userDefined2 /><userDefined3 /><userDefined4 /><userDefined5 /><description>I'm in Lisbon, Portugal for YAPC::EU.</description>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
BIN
t/supporting_collateral/thumb-thumb.gif
Normal file
BIN
t/supporting_collateral/thumb-thumb.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
|
|
@ -13,6 +13,7 @@ if ( typeof WebGUI.AssetManager == "undefined" ) {
|
|||
|
||||
// Keep track of the open more menus
|
||||
WebGUI.AssetManager.MoreMenusDisplayed = {};
|
||||
WebGUI.AssetManager.CrumbMoreMenu;
|
||||
// Append something to a url:
|
||||
WebGUI.AssetManager.appendToUrl = function ( url, params ) {
|
||||
var components = [ url ];
|
||||
|
|
@ -348,16 +349,20 @@ WebGUI.AssetManager.selectRow = function ( child ) {
|
|||
*/
|
||||
WebGUI.AssetManager.showMoreMenu
|
||||
= function ( url, linkTextId, isNotLocked ) {
|
||||
var more = document.getElementById(linkTextId);
|
||||
|
||||
var options = WebGUI.AssetManager.buildMoreMenu(url, more, isNotLocked);
|
||||
|
||||
var menu = new YAHOO.widget.Menu( "crumbMoreMenu", options );
|
||||
menu.render( document.getElementById( 'assetManager' ) );
|
||||
var menu;
|
||||
if ( typeof WebGUI.AssetManager.CrumbMoreMenu == "undefined" ) {
|
||||
var more = document.getElementById(linkTextId);
|
||||
var options = WebGUI.AssetManager.buildMoreMenu(url, more, isNotLocked);
|
||||
menu = new YAHOO.widget.Menu( "crumbMoreMenu", options );
|
||||
menu.render( document.getElementById( 'assetManager' ) );
|
||||
WebGUI.AssetManager.CrumbMoreMenu = menu;
|
||||
}
|
||||
else {
|
||||
menu = WebGUI.AssetManager.CrumbMoreMenu;
|
||||
}
|
||||
menu.show();
|
||||
menu.focus();
|
||||
//YAHOO.util.Event.onDOMReady( function () { menu.render( document.getElementById( 'assetManager' ) ) } );
|
||||
//YAHOO.util.Event.addListener( more, "click", function (e) { menu.show(); menu.focus(); YAHOO.util.Event.stopEvent(e); }, null, menu );
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue