Merge branch 'master' of git@github.com:plainblack/webgui

This commit is contained in:
daviddelikat 2009-10-23 05:07:49 -05:00
commit 945017d762
46 changed files with 1496 additions and 492 deletions

View file

@ -1,4 +1,18 @@
7.8.3
- fixed #11074: Links to CS posts not working
- fixed #11152: Image edits do not autocommit version tags
- fixed template attachments are not cleaned up during purge
- fixed #11150: matrix - search boxes all ticked
- fixed #11063: template_attachments
- fixed #11002: Matrix shows backend stuff on load
- added #10082: Unarchive all collaboration posts
- fixed #11086: bad urls in wiki
- fixed #11047: required field on dataform
- fixed #11162: Can't delete calendar Related Material Link
- fixed #11154: vendor payouts screen borked ( Martin Kamerbeek / Oqapi )
7.8.2 7.8.2
- Added scheduled vendor payout workflow activity. (Special thanks to Martin @ Oqapi)
- fixed #11098: Leaving a version tag makes everyone leave - fixed #11098: Leaving a version tag makes everyone leave
- fixed #11096: Error on deleting FAQ(CS)-item - fixed #11096: Error on deleting FAQ(CS)-item
- fixed #11060: Some tables have latin1 as the default character set - fixed #11060: Some tables have latin1 as the default character set
@ -29,6 +43,11 @@
- fixed #11156: Syndicated Content doesn't show all headlines in feed - fixed #11156: Syndicated Content doesn't show all headlines in feed
- fixed #11138: RichEdit, upload image does not commit a version tag - fixed #11138: RichEdit, upload image does not commit a version tag
- fixed ExpireIncompleteSurveyResponses Workflow: process responses for deleted users - fixed ExpireIncompleteSurveyResponses Workflow: process responses for deleted users
- fixed #11157: calendar tool for entering add event date
- fixed #11158: Calendar iCal feed doesn't show today's all-day events
- added #10614: Force rich editor to use strong and em instead of b and i
- fixed #11131: https / http URLs still caching across secure/insecure boundary
- fixed #11093: Spectre cron can DoS server with many sites
7.8.1 7.8.1
- mark $session->datetime->time as deprecated and remove its use from core code - mark $session->datetime->time as deprecated and remove its use from core code

File diff suppressed because one or more lines are too long

View file

@ -7,6 +7,11 @@ upgrading from one version to the next, or even between multiple
versions. Be sure to heed the warnings contained herein as they will versions. Be sure to heed the warnings contained herein as they will
save you many hours of grief. save you many hours of grief.
7.8.2
--------------------------------------------------------------------
* WebGUI now requires Business::PayPal::API 0.62 or higher.
7.8.1 7.8.1
-------------------------------------------------------------------- --------------------------------------------------------------------
@ -32,6 +37,7 @@ save you many hours of grief.
prefix from the filename. prefix from the filename.
7.8.0 7.8.0
-------------------------------------------------------------------- --------------------------------------------------------------------

File diff suppressed because one or more lines are too long

View file

