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

This commit is contained in:
daviddelikat 2009-10-14 10:42:41 -05:00
commit fa40b99182
52 changed files with 3081 additions and 3155 deletions

View file

@ -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.");
}
}

View file

@ -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);
}
}

View file

@ -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'),

View file

@ -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);

View file

@ -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 } );

View file

@ -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);

View file

@ -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;
}

View file

@ -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

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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"));
}

View file

@ -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();
}

View file

@ -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 )

View file

@ -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.

View file

@ -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.

View file

@ -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;

View file

@ -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.

View file

@ -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,

View file

@ -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;

View file

@ -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;