@ -35,18 +35,36 @@ fixTableDefaultCharsets($session);
correctWikiAttachmentPermissions( $session ); correctWikiAttachmentPermissions( $session );
transactionsNotifications( $session ); transactionsNotifications( $session );
fixBadVarCharColumns ( $session ); fixBadVarCharColumns ( $session );
addVendorPayouts($session);
finish($session); # this line required finish($session); # this line required
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# Describe what our function does sub addVendorPayouts {
#sub exampleFunction { my $session = shift;
# my $session = shift; print "\tAdding vendor payouts... " unless $quiet;
# print "\tWe're doing some stuff here that you should know about... " unless $quiet; my $db = $session->db;
# # and here's our code $db->write(" create table if not exists vendorPayoutLog (
# print "DONE!\n" unless $quiet; payoutId char(22) binary not null primary key,
#} isSuccessful tinyint(1) not null,
errorCode char(10),
errorMessage char(255),
paypalTimestamp char(20) not null,
amount decimal(7,2) not null,
currency char(3) not null,
correlationId char(13) not null,
paymentInformation char(255) not null
)");
$db->write(" create table if not exists vendorPayoutLog_items (
payoutId char(22) binary not null,
transactionItemId char(22) binary not null,
amount decimal(7,2) not null,
primary key( payoutId, transactionItemId )
)");
print "DONE!\n" unless $quiet;
}
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
sub fixTableDefaultCharsets { sub fixTableDefaultCharsets {

View file

@ -0,0 +1,157 @@
#!/usr/bin/env perl
#-------------------------------------------------------------------
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
#-------------------------------------------------------------------
# Please read the legal notices (docs/legal.txt) and the license
# (docs/license.txt) that came with this distribution before using
# this software.
#-------------------------------------------------------------------
# http://www.plainblack.com info@plainblack.com
#-------------------------------------------------------------------
our ($webguiRoot);
BEGIN {
$webguiRoot = "../..";
unshift (@INC, $webguiRoot."/lib");
}
use strict;
use Getopt::Long;
use WebGUI::Session;
use WebGUI::Storage;
use WebGUI::Asset;
my $toVersion = '7.8.3';
my $quiet; # this line required
my $session = start(); # this line required
# upgrade functions go here
reKeyTemplateAttachments($session);
addSelectPaymentGatewayTemplateToSettings($session);
finish($session); # this line required
#----------------------------------------------------------------------------
# Describe what our function does
sub reKeyTemplateAttachments {
my $session = shift;
print "\tChanging the key structure for the template attachments table... " unless $quiet;
# and here's our code
$session->db->write('ALTER TABLE template_attachments ADD COLUMN attachId CHAR(22) BINARY NOT NULL');
my $rh = $session->db->read('select url, templateId, revisionDate from template_attachments');
my $wh = $session->db->prepare('update template_attachments set attachId=? where url=? and templateId=? and revisionDate=?');
while (my @key = $rh->array) {
$wh->execute([$session->id->generate, @key ]);
}
$rh->finish;
$wh->finish;
$session->db->write('ALTER TABLE template_attachments DROP PRIMARY KEY');
$session->db->write('ALTER TABLE template_attachments ADD PRIMARY KEY (attachId)');
print "DONE!\n" unless $quiet;
}
#----------------------------------------------------------------------------
# add default template for selectPaymentGateway
sub addSelectPaymentGatewayTemplateToSettings {
my $session = shift;
print "\tAdding select payment gateway template to settings... " unless $quiet;
$session->db->write("insert into settings values ('selectGatewayTemplateId', '2GxjjkRuRkdUg_PccRPjpA');");
print "Done.\n" unless $quiet;
}
#sub exampleFunction {
# my $session = shift;
# print "\tWe're doing some stuff here that you should know about... " unless $quiet;
# # and here's our code
# print "DONE!\n" unless $quiet;
#}
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
#----------------------------------------------------------------------------
# Add a package to the import node
sub addPackage {
my $session = shift;
my $file = shift;
# 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

View file

@ -162,8 +162,9 @@ sub checkSchedule {
&& $self->checkSegment($now->day, $job->{dayOfMonth}, [1..31]) && $self->checkSegment($now->day, $job->{dayOfMonth}, [1..31])
&& $self->checkSegment($now->month, $job->{monthOfYear}, [1..12]) && $self->checkSegment($now->month, $job->{monthOfYear}, [1..12])
&& $self->checkSegment($now->dow % 7, $job->{dayOfWeek}, [0..6]) ) { && $self->checkSegment($now->dow % 7, $job->{dayOfWeek}, [0..6]) ) {
$self->debug("It's time to run ".$jobId.". Creating workflow instance."); $self->debug("It's time to run ".$jobId.". Creating workflow instance in ".$self->{_jobDelay}." seconds.");
$kernel->yield("runJob",$jobId); $kernel->delay_set("runJob", $self->{_jobDelay}, $jobId);
$self->{_jobDelay} += $self->config->get('timeBetweenRunningWorkflows');
} }
} }
@ -180,8 +181,9 @@ sub checkSchedules {
$self->debug("Checking schedules against current time."); $self->debug("Checking schedules against current time.");
my $now = DateTime->now(time_zone => 'local'); my $now = DateTime->now(time_zone => 'local');
foreach my $id (keys %{$self->{_jobs}}) { foreach my $id (keys %{$self->{_jobs}}) {
$kernel->yield("checkSchedule", $id, $now) $kernel->delay_set("checkSchedule", $self->{_jobDelay}, $id, $now)
} }
$self->{_jobDelay} = $self->config->get('timeBetweenRunningWorkflows');
$kernel->delay_set("checkSchedules",60); $kernel->delay_set("checkSchedules",60);
} }
@ -380,7 +382,13 @@ sub new {
my $config = shift; my $config = shift;
my $logger = shift; my $logger = shift;
my $debug = shift; my $debug = shift;
my $self = {_jobs=>{}, _debug=>$debug, _config=>$config, _logger=>$logger}; my $self = {
_jobs => {},
_debug => $debug,
_config => $config,
_logger => $logger,
_jobDelay => $config->get('timeBetweenRunningWorkflows'),
};
bless $self, $class; bless $self, $class;
my @publicEvents = qw(runJob runJobResponse addJob deleteJob getJsonStatus); my @publicEvents = qw(runJob runJobResponse addJob deleteJob getJsonStatus);
POE::Session->create( POE::Session->create(

View file

@ -1,7 +1,7 @@
package WebGUI; package WebGUI;
our $VERSION = '7.8.2'; our $VERSION = '7.8.3';
our $STATUS = 'beta'; our $STATUS = 'beta';

View file

@ -826,6 +826,26 @@ sub getAdminConsole {
} }
#-------------------------------------------------------------------
=head2 getCache ( )
Returns a cache object specific to this asset, and whether or not the request is in SSL mode.
=cut
sub getCache {
my $self = shift;
my $session = $self->session;
my $cacheKey = "view_".$self->getId;
if ($session->env->sslRequest) {
$cacheKey .= '_ssl';
}
my $cache = WebGUI::Cache->new($session, $cacheKey);
return $cache;
}
#------------------------------------------------------------------- #-------------------------------------------------------------------
=head2 getContainer ( ) =head2 getContainer ( )

View file

@ -608,7 +608,8 @@ Generate the view method for the Asset, and handle caching.
sub view { sub view {
my $self = shift; my $self = shift;
if (!$self->session->var->isAdminOn && $self->get("cacheTimeout") > 10) { if (!$self->session->var->isAdminOn && $self->get("cacheTimeout") > 10) {
my $out = WebGUI::Cache->new($self->session,"view_".$self->getId)->get; my $cache = $self->getCache;
my $out = $cache->get if defined $cache;
return $out if $out; return $out if $out;
} }
my %var = %{$self->get}; my %var = %{$self->get};

View file

@ -223,7 +223,8 @@ Renders this asset.
sub view { sub view {
my $self = shift; my $self = shift;
if (!$self->session->var->isAdminOn && $self->get("cacheTimeout") > 10) { if (!$self->session->var->isAdminOn && $self->get("cacheTimeout") > 10) {
my $out = WebGUI::Cache->new($self->session,"view_".$self->getId)->get; my $cache = $self->getCache;
my $out = $cache->get if defined $cache;
return $out if $out; return $out if $out;
} }
my %var = %{$self->get}; my %var = %{$self->get};
@ -277,23 +278,27 @@ Also adds the Image template form variable.
=cut =cut
sub www_edit { sub www_edit {
my $self = shift; my $self = shift;
return $self->session->privilege->insufficient() unless $self->canEdit; my $session = $self->session;
return $self->session->privilege->locked() unless $self->canEditIfLocked; return $session->privilege->insufficient() unless $self->canEdit;
my $i18n = WebGUI::International->new($self->session, 'Asset_Image'); return $session->privilege->locked() unless $self->canEditIfLocked;
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=resize'),$i18n->get("resize image")) if ($self->get("filename")); my $i18n = WebGUI::International->new($session, 'Asset_Image');
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=rotate'),$i18n->get("rotate image")) if ($self->get("filename")); if ($self->get('filename')) {
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=crop'),$i18n->get("crop image")) if ($self->get("filename")); my $ac = $self->getAdminConsole;
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=annotate'),$i18n->get("annotate image")) if ($self->get("filename")); $ac->addSubmenuItem($self->getUrl('func=resize'), $i18n->get("resize image"));
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=undo'),$i18n->get("undo image")) if ($self->get("filename")); $ac->addSubmenuItem($self->getUrl('func=rotate'), $i18n->get("rotate image"));
my $tabform = $self->getEditForm; $ac->addSubmenuItem($self->getUrl('func=crop'), $i18n->get("crop image"));
$tabform->getTab("display")->template( $ac->addSubmenuItem($self->getUrl('func=annotate'), $i18n->get("annotate image"));
-value=>$self->get("templateId"), $ac->addSubmenuItem($self->getUrl('func=undo'), $i18n->get("undo image"));
-namespace=>"ImageAsset", }
-hoverHelp=>$i18n->get('image template description'), my $tabform = $self->getEditForm;
-defaultValue=>"PBtmpl0000000000000088" $tabform->getTab("display")->template(
); -value => $self->get("templateId"),
return $self->getAdminConsole->render($tabform->print,$i18n->get("edit image")); -namespace => "ImageAsset",
-hoverHelp => $i18n->get('image template description'),
-defaultValue => "PBtmpl0000000000000088",
);
return $self->getAdminConsole->render($tabform->print,$i18n->get("edit image"));
} }
#------------------------------------------------------------------- #-------------------------------------------------------------------
@ -308,18 +313,8 @@ have been done to it.
sub www_undo { sub www_undo {
my $self = shift; my $self = shift;
my $previous = (@{$self->getRevisions()})[1]; my $previous = (@{$self->getRevisions()})[1];
# instantiate assetId
if ($previous) { if ($previous) {
# my $session = $self->session; $self->purgeRevision();
# my $cache = WebGUI::Cache->new($self->session, ["asset",$self->getId,$self->getRevisionDate]);
# $cache->flush;
# my $cache = WebGUI::Cache->new($previous->session, ["asset",$previous->getId,$previous->getRevisionDate]);
# $cache->flush;
$self = $self->purgeRevision();
# $self = undef;
# $self = WebGUI::Asset->new($previous->session, $previous->getId, ref $previous, $previous->getRevisionDate);
$self = $previous; $self = $previous;
$self->generateThumbnail; $self->generateThumbnail;
} }
@ -341,20 +336,21 @@ Allow the user to place some text on their image. This is done via JS and toolt
=cut =cut
sub www_annotate { sub www_annotate {
my $self = shift; my $self = shift;
return $self->session->privilege->insufficient() unless $self->canEdit; my $session = $self->session;
return $self->session->privilege->locked() unless $self->canEditIfLocked; return $session->privilege->insufficient() unless $self->canEdit;
return $session->privilege->locked() unless $self->canEditIfLocked;
if (1) { if (1) {
my $newSelf = $self->addRevision(); my $newSelf = $self->addRevision();
delete $newSelf->{_storageLocation}; delete $newSelf->{_storageLocation};
$newSelf->getStorageLocation->annotate($newSelf->get("filename"),$newSelf,$newSelf->session->form); $newSelf->getStorageLocation->annotate($newSelf->get("filename"),$newSelf,$session->form);
$newSelf->setSize($newSelf->getStorageLocation->getFileSize($newSelf->get("filename"))); $newSelf->setSize($newSelf->getStorageLocation->getFileSize($newSelf->get("filename")));
$self = $newSelf; $self = $newSelf;
$self->generateThumbnail; $self->generateThumbnail;
WebGUI::VersionTag->autoCommitWorkingIfEnabled($session, { allowComments => 0 });
} }
my ($style, $url) = $self->session->quick(qw(style url)); my ($style, $url) = $session->quick(qw(style url));
# $style->setLink($url->extras('annotate/imageMap.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setLink($url->extras('yui/build/resize/assets/skins/sam/resize.css'), {rel=>'stylesheet', type=>'text/css'}); $style->setLink($url->extras('yui/build/resize/assets/skins/sam/resize.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setLink($url->extras('yui/build/fonts/fonts-min.css'), {rel=>'stylesheet', type=>'text/css'}); $style->setLink($url->extras('yui/build/fonts/fonts-min.css'), {rel=>'stylesheet', type=>'text/css'});
@ -366,10 +362,7 @@ sub www_annotate {
$style->setScript($url->extras('yui/build/resize/resize-min.js'), {type=>'text/javascript'}); $style->setScript($url->extras('yui/build/resize/resize-min.js'), {type=>'text/javascript'});
$style->setScript($url->extras('yui/build/imagecropper/imagecropper-min.js'), {type=>'text/javascript'}); $style->setScript($url->extras('yui/build/imagecropper/imagecropper-min.js'), {type=>'text/javascript'});
# my $imageAsset = $self->session->db->getRow("ImageAsset","assetId",$self->getId);
my @pieces = split(/\n/, $self->get('annotations')); my @pieces = split(/\n/, $self->get('annotations'));
# my ($top_left, $width_height, $note) = split(/\n/, $imageAsset->{annotations});
my ($img_null, $tooltip_block, $tooltip_none) = ('', '', ''); my ($img_null, $tooltip_block, $tooltip_none) = ('', '', '');
for (my $i = 0; $i < $#pieces; $i += 3) { for (my $i = 0; $i < $#pieces; $i += 3) {
@ -377,7 +370,6 @@ sub www_annotate {
$tooltip_block .= "YAHOO.util.Dom.setStyle('tooltip$i', 'display', 'block');\n"; $tooltip_block .= "YAHOO.util.Dom.setStyle('tooltip$i', 'display', 'block');\n";
$tooltip_none .= "YAHOO.util.Dom.setStyle('tooltip$i', 'display', 'none');\n"; $tooltip_none .= "YAHOO.util.Dom.setStyle('tooltip$i', 'display', 'none');\n";
my $j = $i + 2; my $j = $i + 2;
# warn("i: $i: ", $self->session->form->process("delAnnotate$i"));
} }
my $image = '<div align="center" class="yui-skin-sam"><img src="'.$self->getStorageLocation->getUrl($self->get("filename")).'" style="border-style:none;" alt="'.$self->get("filename").'" id="yui_img" /></div>'; my $image = '<div align="center" class="yui-skin-sam"><img src="'.$self->getStorageLocation->getUrl($self->get("filename")).'" style="border-style:none;" alt="'.$self->get("filename").'" id="yui_img" /></div>';
@ -385,8 +377,8 @@ sub www_annotate {
my ($width, $height) = $self->getStorageLocation->getSize($self->get("filename")); my ($width, $height) = $self->getStorageLocation->getSize($self->get("filename"));
my @checkboxes = (); my @checkboxes = ();
my $i18n = WebGUI::International->new($self->session,"Asset_Image"); my $i18n = WebGUI::International->new($session,"Asset_Image");
my $f = WebGUI::HTMLForm->new($self->session,-action=>$self->getUrl); my $f = WebGUI::HTMLForm->new($session);
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=edit'),$i18n->get("edit image")); $self->getAdminConsole->addSubmenuItem($self->getUrl('func=edit'),$i18n->get("edit image"));
$f->hidden( $f->hidden(
@ -563,49 +555,51 @@ Returns the user to the roate form.
=cut =cut
sub www_rotate { sub www_rotate {
my $self = shift; my $self = shift;
return $self->session->privilege->insufficient() unless $self->canEdit; my $session = $self->session;
return $self->session->privilege->locked() unless $self->canEditIfLocked; return $session->privilege->insufficient() unless $self->canEdit;
if (defined $self->session->form->process("Rotate")) { return $session->privilege->locked() unless $self->canEditIfLocked;
if (defined $session->form->process("Rotate")) {
my $newSelf = $self->addRevision(); my $newSelf = $self->addRevision();
delete $newSelf->{_storageLocation}; delete $newSelf->{_storageLocation};
$newSelf->getStorageLocation->rotate($newSelf->get("filename"),$newSelf->session->form->process("Rotate")); $newSelf->getStorageLocation->rotate($newSelf->get("filename"),$session->form->process("Rotate"));
$newSelf->setSize($newSelf->getStorageLocation->getFileSize($newSelf->get("filename"))); $newSelf->setSize($newSelf->getStorageLocation->getFileSize($newSelf->get("filename")));
$self = $newSelf; $self = $newSelf;
$self->generateThumbnail; $self->generateThumbnail;
WebGUI::VersionTag->autoCommitWorkingIfEnabled($session, { allowComments => 0 });
} }
my ($x, $y) = $self->getStorageLocation->getSizeInPixels($self->get("filename")); my ($x, $y) = $self->getStorageLocation->getSizeInPixels($self->get("filename"));
##YUI specific datatable CSS ##YUI specific datatable CSS
my ($style, $url) = $self->session->quick(qw(style url)); my ($style, $url) = $session->quick(qw(style url));
my $img_name = $self->getStorageLocation->getUrl($self->get("filename")); my $img_name = $self->getStorageLocation->getUrl($self->get("filename"));
my $img_file = $self->get("filename"); my $img_file = $self->get("filename");
my $image = '<div align="center" class="yui-skin-sam"><img src="'.$self->getStorageLocation->getUrl($self->get("filename")).'" style="border-style:none;" alt="'.$self->get("filename").'" id="yui_img" /></div>'; my $image = '<div align="center" class="yui-skin-sam"><img src="'.$self->getStorageLocation->getUrl($self->get("filename")).'" style="border-style:none;" alt="'.$self->get("filename").'" id="yui_img" /></div>';
my $i18n = WebGUI::International->new($self->session,"Asset_Image"); my $i18n = WebGUI::International->new($session,"Asset_Image");
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=edit'),$i18n->get("edit image")); $self->getAdminConsole->addSubmenuItem($self->getUrl('func=edit'),$i18n->get("edit image"));
my $f = WebGUI::HTMLForm->new($self->session,-action=>$self->getUrl); my $f = WebGUI::HTMLForm->new($session);
$f->hidden( $f->hidden(
-name=>"func", -name=>"func",
-value=>"rotate" -value=>"rotate"
); );
$f->button( $f->button(
-value=>"Left", -value=>"Left",
-extras=>qq(onclick="var deg = document.getElementById('Rotate_formId').value; deg = parseInt(deg) + 90; document.getElementById('Rotate_formId').value = deg;"), -extras=>qq(onclick="var deg = document.getElementById('Rotate_formId').value; deg = parseInt(deg) + 90; document.getElementById('Rotate_formId').value = deg;"),
); );
$f->button( $f->button(
-value=>"Right", -value=>"Right",
-extras=>qq(onclick="var deg = document.getElementById('Rotate_formId').value; deg = parseInt(deg) - 90; document.getElementById('Rotate_formId').value = deg;"), -extras=>qq(onclick="var deg = document.getElementById('Rotate_formId').value; deg = parseInt(deg) - 90; document.getElementById('Rotate_formId').value = deg;"),
); );
$f->integer( $f->integer(
-label=>$i18n->get('degree'), -label=>$i18n->get('degree'),
-name=>"Rotate", -name=>"Rotate",
-value=>0, -value=>0,
); );
$f->submit; $f->submit;
return $self->getAdminConsole->render($f->print.$image,$i18n->get("rotate image")); return $self->getAdminConsole->render($f->print.$image,$i18n->get("rotate image"));
} }
#------------------------------------------------------------------- #-------------------------------------------------------------------
@ -620,22 +614,24 @@ Returns the user to the resize form.
=cut =cut
sub www_resize { sub www_resize {
my $self = shift; my $self = shift;
return $self->session->privilege->insufficient() unless $self->canEdit; my $session = $self->session;
return $self->session->privilege->locked() unless $self->canEditIfLocked; return $session->privilege->insufficient() unless $self->canEdit;
if ($self->session->form->process("newWidth") || $self->session->form->process("newHeight")) { return $session->privilege->locked() unless $self->canEditIfLocked;
my $newSelf = $self->addRevision(); if ($session->form->process("newWidth") || $session->form->process("newHeight")) {
delete $newSelf->{_storageLocation}; my $newSelf = $self->addRevision();
$newSelf->getStorageLocation->resize($newSelf->get("filename"),$newSelf->session->form->process("newWidth"),$newSelf->session->form->process("newHeight")); delete $newSelf->{_storageLocation};
$newSelf->setSize($newSelf->getStorageLocation->getFileSize($newSelf->get("filename"))); $newSelf->getStorageLocation->resize($newSelf->get("filename"),$session->form->process("newWidth"),$session->form->process("newHeight"));
$self = $newSelf; $newSelf->setSize($newSelf->getStorageLocation->getFileSize($newSelf->get("filename")));
$self->generateThumbnail; $self = $newSelf;
} $self->generateThumbnail;
WebGUI::VersionTag->autoCommitWorkingIfEnabled($session, { allowComments => 0 });
}
my ($x, $y) = $self->getStorageLocation->getSizeInPixels($self->get("filename")); my ($x, $y) = $self->getStorageLocation->getSizeInPixels($self->get("filename"));
##YUI specific datatable CSS ##YUI specific datatable CSS
my ($style, $url) = $self->session->quick(qw(style url)); my ($style, $url) = $session->quick(qw(style url));
$style->setLink($url->extras('yui/build/fonts/fonts-min.css'), {rel=>'stylesheet', type=>'text/css'}); $style->setLink($url->extras('yui/build/fonts/fonts-min.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setLink($url->extras('yui/build/resize/assets/skins/sam/resize.css'), {rel=>'stylesheet', type=>'text/css'}); $style->setLink($url->extras('yui/build/resize/assets/skins/sam/resize.css'), {rel=>'stylesheet', type=>'text/css'});
@ -682,33 +678,33 @@ sub www_resize {
</script> </script>
); );
my $i18n = WebGUI::International->new($self->session,"Asset_Image"); my $i18n = WebGUI::International->new($session,"Asset_Image");
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=edit'),$i18n->get("edit image")); $self->getAdminConsole->addSubmenuItem($self->getUrl('func=edit'),$i18n->get("edit image"));
my $f = WebGUI::HTMLForm->new($self->session,-action=>$self->getUrl); my $f = WebGUI::HTMLForm->new($session);
$f->hidden( $f->hidden(
-name=>"func", -name=>"func",
-value=>"resize" -value=>"resize"
); );
$f->readOnly( $f->readOnly(
-label=>$i18n->get('image size'), -label=>$i18n->get('image size'),
-hoverHelp=>$i18n->get('image size description'), -hoverHelp=>$i18n->get('image size description'),
-value=>$x.' x '.$y, -value=>$x.' x '.$y,
); );
$f->integer( $f->integer(
-label=>$i18n->get('new width'), -label=>$i18n->get('new width'),
-hoverHelp=>$i18n->get('new width description'), -hoverHelp=>$i18n->get('new width description'),
-name=>"newWidth", -name=>"newWidth",
-value=>$x, -value=>$x,
); );
$f->integer( $f->integer(
-label=>$i18n->get('new height'), -label=>$i18n->get('new height'),
-hoverHelp=>$i18n->get('new height description'), -hoverHelp=>$i18n->get('new height description'),
-name=>"newHeight", -name=>"newHeight",
-value=>$y, -value=>$y,
); );
$f->submit; $f->submit;
my $image = '<div align="center" class="yui-skin-sam"><img src="'.$self->getStorageLocation->getUrl($self->get("filename")).'" style="border-style:none;" alt="'.$self->get("filename").'" id="yui_img" /></div>'.$resize_js; my $image = '<div align="center" class="yui-skin-sam"><img src="'.$self->getStorageLocation->getUrl($self->get("filename")).'" style="border-style:none;" alt="'.$self->get("filename").'" id="yui_img" /></div>'.$resize_js;
return $self->getAdminConsole->render($f->print.$image,$i18n->get("resize image")); return $self->getAdminConsole->render($f->print.$image,$i18n->get("resize image"));
} }
#------------------------------------------------------------------- #-------------------------------------------------------------------
@ -724,29 +720,31 @@ Returns the user to the cropping form.
=cut =cut
sub www_crop { sub www_crop {
my $self = shift; my $self = shift;
return $self->session->privilege->insufficient() unless $self->canEdit; my $session = $self->session;
return $self->session->privilege->locked() unless $self->canEditIfLocked; return $session->privilege->insufficient() unless $self->canEdit;
return $session->privilege->locked() unless $self->canEditIfLocked;
if ($self->session->form->process("Width") || $self->session->form->process("Height") if ($session->form->process("Width") || $session->form->process("Height")
|| $self->session->form->process("Top") || $self->session->form->process("Left")) { || $session->form->process("Top") || $session->form->process("Left")) {
my $newSelf = $self->addRevision(); my $newSelf = $self->addRevision();
delete $newSelf->{_storageLocation}; delete $newSelf->{_storageLocation};
$newSelf->getStorageLocation->crop( $newSelf->getStorageLocation->crop(
$newSelf->get("filename"), $newSelf->get("filename"),
$newSelf->session->form->process("Width"), $session->form->process("Width"),
$newSelf->session->form->process("Height"), $session->form->process("Height"),
$newSelf->session->form->process("Top"), $session->form->process("Top"),
$newSelf->session->form->process("Left") $session->form->process("Left")
); );
$self = $newSelf; $self = $newSelf;
$self->generateThumbnail; $self->generateThumbnail;
WebGUI::VersionTag->autoCommitWorkingIfEnabled($session, { allowComments => 0 });
} }
my $filename = $self->get("filename"); my $filename = $self->get("filename");
##YUI specific datatable CSS ##YUI specific datatable CSS
my ($style, $url) = $self->session->quick(qw(style url)); my ($style, $url) = $session->quick(qw(style url));
my $crop_js = qq( my $crop_js = qq(
<script> <script>
@ -784,10 +782,10 @@ sub www_crop {
$style->setScript($url->extras('yui/build/resize/resize-min.js'), {type=>'text/javascript'}); $style->setScript($url->extras('yui/build/resize/resize-min.js'), {type=>'text/javascript'});
$style->setScript($url->extras('yui/build/imagecropper/imagecropper-min.js'), {type=>'text/javascript'}); $style->setScript($url->extras('yui/build/imagecropper/imagecropper-min.js'), {type=>'text/javascript'});
my $i18n = WebGUI::International->new($self->session,"Asset_Image"); my $i18n = WebGUI::International->new($session,"Asset_Image");
$self->getAdminConsole->addSubmenuItem($self->getUrl('func=edit'),$i18n->get("edit image")); $self->getAdminConsole->addSubmenuItem($self->getUrl('func=edit'),$i18n->get("edit image"));
my $f = WebGUI::HTMLForm->new($self->session,-action=>$self->getUrl); my $f = WebGUI::HTMLForm->new($session);
$f->hidden( $f->hidden(
-name=>"degree", -name=>"degree",
-value=>"0" -value=>"0"
@ -823,7 +821,7 @@ sub www_crop {
); );
$f->submit; $f->submit;
my $image = '<div align="center" class="yui-skin-sam"><img src="'.$self->getStorageLocation->getUrl($filename).'" style="border-style:none;" alt="'.$filename.'" id="yui_img" /></div>'.$crop_js; my $image = '<div align="center" class="yui-skin-sam"><img src="'.$self->getStorageLocation->getUrl($filename).'" style="border-style:none;" alt="'.$filename.'" id="yui_img" /></div>'.$crop_js;
return $self->getAdminConsole->render($f->print.$image,$i18n->get("crop image")); return $self->getAdminConsole->render($f->print.$image,$i18n->get("crop image"));
} }

View file

@ -221,7 +221,8 @@ used to show the file to administrators.
sub view { sub view {
my $self = shift; my $self = shift;
if (!$self->session->var->isAdminOn && $self->get("cacheTimeout") > 10) { if (!$self->session->var->isAdminOn && $self->get("cacheTimeout") > 10) {
my $out = WebGUI::Cache->new($self->session,"view_".$self->getId)->get; my $cache = $self->getCache;
my $out = $cache->get if defined $cache;
return $out if $out; return $out if $out;
} }
my %var = %{$self->get}; my %var = %{$self->get};

View file

@ -1681,8 +1681,9 @@ sub view {
my $error = shift; my $error = shift;
my $session = $self->session; my $session = $self->session;
if (!$session->var->isAdminOn && $self->get("cacheTimeout") > 10){ if (!$session->var->isAdminOn && $self->get("cacheTimeout") > 10){
my $out = WebGUI::Cache->new($self->session,"view_".$self->getId)->get; my $cache = $self->getCache;
return $out if $out; my $out = $cache->get if defined $cache;
return $out if $out;
} }
my (%data, $segment, %var, @featureloop, @benefitloop, @specificationloop, @accessoryloop, @relatedloop); my (%data, $segment, %var, @featureloop, @benefitloop, @specificationloop, @accessoryloop, @relatedloop);
tie %data, 'Tie::CPHash'; tie %data, 'Tie::CPHash';

View file

@ -279,7 +279,8 @@ sub view {
|| $self->get("cacheTimeout") <= 10 || $self->get("cacheTimeout") <= 10
|| ($versionTag && $versionTag->getId eq $self->get("tagId")); || ($versionTag && $versionTag->getId eq $self->get("tagId"));
unless ($noCache) { unless ($noCache) {
my $out = WebGUI::Cache->new($session,"view_".$calledAsWebMethod."_".$self->getId)->get; my $cache = $self->getCache;
my $out = $cache->get if defined $cache;
return $out if $out; return $out if $out;
} }
my $output = $self->get('usePacked') my $output = $self->get('usePacked')

View file

@ -128,20 +128,16 @@ sub addAttachments {
my $db = $self->session->db; my $db = $self->session->db;
my $sql = q{
INSERT INTO template_attachments
(templateId, revisionDate, url, type, sequence)
VALUES
(?, ?, ?, ?, ?)
};
foreach my $a (@$attachments) { foreach my $a (@$attachments) {
my @params = ( my %params = (
$self->getId, templateId => $self->getId,
$self->get('revisionDate'), revisionDate => $self->get('revisionDate'),
@{$a}{qw(url type sequence)} url => $a->{url},
type => $a->{type},
sequence => $a->{sequence},
attachId => 'new',
); );
$db->write($sql, \@params); $db->setRow('template_attachments', 'attachId', \%params);
} }
} }
@ -719,9 +715,23 @@ sub processRaw {
#------------------------------------------------------------------- #-------------------------------------------------------------------
=head2 purge ( )
Extend the master to purge attachments in all revisions.
=cut
sub purge {
my $self = shift;
$self->session->db->write('delete from template_attachments where templateId=?', [$self->getId]);
return $self->SUPER::purge(@_);
}
#-------------------------------------------------------------------
=head2 purgeRevision ( ) =head2 purgeRevision ( )
Override the master purgeRevision to purge attachments Extend the master purgeRevision to purge attachments
=cut =cut

View file

@ -350,7 +350,8 @@ sub view {
my $self = shift; my $self = shift;
if (!$self->session->var->isAdminOn && $self->get("cacheTimeout") > 10 && !$self->session->form->process("overrideTemplateId") && if (!$self->session->var->isAdminOn && $self->get("cacheTimeout") > 10 && !$self->session->form->process("overrideTemplateId") &&
!$self->session->form->process($self->paginateVar) && !$self->session->form->process("makePrintable")) { !$self->session->form->process($self->paginateVar) && !$self->session->form->process("makePrintable")) {
my $out = WebGUI::Cache->new($self->session,"view_".$self->getId)->get; my $cache = $self->getCache;
my $out = $cache->get if defined $cache;
return $out if $out; return $out if $out;
} }
my %var; my %var;

File diff suppressed because it is too large Load diff

View file

@ -1572,6 +1572,23 @@ sub view {
#------------------------------------------------------------------- #-------------------------------------------------------------------
=head2 www_edit
Override the master class to add an "Unarchive All" link.
=cut
sub www_edit {
my $self = shift;
return $self->session->privilege->insufficient() unless $self->canEdit;
return $self->session->privilege->locked() unless $self->canEditIfLocked;
my $i18n = WebGUI::International->new($self->session, 'Asset_Collaboration');
$self->getAdminConsole->addConfirmedSubmenuItem($self->getUrl('func=unarchiveAll'),$i18n->get("unarchive all"),$i18n->get("unarchive confirm"));
return $self->getAdminConsole->render($self->getEditForm->print,$i18n->get("assetName"));
}
#-------------------------------------------------------------------
=head2 www_search ( ) =head2 www_search ( )
The web method to display and use the forum search interface. The web method to display and use the forum search interface.
@ -1627,6 +1644,35 @@ sub www_subscribe {
return $self->www_view; return $self->www_view;
} }
#----------------------------------------------------------------------------
=head2 www_unarchiveAll ( )
Unarchive all the threads in this collaboration system
=cut
sub www_unarchiveAll {
my ( $self ) = @_;
my $session = $self->session;
return $session->privilege->insufficient() unless $self->canEdit;
my $pb = WebGUI::ProgressBar->new($session);
my $i18n = WebGUI::International->new($session, 'Asset_Collaboration');
$pb->start($i18n->get('unarchive all'), $self->getUrl('func=edit'));
my $threadIds = $self->getLineage(['children'],{
includeOnlyClasses => [ 'WebGUI::Asset::Post::Thread' ],
statusToInclude => [ 'archived' ],
} );
ASSET: foreach my $threadId (@$threadIds) {
my $thread = WebGUI::Asset->newPending($session, $threadId);
if (!$thread || !$thread->canEdit) {
next ASSET;
}
$thread->unarchive;
}
return $pb->finish( $self->getUrl('func=edit') );
}
#------------------------------------------------------------------- #-------------------------------------------------------------------
=head2 www_unsubscribe ( ) =head2 www_unsubscribe ( )

View file

@ -409,12 +409,8 @@ sub www_view {
) { ) {
my $check = $self->checkView; my $check = $self->checkView;
return $check if (defined $check); return $check if (defined $check);
my $cacheKey = "view_".$self->getId; my $cache = $self->getCache;
if ($session->env->sslRequest) { my $out = $cache->get if defined $cache;
$cacheKey .= '_ssl';
}
my $cache = WebGUI::Cache->new($session, $cacheKey);
my $out = $cache->get if defined $cache;
unless ($out) { unless ($out) {
$self->prepareView; $self->prepareView;
$session->stow->set("cacheFixOverride", 1); $session->stow->set("cacheFixOverride", 1);

View file

@ -644,7 +644,6 @@ sub view {
my ($varStatistics,$varStatisticsEncoded); my ($varStatistics,$varStatisticsEncoded);
my $var = $self->get; my $var = $self->get;
$var->{listing_loop} = $self->getListings;
$var->{isLoggedIn} = ($session->user->userId ne "1"); $var->{isLoggedIn} = ($session->user->userId ne "1");
$var->{addMatrixListing_url} = $self->getUrl('func=add;class=WebGUI::Asset::MatrixListing'); $var->{addMatrixListing_url} = $self->getUrl('func=add;class=WebGUI::Asset::MatrixListing');
$var->{exportAttributes_url} = $self->getUrl('func=exportAttributes'); $var->{exportAttributes_url} = $self->getUrl('func=exportAttributes');
@ -1193,6 +1192,7 @@ sub www_getCompareFormData {
if($form->process("search")) { if($form->process("search")) {
if ($searchParamList) { if ($searchParamList) {
RESULT: foreach my $result (@{$self->getListings}) { RESULT: foreach my $result (@{$self->getListings}) {
my $checked = '';
my $matrixListing_attributes = $session->db->buildHashRefOfHashRefs(" my $matrixListing_attributes = $session->db->buildHashRefOfHashRefs("
select value, fieldType, attributeId from Matrix_attribute select value, fieldType, attributeId from Matrix_attribute
left join MatrixListing_attribute as listing using(attributeId) left join MatrixListing_attribute as listing using(attributeId)
@ -1203,24 +1203,21 @@ sub www_getCompareFormData {
my $fieldType = $matrixListing_attributes->{$param->{attributeId}}->{fieldType}; my $fieldType = $matrixListing_attributes->{$param->{attributeId}}->{fieldType};
my $listingValue = $matrixListing_attributes->{$param->{attributeId}}->{value}; my $listingValue = $matrixListing_attributes->{$param->{attributeId}}->{value};
if(($fieldType eq 'MatrixCompare') && ($listingValue < $param->{value})){ if(($fieldType eq 'MatrixCompare') && ($listingValue < $param->{value})){
$result->{checked} = '';
last PARAM; last PARAM;
} }
elsif(($fieldType ne 'MatrixCompare' && $fieldType ne '') && ($param->{value} ne $listingValue)){ elsif(($fieldType ne 'MatrixCompare' && $fieldType ne '') && ($param->{value} ne $listingValue)){
$result->{checked} = '';
last PARAM; last PARAM;
} }
else{ else{
$result->{checked} = 'checked'; $checked = 'checked';
} }
} }
$result->{assetId} =~ s/-/_____/g; $result->{assetId} =~ s/-/_____/g;
push @results, $result if $result->{checked} eq 'checked'; push @results, $result if $checked eq 'checked';
} }
} }
else { else {
foreach my $result (@{$self->getListings}) { foreach my $result (@{$self->getListings}) {
$result->{checked} = 'checked';
$result->{assetId} =~ s/-/_____/g; $result->{assetId} =~ s/-/_____/g;
push @results, $result; push @results, $result;
} }
@ -1390,7 +1387,7 @@ sub www_listAttributes {
=head2 www_search ( ) =head2 www_search ( )
Returns the search screen. Returns the search screen. Uses www_getCompareFormData with search=1 for doing AJAX requests.
=cut =cut

View file

@ -130,7 +130,8 @@ to be displayed within the page style
sub view { sub view {
my $self = shift; my $self = shift;
if (!$self->session->var->isAdminOn && $self->get("cacheTimeout") > 10) { if (!$self->session->var->isAdminOn && $self->get("cacheTimeout") > 10) {
my $out = WebGUI::Cache->new($self->session,"view_".$self->getId)->get; my $cache = $self->getCache;
my $out = $cache->get if defined $cache;
return $out if $out; return $out if $out;
} }
my $i18n = WebGUI::International->new($self->session, 'Asset_MultiSearch'); my $i18n = WebGUI::International->new($self->session, 'Asset_MultiSearch');

View file

@ -534,7 +534,8 @@ if the user is not in Admin Mode.
sub view { sub view {
my $self = shift; my $self = shift;
if (!$self->session->var->isAdminOn && $self->get("cacheTimeout") > 10) { if (!$self->session->var->isAdminOn && $self->get("cacheTimeout") > 10) {
my $out = WebGUI::Cache->new($self->session,"view_".$self->getId)->get; my $cache = $self->getCache;
my $out = $cache->get if defined $cache;
return $out if $out; return $out if $out;
} }
# Initiate an empty debug loop # Initiate an empty debug loop

View file

@ -159,7 +159,7 @@ sub appendSearchBoxVars {
#------------------------------------------------------------------- #-------------------------------------------------------------------
=head2 autolinkHtml ($html) =head2 autolinkHtml ($html, [options])
Scan HTML for words and phrases that match wiki titles, and automatically Scan HTML for words and phrases that match wiki titles, and automatically
link them to those wiki pages. Returns the modified HTML. link them to those wiki pages. Returns the modified HTML.
@ -168,6 +168,14 @@ link them to those wiki pages. Returns the modified HTML.
The HTML to scan. The HTML to scan.
=head3 options
Either a hashref, or a hash of options.
=head4 skipTitles
An array reference of titles that should not be autolinked.
=cut =cut
sub autolinkHtml { sub autolinkHtml {
@ -175,18 +183,21 @@ sub autolinkHtml {
my $html = shift; my $html = shift;
# opts is always the last parameter, and a hash ref # opts is always the last parameter, and a hash ref
my %opts = ref $_[-1] eq 'HASH' ? %{pop @_} : (); my %opts = ref $_[-1] eq 'HASH' ? %{pop @_} : ();
my $skipTitles = $opts{skipTitles} || []; $opts{skipTitles} ||= [];
# LC all the skip titles once, for efficiency
my @skipTitles = map { lc $_ } @{ $opts{skipTitles} };
# TODO: ignore caching for now, but maybe do it later. # TODO: ignore caching for now, but maybe do it later.
my %mapping = $self->session->db->buildHash("SELECT LOWER(d.title), d.url FROM asset AS i INNER JOIN assetData AS d ON i.assetId = d.assetId WHERE i.parentId = ? and className='WebGUI::Asset::WikiPage' and i.state='published' and d.status='approved'", [$self->getId]); # This query returns multiple entries for each asset, so we order by revisionDate and count on the hash to only have the
foreach my $key (keys %mapping) { # latest version.
if (grep {lc $_ eq $key} @$skipTitles) { my %mapping = $self->session->db->buildHash("SELECT LOWER(d.title), d.url FROM asset AS i INNER JOIN assetData AS d ON i.assetId = d.assetId WHERE i.parentId = ? and className='WebGUI::Asset::WikiPage' and i.state='published' and d.status='approved' order by d.revisionDate ASC", [$self->getId]);
delete $mapping{$key}; TITLE: foreach my $title (keys %mapping) {
next; my $url = delete $mapping{$title};
} ##isIn short circuits and is faster than grep and/or first
$key =~ s{\(}{\\\(}gxms; # escape parens next TITLE if isIn($title, @skipTitles);
$key =~ s{\)}{\\\)}gxms; # escape parens $mapping{$title} = $self->session->url->gateway($url);
$mapping{$key} = $self->session->url->gateway($mapping{$key}); }
}
return $html unless %mapping; return $html unless %mapping;
# sort by length so it prefers matching longer titles # sort by length so it prefers matching longer titles
my $matchString = join('|', map{quotemeta} sort {length($b) <=> length($a)} keys %mapping); my $matchString = join('|', map{quotemeta} sort {length($b) <=> length($a)} keys %mapping);

View file

@ -274,7 +274,8 @@ sub getRevisionCount {
=head2 getRevisions ( [ status ] ) =head2 getRevisions ( [ status ] )
Returns an array reference of the revision objects of this asset. Returns an array reference of the revision objects of this asset, sorted by revision date in descending
order. The most recent version will always be first.
=head3 status =head3 status

View file

@ -15,20 +15,22 @@ our $HELP = {
title => 'asset template asset var title', title => 'asset template asset var title',
body => '', body => '',
variables => [ variables => [
{ name => 'title', }, { name => 'assetId', },
{ name => 'assetIdHex', },
{ name => 'title', },
{ name => 'menuTitle', }, { name => 'menuTitle', },
{ name => 'url', }, { name => 'url', },
{ name => 'isHidden', }, { name => 'isHidden', },
{ name => 'newWindow', }, { name => 'newWindow', },
{ name => 'encryptPage', }, { name => 'encryptPage', },
{ name => 'ownerUserId', }, { name => 'ownerUserId', },
{ name => 'groupIdView', }, { name => 'groupIdView', },
{ name => 'groupIdEdit', }, { name => 'groupIdEdit', },
{ name => 'synopsis', }, { name => 'synopsis', },
{ name => 'extraHeadTags', }, { name => 'extraHeadTags', },
{ name => 'isPackage', }, { name => 'isPackage', },
{ name => 'isPrototype', }, { name => 'isPrototype', },
{ name => 'status', }, { name => 'status', },
{ name => 'assetSize', }, { name => 'assetSize', },
{ name => 'keywords', { name => 'keywords',
description => 'keywords template var' }, description => 'keywords template var' },

View file

@ -180,6 +180,13 @@ sub www_editSettings {
label => $i18n->get("edit address template"), label => $i18n->get("edit address template"),
hoverHelp => $i18n->get("edit address template help"), hoverHelp => $i18n->get("edit address template help"),
); );
$form->template(
name => "selectGatewayTemplateId",
value => $setting->get("selectGatewayTemplateId"),
label => $i18n->get("select gateway template"),
namespace => "Shop/selectGateway",
hoverHelp => $i18n->get("select gateway template help"),
);
$form->template( $form->template(
name => "shopMyPurchasesTemplateId", name => "shopMyPurchasesTemplateId",
value => $setting->get("shopMyPurchasesTemplateId"), value => $setting->get("shopMyPurchasesTemplateId"),
@ -226,7 +233,7 @@ sub www_editSettingsSave {
# Save shop templates # Save shop templates
foreach my $template (qw(shopMyPurchasesDetailTemplateId shopMyPurchasesTemplateId foreach my $template (qw(shopMyPurchasesDetailTemplateId shopMyPurchasesTemplateId
shopCartTemplateId shopAddressBookTemplateId shopAddressTemplateId shopReceiptEmailTemplateId)) { shopCartTemplateId shopAddressBookTemplateId shopAddressTemplateId selectGatewayTemplateId shopReceiptEmailTemplateId)) {
$setting->set($template, $form->get($template, "template")); $setting->set($template, $form->get($template, "template"));
} }

View file

@ -423,12 +423,16 @@ sub www_selectPaymentGateway {
# TODO: If only one payOption exists, just send us there # TODO: If only one payOption exists, just send us there
# In order to do this, the PayDriver must give us a direct URL to go to # In order to do this, the PayDriver must give us a direct URL to go to
my $output .= $i18n->get('choose payment gateway message'); my $var;
my @paymentGateways;
foreach my $payOption ( values %{$payOptions} ) { foreach my $payOption ( values %{$payOptions} ) {
$output .= $payOption->{button} . '<br />'; push @paymentGateways, $payOption;
} }
$var->{ paymentGateways } = \@paymentGateways;
return $session->style->userStyle( $output ); $var->{ choose } = $i18n->get('choose payment gateway message');
$session->log->warn('###'.$session->setting->get("selectGatewayTemplateId"));
my $template = WebGUI::Asset::Template->new($session, $session->setting->get("selectGatewayTemplateId"));
return $session->style->userStyle($template->process($var));
} }
1; 1;

View file

@ -0,0 +1,124 @@
package WebGUI::Shop::PayDriver::Skeleton; #change the Skeleton with your own PayDriver name
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=cut
use strict;
use WebGUI::Shop::PayDriver;
use base qw/WebGUI::Shop::PayDriver/;
#-------------------------------------------------------------------
=head2 definition ( )
In the definition you can add your own properties
=cut
sub definition {
my $class = shift;
my $session = shift;
my $definition = shift;
WebGUI::Error::InvalidParam->throw( error => q{Must provide a session variable} )
unless $session && ref $session eq 'WebGUI::Session';
tie my %fields, 'Tie::IxHash';
#add some fields if you need your own parameters
# %fields = (
# currency => {
# fieldType => 'text',
# label => 'currency',
# hoverHelp => 'Fill in your currency',
# defaultValue => 'EUR',
# maxlength => 3,
# size => 3,
# },
# );
push @{ $definition }, {
name => 'Skeleton', #change the Skeleton with your own PayDriver name
properties => \%fields,
};
return $class->SUPER::definition($session, $definition);
}
#-------------------------------------------------------------------
=head2 canCheckoutCart ( )
Returns whether the cart can be checked out by this plugin.
=cut
sub canCheckoutCart {
my $self = shift;
my $cart = $self->getCart;
return 0 unless $cart->readyForCheckout;
return 0 if $cart->requiresRecurringPayment;
return 1;
}
#-------------------------------------------------------------------
=head2 getButton ( )
Create a button for the screen where you select the payment method. Redirect it
to your first www_ method you need
=cut
sub getButton {
my $self = shift;
my $button = WebGUI::Form::formHeader($self->session) .
$self->getDoFormTags('finish') .
WebGUI::Form::submit($self->session, {value => $self->get('label') }) .
WebGUI::Form::formFooter($self->session);
return $button;
}
#-------------------------------------------------------------------
=head2 processPayment ( )
Should interact with the payment gateway and then return an array containing
success/failure (as 1 or 0), transaction code (or payment gateway's transaction
id), status code, and status message.
=cut
sub processPayment {
return (1, undef, 1, 'Success');
}
#-------------------------------------------------------------------
=head2 www_dosomething ( )
Create your own www_ method. They are available from the outside.
So www_finish can be called directly with:
http://www.mysite.com/?shop=pay;method=do;do=finish
=cut
sub www_finish {
my ($self) = @_;
#prcess the transaction (it needs an WebGUI::Shop::Address object)
my $transaction = $self->processTransaction(
$self->getCart->getShippingAddress
);
#return the thankyou page to the user
return $transaction->thankYou();
}
1;

View file

@ -588,16 +588,26 @@ Returns the status to which the item(s) are set.
=cut =cut
sub www_setPayoutStatus { sub www_setPayoutStatus {
my $class = shift; my $class = shift;
my $session = shift; my $session = shift;
my ( $form, $db ) = $session->quick( qw{ form db } );
my $admin = WebGUI::Shop::Admin->new($session); my $admin = WebGUI::Shop::Admin->new($session);
return $session->privilege->adminOnly() unless ($admin->canManage); return $session->privilege->adminOnly() unless ($admin->canManage);
my @itemIds = $session->form->process('itemId'); my $status = $form->process('status');
my $status = $session->form->process('status');
return "error: wrong status [$status]" unless isIn( $status, qw{ NotPaid Scheduled } ); return "error: wrong status [$status]" unless isIn( $status, qw{ NotPaid Scheduled } );
my @itemIds;
if ( $form->process( 'all' ) ) {
@itemIds = $session->db->buildArray( 'select itemId from transactionItem where vendorPayoutStatus = ?' , [
( $status eq 'NotPaid' ) ? 'Scheduled' : 'NotPaid'
] );
}
else {
@itemIds = $form->process('itemId');
}
foreach my $itemId (@itemIds) { foreach my $itemId (@itemIds) {
my $item = WebGUI::Shop::TransactionItem->newByDynamicTransaction( $session, $itemId ); my $item = WebGUI::Shop::TransactionItem->newByDynamicTransaction( $session, $itemId );
return "error: invalid transactionItemId [$itemId]" unless $item; return "error: invalid transactionItemId [$itemId]" unless $item;

View file

@ -0,0 +1,262 @@
package WebGUI::Workflow::Activity::PayoutVendors;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=cut
use strict;
use Business::PayPal::API qw{ MassPay };
use Data::Dumper;
use WebGUI::Mail::Send;
use base 'WebGUI::Workflow::Activity';
=head1 NAME
Package WebGUI::Workflow::Activity::PayoutVendors
=head1 DESCRIPTION
Pays profits to vendors, currently via paypal, but others may be added in the future.
=head1 SYNOPSIS
See WebGUI::Workflow::Activity for details on how to use any activity.
=head1 METHODS
These methods are available from this class:
=cut
#-------------------------------------------------------------------
=head2 definition ()
See WebGUI::Workflow::Activity for details.
=cut
sub definition {
my $class = shift;
my $session = shift;
my $definition = shift;
my $i18n = WebGUI::International->new($session, "Workflow_Activity_PayoutVendors");
tie my %properties, 'Tie::IxHash', (
paypalUsername => {
fieldType => 'text',
label => $i18n->get('PayPal username'),
},
paypalPassword => {
fieldType => 'password',
label => $i18n->get('PayPal password'),
},
paypalSignature => {
fieldType => 'text',
label => $i18n->get('PayPal signature'),
},
useSandbox => {
fieldType => 'yesNo',
label => $i18n->get('Use in Sandbox (test-mode)'),
defaultValue => 0,
},
currencyCode => {
fieldType => 'text',
label => $i18n->get('Currency code'),
maxlength => 3,
size => 3,
defaultValue => 'USD',
},
paypalSubject => {
fieldType => 'text',
label => $i18n->get('Subject for vendor notication email'),
defaultValue => $i18n->get('Vendor payout from').' ' . $session->setting->get('companyUrl'),
},
notificationGroupId => {
fieldType => 'group',
label => $i18n->get('Notify on error'),
},
);
push @{ $definition }, {
name => $i18n->get('Vendor Payout'),
properties => \%properties,
};
return $class->SUPER::definition( $session, $definition );
}
#-------------------------------------------------------------------
=head2 payoutVendor (vendorId)
Sends unsent vendor payouts to paypal.
=head3 vendorId
The vendor to be sent his payouts.
=cut
sub payoutVendor {
my $self = shift;
my $vendorId = shift;
my $db = $self->session->db;
my $payoutId = $self->session->id->generate;
# Instanciate vendor and check if he exists.
my $vendor = WebGUI::Shop::Vendor->new( $self->session, $vendorId );
unless ( $vendor ) {
$self->session->log->error( "Could not instanciate vendor with id [$vendorId] for payout" );
return undef;
}
# check to see that the vendor has a payout address
if ($vendor->get('paymentInformation') eq '') {
$self->session->log->warn("Vendor ".$vendor->getId." hasn't specified a payout address.");
return undef;
}
# Fetch all transactionItems that are scheduled for payout to the vendor.
my $sth = $db->read(
'select itemId, vendorPayoutAmount from transactionItem '
. ' where vendorId=? and vendorPayoutStatus=? and vendorPayoutAmount > 0',
[
$vendorId,
'Scheduled',
]
);
# Process all transaction items and log them in the db.
my $totalAmount = 0;
while ( my $item = $sth->hashRef ) {
$totalAmount += $item->{ vendorPayoutAmount };
$db->write( 'insert into vendorPayoutLog_items (payoutId, transactionItemId, amount) values (?,?,?)', [
$payoutId,
$item->{ itemId },
$item->{ vendorPayoutAmount },
] );
}
my $itemCount = $sth->rows;
$sth->finish;
# Do PayPal MassPay request
my $pp = new Business::PayPal::API(
Username => $self->get('paypalUsername'),
Password => $self->get('paypalPassword'),
Signature => $self->get('paypalSignature'),
sandbox => $self->get('useSandbox'),
);
my %response = $pp->MassPay(
EmailSubject => $self->get('paypalSubject'),
currencyID => $self->get('currencyCode'),
MassPayItems => [ {
ReceiverEmail => $vendor->get('paymentInformation'),
Amount => $totalAmount,
UniqueID => $payoutId,
Note => "Payout for $itemCount sold items",
} ],
);
# Process paypal response
my $payoutDetails = {
payoutId => $payoutId,
isSuccessful => $response{ Ack } eq 'Success' ? 1 : 0,
paypalTimestamp => $response{ Timestamp },
correlationId => $response{ CorrelationID },
amount => $totalAmount,
currency => $self->get('currencyCode'),
paymentInformation => $vendor->get('paymentInformation'),
};
if ( $response{ Ack } ne 'Success' ) {
# An error occurred, keep the error codes
my $errorCode = $response{ Error }->[ 0 ]->{ ErrorCode };
my $errorMessage = $response{ Error }->[ 0 ]->{ LongMessage };
# TODO: Send out email.
my $mail = WebGUI::Mail::Send->create($self->session, {
toGroup => $self->get('notificationGroupId'),
subject => 'Vendor payout error',
});
$mail->addText(
"An error occurred during an automated vendor payout attempt. Response details:\n"
. Dumper( \%response )
. "\n\nVendor information:\n"
. Dumper( $vendor->get )
);
$mail->send;
$payoutDetails->{ errorCode } = $errorCode;
$payoutDetails->{ errorMessage } = $errorMessage;
}
else {
# The transaction was successful, so change the state of the transactionItems to Paid.
$db->write(
'update transactionItem set vendorPayoutStatus=? where itemId in ( '
.' select transactionItemId from vendorPayoutLog_items where payoutId=? '
.')',
[
'Paid',
$payoutId,
]
);
}
# Persist response data to db
$db->setRow( 'vendorPayoutLog', 'payoutId', $payoutDetails, $payoutId );
};
#-------------------------------------------------------------------
=head2 execute ()
See WebGUI::Workflow::Activity for details.
=cut
sub execute {
my $self = shift;
my $object = shift;
my $instance = shift;
my $start = time;
my $ttl = $self->getTTL;
# Fetch vendors eligible for payout.
my $sth = $self->session->db->read(
"select distinct vendorId from transactionItem where vendorPayoutStatus='Scheduled' and vendorPayoutAmount > 0"
);
# Pay on a vendor by vendor basis.
while ( (my $vendorId) = $sth->array ) {
$self->payoutVendor( $vendorId );
# Make sure we won't run longer than allowed.
if ( ( time - $start + 1 ) >= $ttl ) {
$sth->finish;
return $self->WAITING( 1 );
}
}
$sth->finish;
return $self->COMPLETE;
}
1;

View file

@ -1088,6 +1088,16 @@ Couldn't open %-s because %-s <br />
lastUpdated => 1100463645, lastUpdated => 1100463645,
}, },
'assetId' => {
message => q|The unique identifier for this Asset, in base64 encoding.|,
lastUpdated => 1256327617,
},
'assetIdHex' => {
message => q|The unique identifier for this Asset, in hexadecimal format.|,
lastUpdated => 1256327617,
},
'title' => { 'title' => {
message => q|The title of the Asset|, message => q|The title of the Asset|,
lastUpdated => 1160773957, lastUpdated => 1160773957,

View file

@ -1736,6 +1736,18 @@ the Collaboration Asset, the user will be notified.|,
lastUpdated => 1229910435, lastUpdated => 1229910435,
}, },
'unarchive all' => {
message => q{Unarchive All Threads},
context => q{Label for link to unarchive all threads},
lastUpdated => 0,
},
'unarchive confirm' => {
message => q{Are you sure? Any threads past the 'Archive After' interval will be re-archived.},
context => q{Text for pop-up dialog to confirm unarchive all threads},
lastUpdated => 0,
},
}; };
1; 1;

View file

@ -669,6 +669,18 @@ our $I18N = {
context => q|commerce setting help| context => q|commerce setting help|
}, },
'select gateway template' => {
message => q|Select Gateway Template|,
lastUpdated => 0,
context => q|commerce setting|
},
'select gateway template help' => {
message => q|This template is the template for the Select Payment Gateway step.|,
lastUpdated => 0,
context => q|commerce setting help|
},
'transactions' => { 'transactions' => {
message => q|Transactions|, message => q|Transactions|,
lastUpdated => 0, lastUpdated => 0,
@ -1594,6 +1606,24 @@ our $I18N = {
context => q|Table heading in the vendor payout manager.|, context => q|Table heading in the vendor payout manager.|,
}, },
'vp select vendor' => {
message => q|Please select a vendor from the list above to manage individual payouts.|,
lastUpdated => 0,
context => q|Message in the vendor payouts manager when no vendor has been selected.|,
},
'vp vendors' => {
message => q|Vendors|,
lastUpdated => 0,
context => q|Label for the vendors section of the vendor payouts manager|,
},
'vp payouts' => {
message => q|Payouts|,
lastUpdated => 0,
context => q|Label for the vendors section of the vendor payouts manager|,
},
'vp item id' => { 'vp item id' => {
message => q|Item ID|, message => q|Item ID|,
lastUpdated => 0, lastUpdated => 0,

View file

@ -0,0 +1,63 @@
package WebGUI::i18n::English::Workflow_Activity_PayoutVendors;
use strict;
our $I18N = {
'PayPal username' => {
message => q|PayPal username|,
lastUpdated => 0,
context => q|field label|
},
'PayPal password' => {
message => q|PayPal password|,
lastUpdated => 0,
context => q|field label|
},
'PayPal signature' => {
message => q|PayPal signature|,
lastUpdated => 0,
context => q|field label|
},
'Use in Sandbox (test-mode)' => {
message => q|Use in Sandbox (test-mode)|,
lastUpdated => 0,
context => q|field label|
},
'Currency code' => {
message => q|Currency code|,
lastUpdated => 0,
context => q|field label|
},
'Subject for vendor notification email' => {
message => q|Subject for vendor notification email|,
lastUpdated => 0,
context => q|field label|
},
'Vendor payout from' => {
message => q|Vendor payout from|,
lastUpdated => 0,
context => q|Prefix that goes before company URL to create the default value from Subject for vendor notification email.|
},
'Notify on error' => {
message => q|Notify on error|,
lastUpdated => 0,
context => q|field label|
},
'Vendor Payout' => {
message => q|Vendor Payout|,
lastUpdated => 0,
context => q|field label|
},
};
1;
#vim:ft=perl

View file

@ -133,6 +133,7 @@ checkModule('Digest::SHA', '5.47' );
checkModule("CSS::Minifier::XS", "0.03" ); checkModule("CSS::Minifier::XS", "0.03" );
checkModule("JavaScript::Minifier::XS", "0.05" ); checkModule("JavaScript::Minifier::XS", "0.05" );
checkModule("Readonly", "1.03" ); checkModule("Readonly", "1.03" );
checkModule("Business::PayPal::API", "0.62" );
failAndExit("Required modules are missing, running no more checks.") if $missingModule; failAndExit("Required modules are missing, running no more checks.") if $missingModule;

View file

@ -121,6 +121,10 @@ is($att4->[1]->{url}, 'bar', 'rev still has bar');
is($att4->[2]->{url}, 'baz', 'rev does have new thing'); is($att4->[2]->{url}, 'baz', 'rev does have new thing');
is(@$att4, 3, 'rev is proper size'); is(@$att4, 3, 'rev is proper size');
##This is a non-test. Duplicate URLs will not cause the test to blow-up with
##an untrappable error.
$template3rev->addAttachments([{ type => 'headScript', sequence => 3, url => 'baz'}]);
$template3rev->purgeRevision(); $template3rev->purgeRevision();
## Check how templates in the trash and clipboard are handled. ## Check how templates in the trash and clipboard are handled.
@ -168,6 +172,7 @@ like($brokenOutput, qr/$brokenUrl/, '... and the template url');
like($brokenOutput, qr/$brokenId/, '... and the template id'); like($brokenOutput, qr/$brokenId/, '... and the template id');
like($logError, qr/$brokenUrl/, 'process: logged error has the url'); like($logError, qr/$brokenUrl/, 'process: logged error has the url');
like($logError, qr/$brokenId/, '... and the template id'); like($logError, qr/$brokenId/, '... and the template id');
WebGUI::Test->restoreLogging;
WebGUI::Test->tagsToRollback(WebGUI::VersionTag->getWorking($session)); WebGUI::Test->tagsToRollback(WebGUI::VersionTag->getWorking($session));

View file

@ -57,7 +57,7 @@ use Data::Dumper;
use WebGUI::Asset::Wobject::Calendar; use WebGUI::Asset::Wobject::Calendar;
use WebGUI::Asset::Event; use WebGUI::Asset::Event;
plan tests => 15 + scalar @icalWrapTests; plan tests => 14 + scalar @icalWrapTests;
my $session = WebGUI::Test->session; my $session = WebGUI::Test->session;
@ -221,6 +221,30 @@ my $justAfterwt = $windowCal->addChild({
timeZone => $tz, timeZone => $tz,
}, undef, undef, {skipAutoCommitWorkflows => 1}); }, undef, undef, {skipAutoCommitWorkflows => 1});
my $coincident = $windowCal->addChild({
className => 'WebGUI::Asset::Event',
title => 'Coincident with the window start and window end',
startDate => $startDt->toDatabaseDate,
endDate => $endDt->toDatabaseDate,
timeZone => $tz,
}, undef, undef, {skipAutoCommitWorkflows => 1});
my $coincidentLow = $windowCal->addChild({
className => 'WebGUI::Asset::Event',
title => 'Coincident with the window start',
startDate => $startDt->toDatabaseDate,
endDate => $endDt->clone->add(days => 1)->toDatabaseDate,
timeZone => $tz,
}, undef, undef, {skipAutoCommitWorkflows => 1});
my $coincidentHigh = $windowCal->addChild({
className => 'WebGUI::Asset::Event',
title => 'Coincident with the window end',
startDate => $startDt->clone->add( days => -1, )->toDatabaseDate,
endDate => $endDt->toDatabaseDate,
timeZone => $tz,
}, undef, undef, {skipAutoCommitWorkflows => 1});
# wt suffix = with times # wt suffix = with times
# inside # inside
# insidewt # insidewt
@ -228,6 +252,9 @@ my $justAfterwt = $windowCal->addChild({
# |-------------straddlewt---------------| # |-------------straddlewt---------------|
# straddleLowwt # straddleLowwt
# straddleHighwt # straddleHighwt
# |----------coincident-----------|
# |----------coincidentLow------------------|
# |--------------------coincidentHigh-------|
# window: |-------------------------------| # window: |-------------------------------|
# justBeforewt justAfterwt # justBeforewt justAfterwt
# outside high # outside high
@ -239,7 +266,7 @@ my $tag2 = WebGUI::VersionTag->getWorking($session);
$tag2->commit; $tag2->commit;
WebGUI::Test->tagsToRollback($tag2); WebGUI::Test->tagsToRollback($tag2);
is(scalar @{ $windowCal->getLineage(['children'])}, 10, 'added events to the window calendar'); is(scalar @{ $windowCal->getLineage(['children'])}, 13, 'added events to the window calendar');
my @window = $windowCal->getEventsIn($startDt->toDatabase, $endDt->toDatabase); my @window = $windowCal->getEventsIn($startDt->toDatabase, $endDt->toDatabase);
@ -247,11 +274,14 @@ my @window = $windowCal->getEventsIn($startDt->toDatabase, $endDt->toDatabase);
#note join "\n", map { join ' ', $_->get('title'), $_->get('startDate'), $_->get('startTime')} @window; #note join "\n", map { join ' ', $_->get('title'), $_->get('startDate'), $_->get('startTime')} @window;
#note $endDt->toDatabase; #note $endDt->toDatabase;
is(scalar @window, 6, 'getEventsIn returned 6 events');
cmp_bag( cmp_bag(
[ map { $_->get('title') } @window ], [ map { $_->get('title') } @window ],
[ map { $_->get('title') } ($inside, $insidewt, $straddle, $straddleHighwt, $straddleLowwt, $straddlewt)], [ map { $_->get('title') }
'..returns correct 6 events' ($inside, $insidewt,
$straddle, $straddleHighwt, $straddleLowwt, $straddlewt,
$coincident, $coincidentLow, $coincidentHigh, )
],
'..returns correct set of events'
); );
###################################################################### ######################################################################

View file

@ -0,0 +1,56 @@
# vim:syntax=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
#------------------------------------------------------------------
# Test the unarchiveAll function of the collaboration system
#
#
use FindBin;
use strict;
use lib "$FindBin::Bin/../../../lib";
use Test::More;
use WebGUI::Test; # Must use this before any other WebGUI modules
use WebGUI::Session;
#----------------------------------------------------------------------------
# Init
my $session = WebGUI::Test->session;
my $collab = WebGUI::Asset->getImportNode( $session )->addChild({
className => 'WebGUI::Asset::Wobject::Collaboration',
archiveAfter => 60*60*365.25,
});
# Add a thread
my @threads = (
$collab->addChild({
className => 'WebGUI::Asset::Post::Thread',
status => 'archived',
title => 'Archived',
}, undef, undef, { skipAutoCommitWorkflows => 1 }),
);
my $tag = WebGUI::VersionTag->getWorking( $session );
$tag->commit;
WebGUI::Test->tagsToRollback($tag);
#----------------------------------------------------------------------------
# Tests
plan tests => 1; # Increment this number for each test you create
#----------------------------------------------------------------------------
# www_unarchiveAll sets all threads to approved
$collab->www_unarchiveAll;
$threads[0] = WebGUI::Asset->newByDynamicClass( $session, $threads[0]->getId );
is( $threads[0]->get('status'), 'approved', "unarchiveAll sets thread to approved" );
#vim:ft=perl

View file

@ -12,7 +12,7 @@ WebGUI.VendorPayout = function ( containerId ) {
'schedule all button', 'deschedule all button', 'submit scheduled payouts button', 'schedule all button', 'deschedule all button', 'submit scheduled payouts button',
'vendor id', 'vendor name', 'scheduled payout amount', 'not scheduled payout amount', 'vendor id', 'vendor name', 'scheduled payout amount', 'not scheduled payout amount',
'vp item id', 'vp item title', 'vp item price', 'vp item quantity', 'vp item payout amount', 'vp item id', 'vp item title', 'vp item price', 'vp item quantity', 'vp item payout amount',
'vp item payout status' 'vp item payout status', 'vp select vendor', 'vp vendors', 'vp payouts'
] ]
}, },
onpreload : { onpreload : {
@ -30,15 +30,49 @@ WebGUI.VendorPayout = function ( containerId ) {
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
WebGUI.VendorPayout.prototype.initialize = function (aaa, bbb,ccc,ddd) { WebGUI.VendorPayout.prototype.initialize = function (aaa, bbb,ccc,ddd) {
// Vendors data table // Vendor data table
this.vendorList = document.createElement('div'); this.vendorTable = document.createElement( 'div' );
this.container.appendChild( this.vendorList ); this.vendorButtons = document.createElement( 'div' );
var vendor = document.createElement( 'fieldset' );
var vendorLegend = document.createElement( 'legend' );
vendor.appendChild( vendorLegend ).innerHTML = this.i18n( 'vp vendors' );
vendor.appendChild( this.vendorTable );
vendor.appendChild( this.vendorButtons );
this.container.appendChild( vendor );
// Payout data table
this.payoutTable = document.createElement( 'div' );
this.payoutButtons = document.createElement( 'div' );
var payout = document.createElement( 'fieldset' );
var payoutLegend = document.createElement( 'legend' );
payout.appendChild( payoutLegend ).innerHTML = this.i18n( 'vp payouts' );
payout.appendChild( this.payoutTable );
payout.appendChild( this.payoutButtons );
this.container.appendChild( payout );
// (De)schedule buttons // (De)schedule buttons
this.buttonDiv = document.createElement('div'); this.scheduleAllPayoutsButton = new YAHOO.widget.Button( {
this.container.appendChild( this.buttonDiv ); label : this.i18n( 'schedule all button' ),
this.scheduleAllButton = new YAHOO.widget.Button({ label: this.i18n( 'schedule all button' ), container: this.buttonDiv }); container : this.payoutButtons,
this.descheduleAllButton = new YAHOO.widget.Button({ label: this.i18n( 'deschedule all button' ), container: this.buttonDiv }); disabled : true
} );
this.descheduleAllPayoutsButton = new YAHOO.widget.Button( {
label: this.i18n( 'deschedule all button' ),
container: this.payoutButtons,
disabled : true
} );
this.scheduleAllVendorsButton = new YAHOO.widget.Button( {
label : this.i18n( 'schedule all button' ),
container : this.vendorButtons
} );
this.descheduleAllVendorsButton = new YAHOO.widget.Button( {
label : this.i18n( 'deschedule all button' ),
container : this.vendorButtons
} );
// Submit button // Submit button
this.submitPayoutsButton = new YAHOO.widget.Button({ label: this.i18n( 'submit scheduled payouts button' ), container: this.buttonDiv }); this.submitPayoutsButton = new YAHOO.widget.Button({ label: this.i18n( 'submit scheduled payouts button' ), container: this.buttonDiv });
@ -80,7 +114,7 @@ WebGUI.VendorPayout.prototype.initVendorList = function () {
}; };
// initialize data table // initialize data table
this.vendorDataTable = new YAHOO.widget.DataTable( this.vendorList, this.vendorSchema, this.vendorDataSource, { this.vendorDataTable = new YAHOO.widget.DataTable( this.vendorTable, this.vendorSchema, this.vendorDataSource, {
selectionMode : 'single' selectionMode : 'single'
} ); } );
@ -93,9 +127,12 @@ WebGUI.VendorPayout.prototype.initVendorList = function () {
this.vendorDataTable.subscribe( "rowClickEvent", function (e) { this.vendorDataTable.subscribe( "rowClickEvent", function (e) {
var record = this.getRecord( e.target ); var record = this.getRecord( e.target );
obj.currentVendorId = record.getData( 'vendorId' ); obj.currentVendorId = record.getData( 'vendorId' );
obj.currentVendorRow = record; obj.currentVendorIndex = this.getRecordIndex( record );
obj.refreshItemDataTable(); obj.refreshItemDataTable();
obj.scheduleAllPayoutsButton.set( 'disabled', false );
obj.descheduleAllPayoutsButton.set( 'disabled', false );
} ); } );
} }
@ -110,13 +147,20 @@ WebGUI.VendorPayout.prototype.refreshItemDataTable = function () {
} ); } );
} }
//----------------------------------------------------------------------------
WebGUI.VendorPayout.prototype.refreshVendorDataTable = function () {
this.vendorDataSource.sendRequest( '', {
success : this.vendorDataTable.onDataReturnUpdateRows, //ReplaceRows,
scope : this.vendorDataTable
} );
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
WebGUI.VendorPayout.prototype.refreshVendorRow = function () { WebGUI.VendorPayout.prototype.refreshVendorRow = function () {
var obj = this; var obj = this;
this.vendorDataSource.sendRequest( 'vendorId=' + this.currentVendorId, { this.vendorDataSource.sendRequest( 'vendorId=' + this.currentVendorId, {
// onDataReturnUpdateRows is not available in yui 2.6.0... success : function ( req, response , payload ) {
success : function ( req, response , payload ) { this.updateRow( obj.currentVendorIndex, response.results[0] );
this.updateRow( obj.currentVendorRow, response.results[0] );
}, },
scope : this.vendorDataTable scope : this.vendorDataTable
} ); } );
@ -156,11 +200,12 @@ WebGUI.VendorPayout.prototype.initPayoutDetails = function () {
}; };
// Instanciate the DataTable. // Instanciate the DataTable.
this.itemDataTable = new YAHOO.widget.DataTable( this.payoutDetails, this.itemSchema, this.itemDataSource, { this.itemDataTable = new YAHOO.widget.DataTable( this.payoutTable, this.itemSchema, this.itemDataSource, {
dynamicData : true, dynamicData : true,
formatRow : rowFormatter, formatRow : rowFormatter,
paginator : new YAHOO.widget.Paginator({ rowsPerPage:10 } ) //, updateOnChange: true }) paginator : new YAHOO.widget.Paginator({ rowsPerPage:10 } ),
}); MSG_EMPTY : this.i18n( 'vp select vendor' ) //, updateOnChange: true })
} );
this.itemDataTable.handleDataReturnPayload = function(oRequest, oResponse, oPayload) { this.itemDataTable.handleDataReturnPayload = function(oRequest, oResponse, oPayload) {
// For some reason oPayload is undefined when we're switch vendors. This is a hack to // For some reason oPayload is undefined when we're switch vendors. This is a hack to
// still set the paginator correctly. // still set the paginator correctly.
@ -210,29 +255,38 @@ WebGUI.VendorPayout.prototype.initPayoutDetails = function () {
WebGUI.VendorPayout.prototype.initButtons = function () { WebGUI.VendorPayout.prototype.initButtons = function () {
var obj = this; var obj = this;
var updateAll = function ( status ) { var updateAll = function ( status, bulk ) {
// TODO: Make this range based. // TODO: Make this range based.
var records = obj.itemDataTable.getRecordSet().getRecords(); var records = obj.itemDataTable.getRecordSet().getRecords();
var itemIds = new Array;
for (i = 0; i < records.length; i++) { var postdata = 'shop=vendor&method=setPayoutStatus&status=' + status;
itemIds.push( 'itemId=' + records[i].getData( 'itemId' ) );
}
var postdata = itemIds.join('&'); if ( bulk ) {
var url = '?shop=vendor&method=setPayoutStatus&status=' + status; postdata += '&all=1';
}
else {
var itemIds = new Array;
for (i = 0; i < records.length; i++) {
itemIds.push( 'itemId=' + records[i].getData( 'itemId' ) );
}
postdata += '&' + itemIds.join('&');
}
var callback = { var callback = {
success: function (o) { success: function (o) {
this.refreshItemDataTable(); this.refreshItemDataTable();
this.refreshVendorRow(); bulk ? this.refreshVendorDataTable() : this.refreshVendorRow();
}, },
scope: obj scope: obj
}; };
YAHOO.util.Connect.asyncRequest( 'POST', url, callback, postdata ); YAHOO.util.Connect.asyncRequest( 'POST', '/', callback, postdata );
} }
this.scheduleAllButton.on( 'click', function () { updateAll( 'Scheduled' ) } ); this.scheduleAllVendorsButton.on( 'click', function () { updateAll( 'Scheduled', true ) } );
this.descheduleAllButton.on( 'click', function () { updateAll( 'NotPaid' ) } ); this.descheduleAllVendorsButton.on( 'click', function () { updateAll( 'NotPaid', true ) } );
this.scheduleAllPayoutsButton.on( 'click', function () { updateAll( 'Scheduled' ) } );
this.descheduleAllPayoutsButton.on( 'click', function () { updateAll( 'NotPaid' ) } );
} }

View file

@ -63,41 +63,42 @@ YAHOO.WebGUI.Form.DatePicker = {
MDY_YEAR_POSITION: 1, MDY_YEAR_POSITION: 1,
MDY_MONTH_POSITION: 2, MDY_MONTH_POSITION: 2,
MDY_DAY_POSITION: 3, MDY_DAY_POSITION: 3,
START_WEEKDAY: getWebguiProperty('firstDayOfWeek'),
WEEKDAYS_LONG: [ WEEKDAYS_LONG: [
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'sunday'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'monday'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'monday'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'tuesday'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'tuesday'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'wednesday'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'wednesday'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'thursday'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'thursday'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'friday'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'friday'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'saturday'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'saturday')
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'sunday')
], ],
WEEKDAYS_MEDIUM: [ WEEKDAYS_MEDIUM: [
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'sunday med'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'monday med'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'monday med'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'tuesday med'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'tuesday med'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'wednesday med'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'wednesday med'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'thursday med'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'thursday med'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'friday med'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'friday med'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'saturday med'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'saturday med')
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'sunday med')
], ],
WEEKDAYS_SHORT: [ WEEKDAYS_SHORT: [
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'sunday short'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'monday short'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'monday short'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'tuesday short'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'tuesday short'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'wednesday short'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'wednesday short'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'thursday short'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'thursday short'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'friday short'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'friday short'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'saturday short'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'saturday short')
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'sunday short')
], ],
WEEKDAYS_1CHAR: [ WEEKDAYS_1CHAR: [
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'sunday 1char'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'monday 1char'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'monday 1char'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'tuesday 1char'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'tuesday 1char'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'wednesday 1char'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'wednesday 1char'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'thursday 1char'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'thursday 1char'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'friday 1char'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'friday 1char'),
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'saturday 1char'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'saturday 1char')
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'sunday 1char')
], ],
MONTHS_SHORT: [ MONTHS_SHORT: [
YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'january short'), YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'january short'),
@ -133,14 +134,10 @@ YAHOO.WebGUI.Form.DatePicker = {
'cancel' : YAHOO.WebGUI.Form.DatePicker.i18n.get('WebGUI', 'cancel'), 'cancel' : YAHOO.WebGUI.Form.DatePicker.i18n.get('WebGUI', 'cancel'),
'month' : YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'Month'), 'month' : YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'Month'),
'year' : YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'Year'), 'year' : YAHOO.WebGUI.Form.DatePicker.i18n.get('DateTime', 'Year'),
'invalid year' : YAHOO.WebGUI.Form.DatePicker.i18n.get('Form_Date', 'Invalid year'), 'invalid year' : YAHOO.WebGUI.Form.DatePicker.i18n.get('Form_Date', 'Invalid year')
} }
} }
}; };
var firstDayOfWeek = getWebguiProperty('firstDayOfWeek');
if (firstDayOfWeek) {
config.START_WEEKDAY = firstDayOfWeek;
}
this.calendar = new YAHOO.widget.Calendar(null, cal, config); this.calendar = new YAHOO.widget.Calendar(null, cal, config);
this.calendar.selectEvent.subscribe(this.handleSelect, this, true); this.calendar.selectEvent.subscribe(this.handleSelect, this, true);
this.calendar.beforeShowEvent.subscribe(this.handleBeforeShow, this, true); this.calendar.beforeShowEvent.subscribe(this.handleBeforeShow, this, true);