Merge commit '4969f31e1f' into WebGUI8
This commit is contained in:
commit
e5b82bc861
61 changed files with 2199 additions and 521 deletions
|
|
@ -1,4 +1,29 @@
|
|||
7.9.5
|
||||
- Asset->www_copy now has a progress bar
|
||||
- fixed #11556: New cart doesn't work with other forms on the same page
|
||||
- fixed #11557: Shop credit deduction calculated incorrectly
|
||||
- fixed #11561: PayDriver_Cash - password help
|
||||
- fixed #11541: running workflows screen
|
||||
- fixed #11544: VersionTag Workflows with missing Version Tags run forever
|
||||
- fixed #11555: Wiki subcategories entry field is not labeled
|
||||
- fixed: UserList asset has SQL injection bug
|
||||
- fixed #11558: wiki results for visitors
|
||||
- fixed #11533: Saving entered data at registration
|
||||
- fixed #11564: Shop: Cart does not require a state field in the address
|
||||
- fixed #11562: Missing perl modules in gotcha
|
||||
- fixed #11565: Can't clear cache on plainblack.com
|
||||
- fixed #11540: Pending version tags are not completed on approval under certain conditions
|
||||
- fixed #11566: Group API: group membership cannot be checked without consideration of expiration dates.
|
||||
- fixed #11567: EMS: Build badge page, ticket tab, pagination
|
||||
- added: a new inbox setting which supresses friend rejection notices
|
||||
- fixed #11552: Visitors (and others) can bypass group-by-IP restrictions
|
||||
- fixed #11572: visitors can enter editProfile
|
||||
- fixed #11563: Syndicated Content - descriptionFirstParagraph cuts off
|
||||
- fixed #11538: User invite mail: whitespace in message lost
|
||||
- fixed #11549: Shortcut Asset cannot override Page Layout
|
||||
- added #11502: Gallery: Allow specification of location when uploading ZIP archives
|
||||
- added #11517: Gallery: Sorting of files uploaded in zip archives
|
||||
- fixed #11559: Unsubscribe Link in Emails
|
||||
|
||||
7.9.4
|
||||
- We're shipping underscore.js now for its suite of extremely handy utility
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -17,6 +17,14 @@ save you many hours of grief.
|
|||
- Moose
|
||||
- CHI
|
||||
|
||||
7.9.5
|
||||
--------------------------------------------------------------------
|
||||
* Starting in WebGUI 7.9.4, the CHI and Cache::FastMmap modules are required.
|
||||
|
||||
* Starting in WebGUI 7.9.5, you cannot enter in a URL that is a has more than 2 dashes,
|
||||
"-", in a row. They will be collapsed down into 1 dash.
|
||||
|
||||
|
||||
7.9.4
|
||||
--------------------------------------------------------------------
|
||||
* Shop and Cart changes
|
||||
|
|
|
|||
BIN
docs/upgrades/packages-7.9.5/root_import_collaboration.wgpkg
Normal file
BIN
docs/upgrades/packages-7.9.5/root_import_collaboration.wgpkg
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -22,6 +22,7 @@ use Getopt::Long;
|
|||
use WebGUI::Session;
|
||||
use WebGUI::Storage;
|
||||
use WebGUI::Asset;
|
||||
use WebGUI::Workflow::Instance;
|
||||
|
||||
|
||||
my $toVersion = '7.9.5';
|
||||
|
|
@ -31,10 +32,14 @@ my $quiet; # this line required
|
|||
my $session = start(); # this line required
|
||||
|
||||
# upgrade functions go here
|
||||
modifySortItems( $session );
|
||||
fixRequestForApprovalScratch($session);
|
||||
addRejectNoticeSetting($session);
|
||||
updateGroupGroupingsTable($session);
|
||||
installNewCSUnsubscribeTemplate($session);
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
#sub exampleFunction {
|
||||
|
|
@ -44,6 +49,85 @@ finish($session); # this line required
|
|||
# print "DONE!\n" unless $quiet;
|
||||
#}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Adds setting which allows users to set whether or not to send reject notices
|
||||
sub addRejectNoticeSetting {
|
||||
my $session = shift;
|
||||
print "\tAdding reject notice setting... " unless $quiet;
|
||||
$session->setting->add('sendRejectNotice',1);
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
sub installNewCSUnsubscribeTemplate {
|
||||
my $session = shift;
|
||||
print "\tAdding new unsubscribe template to the CS... " unless $quiet;
|
||||
$session->db->write(q|ALTER TABLE Collaboration ADD COLUMN unsubscribeTemplateId CHAR(22) NOT NULL|);
|
||||
$session->db->write(q|UPDATE Collaboration set unsubscribeTemplateId='default_CS_unsubscribe'|);
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add keys and indicies to groupGroupings to help speed up group queries
|
||||
sub updateGroupGroupingsTable {
|
||||
my $session = shift;
|
||||
print "\tAdding primary key and indicies to groupGroupings table... " unless $quiet;
|
||||
my $sth = $session->db->read('show create table groupGroupings');
|
||||
my ($field,$stmt) = $sth->array;
|
||||
$sth->finish;
|
||||
unless ($stmt =~ m/PRIMARY KEY/i) {
|
||||
$session->db->write("alter table groupGroupings add primary key (groupId,inGroup)");
|
||||
}
|
||||
unless ($stmt =~ m/KEY `inGroup`/i) {
|
||||
$session->db->write("alter table groupGroupings add index inGroup (inGroup)");
|
||||
}
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
sub fixRequestForApprovalScratch {
|
||||
my $session = shift;
|
||||
print "\tCorrect RequestApprovalForVersionTag workflow instance data with leading commas... " unless $quiet;
|
||||
# and here's our code
|
||||
my $instances = WebGUI::Workflow::Instance->getAllInstances($session);
|
||||
INSTANCE: foreach my $instance (@{ $instances }) {
|
||||
my $messageId = $instance->getScratch('messageId');
|
||||
next INSTANCE unless $messageId;
|
||||
$messageId =~ s/^,//;
|
||||
$instance->setScratch('messageId', $messageId);
|
||||
}
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Changes sortItems to a SelectBox
|
||||
sub modifySortItems {
|
||||
my $session = shift;
|
||||
print "\tUpdating SyndicatedContent...\n" unless $quiet;
|
||||
|
||||
require WebGUI::Form::SelectBox;
|
||||
|
||||
print "\t\tModifying table...\n" unless $quiet;
|
||||
my $type = WebGUI::Form::SelectBox->getDatabaseFieldType;
|
||||
$session->db->write("ALTER TABLE SyndicatedContent MODIFY sortItems $type");
|
||||
|
||||
print "\t\tConverting old values..." unless $quiet;
|
||||
$session->db->write(q{
|
||||
UPDATE SyndicatedContent
|
||||
SET sortItems = 'none'
|
||||
WHERE sortItems <> '1'
|
||||
});
|
||||
$session->db->write(q{
|
||||
UPDATE SyndicatedContent
|
||||
SET sortItems = 'pubDate_des'
|
||||
WHERE sortItems = '1'
|
||||
});
|
||||
|
||||
# and here's our code
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -294,7 +294,8 @@ sub getJsonStatus {
|
|||
my %output;
|
||||
if ($sitename) { #must have entry for each queue
|
||||
%output = %queues;
|
||||
foreach my $instance ($self->getInstances) {
|
||||
INSTANCE: foreach my $instance ($self->getInstances) {
|
||||
next INSTANCE unless $instance->{sitename} eq $sitename;
|
||||
my $queue = ucfirst($instance->{status});
|
||||
push @{$output{$queue}}, [$instance->{workingPriority}, $instance->{instanceId}, $instance];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -238,6 +238,12 @@ sub editSettingsForm {
|
|||
hoverHelp => $i18n->get('send inbox notifications only help'),
|
||||
defaultValue => $setting->get('sendInboxNotificationsOnly'),
|
||||
);
|
||||
$f->yesNo(
|
||||
name => 'sendRejectNotice',
|
||||
label => $i18n->get('send reject notice'),
|
||||
hoverHelp => $i18n->get('send reject notice help'),
|
||||
defaultValue => $setting->get('sendRejectNotice'),
|
||||
);
|
||||
$f->text(
|
||||
name => 'inboxNotificationsSubject',
|
||||
label => $i18n->get('inbox notifications subject'),
|
||||
|
|
@ -306,6 +312,7 @@ sub editSettingsFormSave {
|
|||
$setting->set("inboxNotificationsSubject", $form->process("inboxNotificationsSubject", "text"));
|
||||
$setting->set("inboxNotificationTemplateId", $form->process("inboxNotificationTemplateId","template"));
|
||||
$setting->set("inboxSmsNotificationTemplateId", $form->process("inboxSmsNotificationTemplateId","template"));
|
||||
$setting->set("sendRejectNotice", $form->process("sendRejectNotice","yesNo"));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -605,7 +612,7 @@ sub www_approveDenyInvitations {
|
|||
next unless ($invite->{inviterId}); #Not sure how this could ever happen, but check for it
|
||||
next unless ($session->user->userId eq $invite->{friendId}); #Protect against malicious stuff
|
||||
if($deny) {
|
||||
$friends->rejectAddRequest($inviteId);
|
||||
$friends->rejectAddRequest($inviteId,$session->setting->get("sendRejectNotice"));
|
||||
}
|
||||
elsif($approve) {
|
||||
$friends->approveAddRequest($inviteId);
|
||||
|
|
@ -954,7 +961,7 @@ sub www_inviteUserSave {
|
|||
);
|
||||
|
||||
## No sneaky attack paths...
|
||||
$var->{'message'} = WebGUI::HTML::html2text( WebGUI::HTML::filter($message) );
|
||||
$var->{'message'} = WebGUI::HTML::format(WebGUI::HTML::filter($message));
|
||||
|
||||
my $emailBody = $self->processTemplate( $var, $self->getInviteUserMessageTemplateId );
|
||||
|
||||
|
|
|
|||
|
|
@ -996,18 +996,22 @@ sub unstick {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 unsubscribe ( )
|
||||
=head2 unsubscribe ( [$user] )
|
||||
|
||||
Negates the subscribe method.
|
||||
Unsubscribes a user from this thread.
|
||||
|
||||
=head3 $user
|
||||
|
||||
An optional user object to unsubscribe. If the object isn't passed, then it uses the session user.
|
||||
|
||||
=cut
|
||||
|
||||
sub unsubscribe {
|
||||
my $self = shift;
|
||||
my $self = shift;
|
||||
my $user = shift || $self->session->user;
|
||||
my $group = WebGUI::Group->new($self->session,$self->subscriptionGroupId);
|
||||
return
|
||||
if !$group;
|
||||
$group->deleteUsers([$self->session->user->userId]);
|
||||
return if !$group;
|
||||
$group->deleteUsers([$user->userId]);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1355,16 +1359,60 @@ sub www_unstick {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_unsubscribe ( )
|
||||
=head2 www_unsubscribe ( [$message] )
|
||||
|
||||
The web method to unsubscribe from a thread.
|
||||
|
||||
=head3 $message
|
||||
|
||||
An error message to display to the user.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_unsubscribe {
|
||||
my $self = shift;
|
||||
$self->unsubscribe if $self->canSubscribe;
|
||||
return $self->www_view;
|
||||
my $self = shift;
|
||||
my $message = shift;
|
||||
if($self->canSubscribe){
|
||||
$self->unsubscribe;
|
||||
return $self->www_view;
|
||||
}
|
||||
else {
|
||||
my $session = $self->session;
|
||||
my $i18n = WebGUI::International->new($session, 'Asset_Collaboration');
|
||||
my $var = $self->get();
|
||||
$var->{title} = $self->getTitle;
|
||||
$var->{url} = $self->getUrl;
|
||||
$var->{formHeader} = WebGUI::Form::formHeader($session)
|
||||
. WebGUI::Form::hidden($session, { name => 'func', value => 'unsubscribeConfirm', }, ),
|
||||
$var->{formFooter} = WebGUI::Form::formFooter($session),
|
||||
$var->{formSubmit} = WebGUI::Form::submit($session, { value => $i18n->get('unsubscribe'), }),
|
||||
$var->{formEmail} = WebGUI::Form::email($session, { name => 'userEmail', value => $session->form->process('userEmail'), }),
|
||||
$var->{formMessage} = $message;
|
||||
return $self->getParent->processStyle($self->processTemplate($var, $self->getParent->get("unsubscribeTemplateId")));
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_unsubscribeConfirm ( )
|
||||
|
||||
Process the unsubscribe form.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_unsubscribeConfirm {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
return $self->www_view unless $session->form->validToken;
|
||||
my $email = $session->form->process('userEmail', 'email');
|
||||
return $self->www_view unless $email;
|
||||
my $user = WebGUI::User->newByEmail($session, $email);
|
||||
my $i18n = WebGUI::International->new($session, 'Asset_Collaboration');
|
||||
if (! $user) {
|
||||
return $self->www_unsubscribe($i18n->get('no user email error message'));
|
||||
}
|
||||
$self->unsubscribe($user);
|
||||
return $self->www_unsubscribe($i18n->get('You have been unsubscribed'));
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -904,9 +904,13 @@ sub view {
|
|||
}
|
||||
}
|
||||
|
||||
if ($self->get("shortcutToAssetId") eq $self->get("parentId")) {
|
||||
$content = $i18n->get("Displaying this shortcut would cause a feedback loop");
|
||||
} else {
|
||||
if ($self->get("shortcutToAssetId") eq $self->get("parentId")) {
|
||||
$content = $i18n->get("Displaying this shortcut would cause a feedback loop");
|
||||
}
|
||||
elsif (! $shortcut->canView) {
|
||||
$content = '';
|
||||
}
|
||||
else {
|
||||
# Make sure the www_view method won't be skipped b/c the asset is cached.
|
||||
$shortcut->purgeCache();
|
||||
|
||||
|
|
@ -1214,10 +1218,12 @@ Render the shortcut in standalone mode.
|
|||
=cut
|
||||
|
||||
sub www_view {
|
||||
my $self = shift;
|
||||
my $check = $self->checkView;
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $check = $self->checkView;
|
||||
return $check if defined $check;
|
||||
my $shortcut = $self->getShortcut;
|
||||
return $session->privilege->noAccess() unless $shortcut->canView;
|
||||
$self->prepareView;
|
||||
|
||||
# Make sure the www_view method won't be skipped b/c the asset is cached.
|
||||
|
|
|
|||
|
|
@ -452,6 +452,14 @@ property postReceivedTemplateId => (
|
|||
hoverHelp => [ 'post received template hoverHelp', 'Asset_Collaboration' ],
|
||||
default => 'default_post_received1',
|
||||
);
|
||||
property unsubscribeTemplateId => (
|
||||
fieldType => 'template',
|
||||
namespace => 'Collaboration/Unsubscribe',
|
||||
tab => 'display',
|
||||
label => [ 'unsubscribe template', 'Asset_Collaboration' ],
|
||||
hoverHelp => [ 'unsubscribe template hoverHelp', 'Asset_Collaboration' ],
|
||||
default => 'default_CS_unsubscribe',
|
||||
);
|
||||
|
||||
with 'WebGUI::Role::Asset::RssFeed';
|
||||
|
||||
|
|
@ -1557,18 +1565,22 @@ sub subscribe {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 unsubscribe ( )
|
||||
=head2 unsubscribe ( [$user] )
|
||||
|
||||
Unsubscribes a user from this collaboration system
|
||||
|
||||
=head3 $user
|
||||
|
||||
An optional user object to unsubscribe. If the object isn't passed, then it uses the session user.
|
||||
|
||||
=cut
|
||||
|
||||
sub unsubscribe {
|
||||
my $self = shift;
|
||||
my $self = shift;
|
||||
my $user = shift || $self->session->user;
|
||||
my $group = WebGUI::Group->new($self->session,$self->subscriptionGroupId);
|
||||
return
|
||||
unless $group;
|
||||
$group->deleteUsers([$self->session->user->userId],[$self->subscriptionGroupId]);
|
||||
return unless $group;
|
||||
$group->deleteUsers([$user->userId]);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1706,24 +1718,64 @@ sub www_unarchiveAll {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_unsubscribe ( )
|
||||
=head2 www_unsubscribe ( [$message] )
|
||||
|
||||
The web method to unsubscribe from a collaboration.
|
||||
|
||||
=head3 $message
|
||||
|
||||
An error message to display to the user.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_unsubscribe {
|
||||
my $self = shift;
|
||||
my $self = shift;
|
||||
my $message = shift;
|
||||
if($self->canSubscribe){
|
||||
$self->unsubscribe;
|
||||
return $self->www_view;
|
||||
}else{
|
||||
return $self->session->privilege->noAccess;
|
||||
}
|
||||
else {
|
||||
my $session = $self->session;
|
||||
my $i18n = WebGUI::International->new($session, 'Asset_Collaboration');
|
||||
my $var = $self->get();
|
||||
$var->{title} = $self->getTitle;
|
||||
$var->{url} = $self->getUrl;
|
||||
$var->{formHeader} = WebGUI::Form::formHeader($session)
|
||||
. WebGUI::Form::hidden($session, { name => 'func', value => 'unsubscribeConfirm', }, ),
|
||||
$var->{formFooter} = WebGUI::Form::formFooter($session),
|
||||
$var->{formSubmit} = WebGUI::Form::submit($session, { value => $i18n->get('unsubscribe'), }),
|
||||
$var->{formEmail} = WebGUI::Form::email($session, { name => 'userEmail', value => $session->form->process('userEmail'), }),
|
||||
$var->{formMessage} = $message;
|
||||
return $self->processStyle($self->processTemplate($var, $self->get("unsubscribeTemplateId")));
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_unsubscribeConfirm ( )
|
||||
|
||||
Process the unsubscribe form.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_unsubscribeConfirm {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
return $self->www_view unless $session->form->validToken;
|
||||
my $email = $session->form->process('userEmail', 'email');
|
||||
return $self->www_view unless $email;
|
||||
my $user = WebGUI::User->newByEmail($session, $email);
|
||||
my $i18n = WebGUI::International->new($session, 'Asset_Collaboration');
|
||||
if (! $user) {
|
||||
return $self->www_unsubscribe($i18n->get('no user email error message'));
|
||||
}
|
||||
$self->unsubscribe($user);
|
||||
return $self->www_unsubscribe($i18n->get('You have been unsubscribed'));
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 www_view
|
||||
|
||||
Extend the base method to handle the visitor cache timeout.
|
||||
|
|
|
|||
|
|
@ -1896,7 +1896,7 @@ className='WebGUI::Asset::Sku::EMSTicket' and state='published' and revisionDate
|
|||
|
||||
# gotta get to the page we're working with
|
||||
$counter++;
|
||||
next unless ($counter >= ($startIndex * $numberOfResults));
|
||||
next unless ($counter >= $startIndex+1);
|
||||
|
||||
# publish the data for this ticket
|
||||
my $description = $ticket->description;
|
||||
|
|
|
|||
|
|
@ -43,16 +43,22 @@ for my $i ( 1 .. 5 ) {
|
|||
with 'WebGUI::Role::Asset::AlwaysHidden';
|
||||
with 'WebGUI::Role::Asset::RssFeed';
|
||||
|
||||
use strict;
|
||||
use Carp qw( croak );
|
||||
use File::Find;
|
||||
use File::Spec;
|
||||
use File::Temp qw{ tempdir };
|
||||
use JSON qw();
|
||||
use Image::ExifTool qw( :Public );
|
||||
use JSON;
|
||||
use Tie::IxHash;
|
||||
|
||||
use WebGUI::International;
|
||||
use WebGUI::HTML;
|
||||
use WebGUI::ProgressBar;
|
||||
use WebGUI::Storage;
|
||||
|
||||
# Do not move this instruction!
|
||||
use Archive::Any;
|
||||
|
||||
=head1 NAME
|
||||
|
|
@ -88,6 +94,12 @@ The name of the file archive to import.
|
|||
|
||||
A base set of properties to add to each file in the archive.
|
||||
|
||||
=head3 sortBy
|
||||
|
||||
Order in which files should be added to the gallery album. Legal values are
|
||||
'name', 'date' and 'fileOrder'. If missing or invalid, files will be added as
|
||||
ordered in the archive (default; corresponding to 'fileOrder').
|
||||
|
||||
=head3 $outputSub
|
||||
|
||||
A callback to use for outputting data, most likely to a progress bar. It expects the
|
||||
|
|
@ -100,6 +112,7 @@ sub addArchive {
|
|||
my $self = shift;
|
||||
my $filename = shift;
|
||||
my $properties = shift;
|
||||
my $sortBy = shift;
|
||||
my $outputSub = shift || sub {};
|
||||
my $gallery = $self->getParent;
|
||||
my $session = $self->session;
|
||||
|
|
@ -119,6 +132,33 @@ sub addArchive {
|
|||
find( {
|
||||
wanted => $wanted,
|
||||
}, $tempdirName );
|
||||
|
||||
# Sort files by date
|
||||
if ($sortBy eq 'date') {
|
||||
# Hash for storing last modified timestamps
|
||||
my %mtimes;
|
||||
|
||||
my $exifTool = Image::ExifTool->new;
|
||||
# Make ExifTool return epoch timestamps
|
||||
$exifTool->Options('DateFormat', '%s');
|
||||
|
||||
# Iterate through all files
|
||||
foreach my $file (@files) {
|
||||
# Extract exif data from image
|
||||
$exifTool->ExtractInfo( $file );
|
||||
# Get last modified timestamp from exif data
|
||||
$mtimes{$file} = $exifTool->GetValue('ModifyDate');
|
||||
# Use last modified date of file as fallback
|
||||
$mtimes{$file} = (stat($file))[9] unless $mtimes{$file};
|
||||
}
|
||||
|
||||
# Sort files based on last modified timestamps
|
||||
@files = sort { $mtimes{$a} <=> $mtimes{$b} } @files;
|
||||
}
|
||||
# Sort files by name
|
||||
elsif ($sortBy eq 'name') {
|
||||
@files = sort @files;
|
||||
}
|
||||
|
||||
for my $filePath (@files) {
|
||||
my ($volume, $directory, $filename) = File::Spec->splitpath( $filePath );
|
||||
|
|
@ -955,12 +995,29 @@ sub www_addArchive {
|
|||
name => "keywords",
|
||||
value => ( $form->get("keywords") ),
|
||||
});
|
||||
|
||||
$var->{ form_location }
|
||||
= WebGUI::Form::Text( $session, {
|
||||
name => "location",
|
||||
value => ( $form->get("location") ),
|
||||
});
|
||||
|
||||
$var->{ form_friendsOnly }
|
||||
= WebGUI::Form::yesNo( $session, {
|
||||
name => "friendsOnly",
|
||||
value => ( $form->get("friendsOnly") ),
|
||||
});
|
||||
|
||||
$var->{ form_sortBy }
|
||||
= WebGUI::Form::RadioList( $session, {
|
||||
name => "sortBy",
|
||||
value => [ "name" ],
|
||||
options => {
|
||||
name => $i18n->get("addArchive sortBy name", 'Asset_GalleryAlbum'),
|
||||
date => $i18n->get("addArchive sortBy date", 'Asset_GalleryAlbum'),
|
||||
fileOrder => $i18n->get("addArchive sortBy fileOrder", 'Asset_GalleryAlbum'),
|
||||
},
|
||||
});
|
||||
|
||||
return $self->processStyle(
|
||||
$self->processTemplate($var, $self->getParent->templateIdAddArchive)
|
||||
|
|
@ -978,26 +1035,39 @@ Process the form for adding an archive.
|
|||
sub www_addArchiveSave {
|
||||
my $self = shift;
|
||||
|
||||
# Return error message if the user viewing does not have permission to add files
|
||||
return $self->session->privilege->insufficient unless $self->canAddFile;
|
||||
|
||||
my $session = $self->session;
|
||||
my $form = $self->session->form;
|
||||
my $i18n = WebGUI::International->new( $session, 'Asset_GalleryAlbum' );
|
||||
my $pb = WebGUI::ProgressBar->new($session);
|
||||
|
||||
# Retrieve properties and sort order from form variables
|
||||
my $properties = {
|
||||
keywords => $form->get("keywords"),
|
||||
location => $form->get("location"),
|
||||
friendsOnly => $form->get("friendsOnly"),
|
||||
};
|
||||
my $sortBy = $form->get("sortBy");
|
||||
|
||||
# Create progress bar to keep the connection alive
|
||||
$pb->start($i18n->get('Uploading archive'), $session->url->extras('adminConsole/assets.gif'));
|
||||
|
||||
# Retrieve storage containing the uploaded archive
|
||||
my $storageId = $form->get("archive", "File");
|
||||
my $storage = WebGUI::Storage->get( $session, $storageId );
|
||||
if (!$storage) {
|
||||
return $pb->finish($self->getUrl('func=addArchive;error='.$i18n->get('addArchive error too big')));
|
||||
}
|
||||
my $filename = $storage->getPath( $storage->getFiles->[0] );
|
||||
|
||||
eval { $self->addArchive( $filename, $properties, sub{ $pb->update(sprintf $i18n->get(shift), @_); }); };
|
||||
# Get the full path to the archive
|
||||
my $filename = $storage->getPath( $storage->getFiles->[0] );
|
||||
|
||||
# Try to add files in archive as photos
|
||||
eval { $self->addArchive( $filename, $properties, $sortBy, sub{ $pb->update(sprintf $i18n->get(shift), @_); }); };
|
||||
|
||||
# Delete storage containing archive
|
||||
$storage->delete;
|
||||
if ( my $error = $@ ) {
|
||||
return $pb->finish($self->getUrl('func=addArchive;error='.sprintf $i18n->get('addArchive error generic'), $error ));
|
||||
|
|
|
|||
|
|
@ -71,11 +71,23 @@ property hasTerms => (
|
|||
);
|
||||
property sortItems => (
|
||||
tab => 'properties',
|
||||
fieldType => 'yesNo',
|
||||
default => 1,
|
||||
fieldType => 'selectBox',
|
||||
default => 'none',
|
||||
label => ['sortItemsLabel', 'Asset_SyndicatedContent'],
|
||||
hoverHelp => ['sortItemsLabel description', 'Asset_SyndicatedContent'],
|
||||
options => \&_sortItems_options,
|
||||
);
|
||||
sub _sortItems_options {
|
||||
my $session = shift->session;
|
||||
my $i18n = WebGUI::International->new($session,'Asset_SyndicatedContent');
|
||||
tie my %o, 'Tie::IxHash', (
|
||||
none => $i18n->get('no order'),
|
||||
feed => $i18n->get('feed order'),
|
||||
pubDate_asc => $i18n->get('publication date ascending'),
|
||||
pubDate_des => $i18n->get('publication date descending'),
|
||||
);
|
||||
return \%o;
|
||||
}
|
||||
has '+uiLevel' => (
|
||||
default => 6,
|
||||
);
|
||||
|
|
@ -114,11 +126,15 @@ Combines all feeds into a single XML::FeedPP object.
|
|||
=cut
|
||||
|
||||
sub generateFeed {
|
||||
my $self = shift;
|
||||
my $limit = shift || $self->maxHeadlines;
|
||||
my $self = shift;
|
||||
my $limit = shift || $self->maxHeadlines;
|
||||
my $session = $self->session;
|
||||
my ( $log, $cache ) = $session->quick(qw( log cache ));
|
||||
my $feed = XML::FeedPP::Atom->new();
|
||||
my $log = $session->log;
|
||||
my $cache = $session->cache;
|
||||
my $sort = $self->sortItems;
|
||||
|
||||
my %opt = (use_ixhash => 1) if $sort eq 'feed';
|
||||
my $feed = XML::FeedPP::Atom->new(%opt);
|
||||
|
||||
# build one feed out of many
|
||||
my $newlyCached = 0;
|
||||
|
|
@ -151,7 +167,7 @@ sub generateFeed {
|
|||
# care of any encoding specified in the XML prolog
|
||||
utf8::downgrade($value, 1);
|
||||
eval {
|
||||
my $singleFeed = XML::FeedPP->new($value, utf8_flag => 1, -type => 'string');
|
||||
my $singleFeed = XML::FeedPP->new($value, utf8_flag => 1, -type => 'string', %opt);
|
||||
$feed->merge_channel($singleFeed);
|
||||
$feed->merge_item($singleFeed);
|
||||
};
|
||||
|
|
@ -183,9 +199,14 @@ sub generateFeed {
|
|||
}
|
||||
|
||||
# sort them by date and remove any duplicate from the OR based term matching above
|
||||
if ($self->sortItems) {
|
||||
if ($sort =~ /^pubDate/) {
|
||||
$feed->sort_item();
|
||||
}
|
||||
if ($sort =~ /_asc$/) {
|
||||
my @items = $feed->get_item;
|
||||
$feed->clear_item;
|
||||
$feed->add_item($_) for (reverse @items);
|
||||
}
|
||||
|
||||
# limit the feed to the maximum number of headlines (or the feed generator limit).
|
||||
$feed->limit_item($limit);
|
||||
|
|
@ -270,10 +291,19 @@ sub getTemplateVariables {
|
|||
$item{descriptionFirst25words} =~ s/(((\S+)\s+){25}).*/$1/s;
|
||||
$item{descriptionFirst10words} = $item{descriptionFirst25words};
|
||||
$item{descriptionFirst10words} =~ s/(((\S+)\s+){10}).*/$1/s;
|
||||
$item{descriptionFirst2paragraphs} = $item{description};
|
||||
$item{descriptionFirst2paragraphs} =~ s/^((.*?\n){2}).*/$1/s;
|
||||
$item{descriptionFirstParagraph} = $item{descriptionFirst2paragraphs};
|
||||
$item{descriptionFirstParagraph} =~ s/^(.*?\n).*/$1/s;
|
||||
if ($description =~ /<p>/) {
|
||||
my $html = $description;
|
||||
$html =~ tr/\n/ /s;
|
||||
my @paragraphs = map { "<p>".$_."</p>" } WebGUI::HTML::splitTag($html,3);
|
||||
$item{descriptionFirstParagraph} = $paragraphs[0];
|
||||
$item{descriptionFirst2paragraphs} = join '', @paragraphs[0..1];
|
||||
}
|
||||
else {
|
||||
$item{descriptionFirst2paragraphs} = $item{description};
|
||||
$item{descriptionFirst2paragraphs} =~ s/^((.*?\n){2}).*/$1/s;
|
||||
$item{descriptionFirstParagraph} = $item{descriptionFirst2paragraphs};
|
||||
$item{descriptionFirstParagraph} =~ s/^(.*?\n).*/$1/s;
|
||||
}
|
||||
$item{descriptionFirst4sentences} = $item{description};
|
||||
$item{descriptionFirst4sentences} =~ s/^((.*?\.){4}).*/$1/s;
|
||||
$item{descriptionFirst3sentences} = $item{descriptionFirst4sentences};
|
||||
|
|
|
|||
|
|
@ -502,6 +502,7 @@ sub view {
|
|||
if(isIn($sortBy,@sortByUserProperties)){
|
||||
$sortBy = 'users.'.$sortBy;
|
||||
}
|
||||
$sortBy = join '.', map { $self->session->db->quoteIdentifier($_) } split /\./, $sortBy;
|
||||
$sql .= " order by ".$sortBy." ".$sortOrder;
|
||||
|
||||
($defaultPublicProfile) = $self->session->db->quickArray("SELECT dataDefault FROM userProfileField WHERE fieldName='publicProfile'");
|
||||
|
|
|
|||
|
|
@ -972,19 +972,13 @@ sub www_search {
|
|||
wikiHomeUrl=>$self->getUrl,
|
||||
addPageUrl=>$self->getUrl("func=add;class=WebGUI::Asset::WikiPage;title=".$queryString),
|
||||
};
|
||||
if (defined $queryString) {
|
||||
$self->session->scratch->set('wikiSearchQueryString', $queryString);
|
||||
}
|
||||
else {
|
||||
$queryString = $self->session->scratch->get('wikiSearchQueryString');
|
||||
}
|
||||
$self->appendSearchBoxVars($var, $queryString);
|
||||
if (length $queryString) {
|
||||
my $search = WebGUI::Search->new($self->session);
|
||||
$search->search({ keywords => $queryString,
|
||||
lineage => [$self->lineage],
|
||||
classes => ['WebGUI::Asset::WikiPage'] });
|
||||
my $rs = $search->getPaginatorResultSet($self->getUrl("func=search"));
|
||||
my $rs = $search->getPaginatorResultSet($self->getUrl("func=search;query=".$queryString));
|
||||
$rs->appendTemplateVars($var);
|
||||
my @results = ();
|
||||
foreach my $row (@{$rs->getPageData}) {
|
||||
|
|
|
|||
|
|
@ -232,36 +232,98 @@ sub paste {
|
|||
|
||||
=head2 www_copy ( )
|
||||
|
||||
Duplicates self, cuts duplicate, returns self->getContainer->www_view if canEdit. Otherwise returns an AdminConsole rendered as insufficient privilege.
|
||||
Duplicates self, cuts duplicate, returns self->getContainer->www_view if
|
||||
canEdit. Otherwise returns an AdminConsole rendered as insufficient privilege.
|
||||
If with children/descendants is selected, a progress bar will be rendered.
|
||||
|
||||
=cut
|
||||
|
||||
sub www_copy {
|
||||
my $self = shift;
|
||||
return $self->session->privilege->insufficient
|
||||
unless $self->canEdit;
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
return $session->privilege->insufficient unless $self->canEdit;
|
||||
|
||||
|
||||
# with: 'children' || 'descendants' || ''
|
||||
my $with = $self->session->form->get('with') || '';
|
||||
my $newAsset;
|
||||
if ($with) {
|
||||
my $childrenOnly = $with eq 'children';
|
||||
$newAsset = $self->duplicateBranch($childrenOnly);
|
||||
my $with = $session->form->get('with');
|
||||
if ($with eq 'children') {
|
||||
$self->_wwwCopyChildren;
|
||||
}
|
||||
elsif ($with eq 'descendants') {
|
||||
$self->_wwwCopyDescendants;
|
||||
}
|
||||
else {
|
||||
$newAsset = $self->duplicate({skipAutoCommitWorkflows => 1});
|
||||
$self->_wwwCopySingle;
|
||||
}
|
||||
my $i18n = WebGUI::International->new($self->session, 'Asset');
|
||||
$newAsset->update({ title=>sprintf("%s (%s)",$self->getTitle,$i18n->get('copy'))});
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
sub _wwwCopyChildren { shift->_wwwCopyProgress(1) }
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
sub _wwwCopyDescendants { shift->_wwwCopyProgress(0) }
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
sub _wwwCopyFinish {
|
||||
my ($self, $newAsset) = @_;
|
||||
my $session = $self->session;
|
||||
my $i18n = WebGUI::International->new($session, 'Asset');
|
||||
my $title = sprintf("%s (%s)", $self->getTitle, $i18n->get('copy'));
|
||||
$newAsset->update({ title => $title });
|
||||
$newAsset->cut;
|
||||
if (WebGUI::VersionTag->autoCommitWorkingIfEnabled($self->session, {
|
||||
allowComments => 1,
|
||||
returnUrl => $self->getUrl,
|
||||
}) eq 'redirect') {
|
||||
return undef;
|
||||
};
|
||||
return $self->session->asset($self->getContainer)->www_view;
|
||||
my $result = WebGUI::VersionTag->autoCommitWorkingIfEnabled(
|
||||
$session, {
|
||||
allowComments => 1,
|
||||
returnUrl => $self->getUrl,
|
||||
}
|
||||
);
|
||||
my $redirect = $result eq 'redirect';
|
||||
$session->asset($self->getContainer) unless $redirect;
|
||||
return $redirect;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
sub _wwwCopyProgress {
|
||||
my ($self, $childrenOnly) = @_;
|
||||
my $session = $self->session;
|
||||
my $i18n = WebGUI::International->new($session, 'Asset');
|
||||
|
||||
# This could potentially time out, so we'll render a progress bar.
|
||||
my $pb = WebGUI::ProgressBar->new($session);
|
||||
my @stack;
|
||||
|
||||
return $pb->run(
|
||||
title => $i18n->get('Copy Assets'),
|
||||
icon => $session->url->extras('adminConsole/assets.gif'),
|
||||
code => sub {
|
||||
my $bar = shift;
|
||||
my $newAsset = $self->duplicateBranch($childrenOnly);
|
||||
$bar->update($i18n->get('cut'));
|
||||
my $redirect = $self->_wwwCopyFinish($newAsset);
|
||||
return $redirect ? $self->getUrl : $self->getContainer->getUrl;
|
||||
},
|
||||
wrap => {
|
||||
'WebGUI::Asset::duplicateBranch' => sub {
|
||||
my ($bar, $original, $asset, @args) = @_;
|
||||
push(@stack, $asset->getTitle);
|
||||
my $ret = $asset->$original(@args);
|
||||
pop(@stack);
|
||||
return $ret;
|
||||
},
|
||||
'WebGUI::Asset::duplicate' => sub {
|
||||
my ($bar, $original, $asset, @args) = @_;
|
||||
my $name = join '/', @stack, $asset->getTitle;
|
||||
$bar->update($name);
|
||||
return $asset->$original(@args);
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
sub _wwwCopySingle {
|
||||
my $self = shift;
|
||||
my $newAsset = $self->duplicate({skipAutoCommitWorkflows => 1});
|
||||
my $redirect = $self->_wwwCopyFinish($newAsset);
|
||||
return $redirect ? undef : $self->getContainer->www_view;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ sub createAccount {
|
|||
$formField = $field->formField($properties, undef, undef, undef, $defaultValue);
|
||||
}
|
||||
else {
|
||||
$formField = $field->formField($properties, undef, undef, undef, undef, undef, 'useFormDefault');
|
||||
$formField = $field->formField($properties);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,151 +0,0 @@
|
|||
package WebGUI::Cache::CHI;
|
||||
|
||||
use strict;
|
||||
use base 'WebGUI::Cache';
|
||||
use File::Temp qw/tempdir/;
|
||||
use CHI;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
WebGUI::Cache::CHI - CHI cache driver
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is a WebGUI Cache driver to the CHI cache interface. This allows WebGUI
|
||||
sites to use any CHI::Driver like FastMmap and Memcached
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=cut
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 delete ( )
|
||||
|
||||
Delete the current key
|
||||
|
||||
=cut
|
||||
|
||||
sub delete {
|
||||
my ( $self ) = @_;
|
||||
return $self->{_chi}->remove( $self->{_key} );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 deleteChunk ( partialKey )
|
||||
|
||||
Delete multiple keys from the cache
|
||||
|
||||
=cut
|
||||
|
||||
sub deleteChunk {
|
||||
my ( $self, $key ) = @_;
|
||||
$key = $self->parseKey( $key );
|
||||
for my $checkKey ( $self->{_chi}->get_keys ) {
|
||||
if ( $checkKey =~ /^\Q$key/ ) {
|
||||
$self->{_chi}->remove( $checkKey );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 flush ( )
|
||||
|
||||
Delete the entire cache namespace
|
||||
|
||||
=cut
|
||||
|
||||
sub flush {
|
||||
my ( $self ) = @_;
|
||||
$self->{_chi}->purge;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 get ( )
|
||||
|
||||
Get the data in the current key
|
||||
|
||||
=cut
|
||||
|
||||
sub get {
|
||||
my ( $self ) = @_;
|
||||
return $self->{_chi}->get( $self->{_key} );
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 new ( session, key [, namespace] )
|
||||
|
||||
Create a new WebGUI::Cache object with the given key. The namespace defaults
|
||||
to the current site's configuration file name
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my ( $class, $session, $key, $namespace ) = @_;
|
||||
$namespace ||= $session->config->getFilename;
|
||||
$key = $class->parseKey( $key );
|
||||
|
||||
# Create CHI object from config
|
||||
my $chi;
|
||||
unless ( $chi = $session->stow->get( "CHI" ) ) {
|
||||
my $cacheConf = $session->config->get('cache');
|
||||
$cacheConf->{namespace} = $namespace;
|
||||
|
||||
# Default values
|
||||
my $resolveConf = sub {
|
||||
my ($config) = @_;
|
||||
if ( $config->{driver} =~ /DBI/ ) {
|
||||
$config->{ dbh } = $session->db->dbh;
|
||||
}
|
||||
if ( $config->{driver} =~ /File|FastMmap|BerkeleyDB/ ) {
|
||||
$config->{ root_dir } ||= tempdir();
|
||||
}
|
||||
};
|
||||
|
||||
$resolveConf->( $cacheConf );
|
||||
if ( $cacheConf->{l1_cache} ) {
|
||||
$resolveConf->( $cacheConf->{l1_cache} );
|
||||
}
|
||||
|
||||
$chi = CHI->new( %{$cacheConf} );
|
||||
$session->stow->set( "CHI", $chi );
|
||||
}
|
||||
|
||||
return bless { _session => $session, _key => $key, _chi => $chi }, $class;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 set ( content [, ttl ] )
|
||||
|
||||
Set the content to the current key. ttl is the number of seconds the cache
|
||||
should live.
|
||||
|
||||
=cut
|
||||
|
||||
sub set {
|
||||
my ( $self, $content, $ttl ) = @_;
|
||||
$ttl ||= 60;
|
||||
$self->{_chi}->set( $self->{_key}, $content, $ttl );
|
||||
return;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 stats ( )
|
||||
|
||||
Get the size of the cache
|
||||
|
||||
=cut
|
||||
|
||||
sub stats {
|
||||
my ( $self ) = @_;
|
||||
return $self->{_chi}->get_size;
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
|
@ -288,7 +288,7 @@ sub new {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 rejectAddRequest ( inviteId )
|
||||
=head2 rejectAddRequest ( inviteId[,sendNotification] )
|
||||
|
||||
Sends a rejection notice, and deletes the invitation.
|
||||
|
||||
|
|
@ -296,21 +296,30 @@ Sends a rejection notice, and deletes the invitation.
|
|||
|
||||
The id of an invitation.
|
||||
|
||||
=head3 sendNotification
|
||||
|
||||
Boolean indicating whether or not to send out the deny notification. Defaults to true
|
||||
|
||||
=cut
|
||||
|
||||
sub rejectAddRequest {
|
||||
my $self = shift;
|
||||
my $self = shift;
|
||||
my $inviteId = shift;
|
||||
my $notify = shift;
|
||||
|
||||
my $db = $self->session->db;
|
||||
my $invite = $self->getAddRequest($inviteId);
|
||||
my $i18n = WebGUI::International->new($self->session, "Friends");
|
||||
my $inbox = WebGUI::Inbox->new($self->session);
|
||||
$inbox->addMessage({
|
||||
message => sprintf($i18n->get("friends invitation not accepted by user"), $self->user->getWholeName),
|
||||
subject => $i18n->get('friends invitation not accepted'),
|
||||
userId => $invite->{inviterId},
|
||||
status => 'unread',
|
||||
});
|
||||
|
||||
unless (defined $notify && !$notify) { #Notify is defined but not true
|
||||
$inbox->addMessage({
|
||||
message => sprintf($i18n->get("friends invitation not accepted by user"), $self->user->getWholeName),
|
||||
subject => $i18n->get('friends invitation not accepted'),
|
||||
userId => $invite->{inviterId},
|
||||
status => 'unread',
|
||||
});
|
||||
}
|
||||
$inbox->getMessage($invite->{messageId})->setStatus('completed');
|
||||
$self->session->db->deleteRow("friendInvitations", "inviteId", $inviteId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,6 +219,46 @@ sub autoDelete {
|
|||
return $self->get("autoDelete");
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 cacheGroupings ( user, is_member )
|
||||
|
||||
Adds a record to the grouping for this group into the cache.
|
||||
|
||||
=head3 user
|
||||
|
||||
User object to set cache for
|
||||
|
||||
=head3 is_member
|
||||
|
||||
Boolean which indicates whether or not the user passed in is a member of this group
|
||||
|
||||
=cut
|
||||
|
||||
sub cacheGroupings {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $groupId = $self->getId;
|
||||
my $user = shift;
|
||||
my $isInGroup = shift || 0;
|
||||
my $userId = $user->userId;
|
||||
my $sessionId = $session->getId;
|
||||
|
||||
### Undocumented - groupMembers can be passed in if it they are already built.
|
||||
#These exist specifically for WebGUI::User::isInGroup to use and should not be used elsewhere
|
||||
#unless you know what you are doing
|
||||
my $groupMembers = shift || $session->cache->get("groupMembers".$groupId) || {};
|
||||
|
||||
#Build cache in a special way for visitors
|
||||
if($userId eq '1') {
|
||||
$groupMembers->{$userId}->{$sessionId} = { isMember => $isInGroup };
|
||||
}
|
||||
else {
|
||||
$groupMembers->{$userId} = { isMember => $isInGroup };
|
||||
}
|
||||
|
||||
$session->cache->set("groupMembers". $groupId, $groupMembers, $self->groupCacheTimeout);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
|
|
@ -229,12 +269,14 @@ Clears all caches for this group and any ancestor groups of the group.
|
|||
=cut
|
||||
|
||||
sub clearCaches {
|
||||
my $self = shift;
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
##Clear my cache and the cache of all groups above me.
|
||||
my $groups = $self->getAllGroupsFor();
|
||||
my $cache = $self->session->cache;
|
||||
foreach my $group ( $self->getId, @{ $groups } ) {
|
||||
$cache->remove("group_".$group);
|
||||
$cache->remove("groupMembers".$group);
|
||||
}
|
||||
my $stow = $self->session->stow;
|
||||
$stow->delete("groupObj");
|
||||
|
|
@ -509,7 +551,7 @@ sub get {
|
|||
|
||||
=head2 getAllGroupsFor ( )
|
||||
|
||||
Returns an array reference containing a list of all groups this group is in, recursively.
|
||||
Returns an array reference containing a list of all groupIds this group is in, recursively.
|
||||
|
||||
=cut
|
||||
|
||||
|
|
@ -563,12 +605,11 @@ sub getAllUsers {
|
|||
$self->session->errorHandler->fatal("Endless recursive loop detected while determining groups in group.\nRequested groupId: ".$self->getId);
|
||||
}
|
||||
my $groups = $self->getGroupsIn();
|
||||
##Have to iterate twice due to the withoutExpired clause.
|
||||
foreach my $groupId (@{ $groups }) {
|
||||
my $subGroup = WebGUI::Group->new($self->session, $groupId);
|
||||
next
|
||||
if !$subGroup;
|
||||
push @users, @{ $subGroup->getAllUsers(1, $withoutExpired, $loopCount) };
|
||||
push @users, @{ $subGroup->getAllUsers($withoutExpired, $loopCount) };
|
||||
}
|
||||
my %users = map { $_ => 1 } @users;
|
||||
@users = keys %users;
|
||||
|
|
@ -624,7 +665,7 @@ sub getDatabaseUsers {
|
|||
|
||||
=head2 getGroupsFor ( )
|
||||
|
||||
Returns an array reference containing a list of groups this group is in. This method
|
||||
Returns an array reference containing a list of groupIds this group is in. This method
|
||||
does not check recursively backwards up the list of groups.
|
||||
|
||||
=cut
|
||||
|
|
@ -698,7 +739,7 @@ Returns the groupId for this group.
|
|||
|
||||
sub getId {
|
||||
my $self = shift;
|
||||
return $self->{_groupId};
|
||||
return $self->{_groupId};
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -943,6 +984,373 @@ sub getUsersNotIn {
|
|||
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 hasDatabaseUser ( userId )
|
||||
|
||||
Determine if the user passed in is a member of this group via a database query.
|
||||
|
||||
Membership will always be false if no query or database link has been defined
|
||||
for this group.
|
||||
|
||||
=head3 userId
|
||||
|
||||
id of the user to check for membership
|
||||
|
||||
=cut
|
||||
|
||||
sub hasDatabaseUser {
|
||||
my $self = shift;
|
||||
my $userId = shift;
|
||||
my $session = $self->session;
|
||||
my $gid = $self->getId;
|
||||
|
||||
my $query = $self->get("dbQuery");
|
||||
my $dbLinkId = $self->get("databaseLinkId");
|
||||
return 0 unless ($userId && $query && defined $dbLinkId);
|
||||
|
||||
my $dbLink = WebGUI::DatabaseLink->new($session,$dbLinkId);
|
||||
unless (defined $dbLink) {
|
||||
$session->log->error("The database link ".$dbLinkId." no longer exists even though group ".$gid." references it. Group $gid may not be working correctly");
|
||||
return 0;
|
||||
}
|
||||
|
||||
my $dbh = $dbLink->db;
|
||||
unless (defined $dbh) {
|
||||
$session->log->error("Link to database established by could not get database handler for group $gid. This group may not be working correctly");
|
||||
$dbLink->disconnect;
|
||||
return 0;
|
||||
}
|
||||
|
||||
WebGUI::Macro::process($self->session,\$query);
|
||||
#Try to speed up the query by adding a userId filter to the where clause
|
||||
if ($query =~ m/^\s*SELECT\s*(.*)\s*FROM/i) {
|
||||
my $uid_ident = $1;
|
||||
$query =~ s/where/where $uid_ident = '$userId' and/i;
|
||||
}
|
||||
my $sth = $dbh->unconditionalRead($query);
|
||||
|
||||
unless(defined $sth) {
|
||||
$session->log->error("Couldn't process unconditional read for database group with group id $gid. This group may not be working correctly");
|
||||
return 0;
|
||||
}
|
||||
|
||||
unless ($sth->errorCode < 1) {
|
||||
$session->log->warn("There was a problem with the database query for group ID $gid.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (my ($uid) = $sth->array) {
|
||||
if ($uid eq $userId) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 hasIpUser ( userId )
|
||||
|
||||
Determine if the user passed in is a member of this group via the lastIP recorded
|
||||
in the user's session and this group's IpFilter.
|
||||
|
||||
Membership will always be false if no IpFilter has been set
|
||||
|
||||
=head3 userId
|
||||
|
||||
id of the user to check for membership
|
||||
|
||||
=cut
|
||||
|
||||
sub hasIpUser {
|
||||
my $self = shift;
|
||||
my $userId = shift;
|
||||
my $session = $self->session;
|
||||
|
||||
my $IpFilter = $self->ipFilter();
|
||||
return 0 unless ($IpFilter && $userId);
|
||||
|
||||
$IpFilter =~ s/\s//g;
|
||||
my @filters = split /;/, $IpFilter;
|
||||
|
||||
my @ips = $session->db->buildArray(
|
||||
q{ select lastIP from userSession where expires > ? and userId = ? }
|
||||
,[ time(), $userId ]
|
||||
);
|
||||
|
||||
foreach my $ip (@ips) {
|
||||
return 1 if (isInSubnet($ip,\@filters));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 hasKarmaUser ( userId )
|
||||
|
||||
Determine if the user passed in is a member of this group via the their current
|
||||
karma setting and this group's karmaThreshold.
|
||||
|
||||
If karma is not enabled for this site, membership will always be false.
|
||||
|
||||
=head3 userId
|
||||
|
||||
id of the user to check for membership
|
||||
|
||||
=cut
|
||||
|
||||
sub hasKarmaUser {
|
||||
my $self = shift;
|
||||
my $userId = shift;
|
||||
my $session = $self->session;
|
||||
|
||||
return 0 unless ($session->setting->get('useKarma') && $userId);
|
||||
|
||||
return $session->db->quickScalar(
|
||||
q{ select count(*) from users where karma >= ? and userId = ? }
|
||||
,[$self->karmaThreshold,$userId]
|
||||
);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 hasLDAPUser ( userId )
|
||||
|
||||
Determine if the user passed in is a member of this group via an LDAP
|
||||
connection
|
||||
|
||||
If ldapLink, ldapGroup, and ldapGroupProperty are not configured for this group
|
||||
membership will always be false.
|
||||
|
||||
#TODO - change the way this works to search LDAP for the dn associated with the
|
||||
userId. That should speed this up a bunch for people using LDAP groups.
|
||||
|
||||
=head3 userId
|
||||
|
||||
id of the user to check for membership
|
||||
|
||||
=cut
|
||||
|
||||
sub hasLDAPUser {
|
||||
my $self = shift;
|
||||
my $userId = shift;
|
||||
my $session = $self->session;
|
||||
my @ldapUsers = ();
|
||||
my $gid = $self->getId;
|
||||
|
||||
### Check LDAP
|
||||
my $ldapLinkId = $self->get("ldapLinkId");
|
||||
my $ldapGroup = $self->get("ldapGroup");
|
||||
my $ldapGroupProperty = $self->get("ldapGroupProperty");
|
||||
my $ldapRecursiveProperty = $self->get("ldapRecursiveProperty");
|
||||
my $ldapRecurseFilter = $self->get("ldapRecursiveFilter");
|
||||
|
||||
return 0 unless ($ldapLinkId && $ldapGroup && $ldapGroupProperty && $userId);
|
||||
|
||||
my $ldapLink = WebGUI::LDAPLink->new($session,$ldapLinkId);
|
||||
unless ($ldapLink && $ldapLink->bind) {
|
||||
$self->session->errorHandler->warn("There was a problem connecting to LDAP link $ldapLinkId for group ID $gid.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
my $people = [];
|
||||
if($ldapRecursiveProperty) {
|
||||
$ldapLink->recurseProperty($ldapGroup,$people,$ldapGroupProperty,$ldapRecursiveProperty,$ldapRecurseFilter);
|
||||
} else {
|
||||
$people = $ldapLink->getProperty($ldapGroup,$ldapGroupProperty);
|
||||
}
|
||||
$ldapLink->unbind;
|
||||
|
||||
foreach my $person (@{$people}) {
|
||||
$person =~ s/\s*,\s*/,/g;
|
||||
$person = lc($person);
|
||||
my $personRegExp = "^uid=$person,";
|
||||
my $uid = $session->db->quickScalar("select userId from authentication where authMethod='LDAP' and fieldName='connectDN' and lower(fieldData) = ? OR lower(fieldData) REGEXP ?",[$person,$personRegExp]);
|
||||
return 1 if ($uid eq $userId);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 hasScratchUser ( userId )
|
||||
|
||||
Determine if the user passed in is a member of this group via session scratch
|
||||
variable settings and this group's scratchFilter.
|
||||
|
||||
If no scratchFilter has been set for this group, membership will always be false.
|
||||
|
||||
=head3 userId
|
||||
|
||||
id of the user to check for membership
|
||||
|
||||
=cut
|
||||
|
||||
sub hasScratchUser {
|
||||
my $self = shift;
|
||||
my $userId = shift;
|
||||
my $session = $self->session;
|
||||
|
||||
my $scratchFilter = $self->scratchFilter();
|
||||
return 0 unless ($scratchFilter && $userId);
|
||||
|
||||
$scratchFilter =~ s/\s//g;
|
||||
my @filters = split /;/, $scratchFilter;
|
||||
|
||||
my @scratchClauses = ();
|
||||
my @scratchPlaceholders = ( $userId, time() );
|
||||
foreach my $filter (@filters) {
|
||||
my ($name, $value) = split /=/, $filter;
|
||||
push @scratchClauses, "(s.name=? AND s.value=?)";
|
||||
push @scratchPlaceholders, $name, $value;
|
||||
}
|
||||
my $scratchClause = join ' OR ', @scratchClauses;
|
||||
|
||||
my $query = qq{
|
||||
select
|
||||
count(*)
|
||||
from
|
||||
userSession u, userSessionScratch s
|
||||
where
|
||||
u.sessionId=s.sessionId AND
|
||||
u.userId = ? AND
|
||||
u.expires > ? AND
|
||||
( $scratchClause )
|
||||
};
|
||||
|
||||
return $session->db->quickScalar($query, [ @scratchPlaceholders ]);
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 hasUser ( user )
|
||||
|
||||
Determine if the user passed in is a member of one of the special groups
|
||||
for this group
|
||||
|
||||
=head3 user
|
||||
|
||||
user object to check groups for
|
||||
|
||||
=cut
|
||||
|
||||
sub hasUser {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $user = shift || WebGUI::User->new($session,3); #Check the admin account if no user is passed in
|
||||
my $gid = $self->getId;
|
||||
my $db = $session->db;
|
||||
|
||||
my $uid = $user->userId;
|
||||
### Get what's in session cache for this group
|
||||
my $isInGroup = $session->stow->get("isInGroup", { noclone => 1 }) || {};
|
||||
### Check to see that we have a cache built for this user
|
||||
my $hasCache = (exists $isInGroup->{$uid}->{cached});
|
||||
|
||||
### Return what is in the cache if we've already cached this group in the session.
|
||||
return $isInGroup->{$uid}->{$gid} if ( exists $isInGroup->{$uid}->{$gid} );
|
||||
|
||||
### If we dont' have a cache yet, cache all of the groups this user is directly a member of
|
||||
### this will only happen if there is no cache built for this user and it saves us from running one query per group
|
||||
unless ($hasCache) {
|
||||
### Get the list of groups this user is directly a member of
|
||||
my @groups = $db->buildArray(
|
||||
q{ select groupId from groupings where userId=? and expireDate > ? }
|
||||
, [$uid,time()]
|
||||
);
|
||||
### Cache the groupings we find
|
||||
map { $isInGroup->{$uid}->{$_} = 1 } @groups;
|
||||
### Set a cached flag so someone else doesn't accidentally call stow before us and screw our quick caching method
|
||||
$isInGroup->{$uid}->{cached} = 1;
|
||||
### Stow the cache here because we have set the cache for other groups besides this one.
|
||||
$session->stow->set("isInGroup",$isInGroup);
|
||||
### Return if we found the user in this group
|
||||
return 1 if ( $isInGroup->{$uid}->{$gid} );
|
||||
}
|
||||
|
||||
### User was not found directly in this group. Create a list of groups to check deeply and add this group to that list
|
||||
my $groupsToCheckDeeply = { $gid => 1 };
|
||||
|
||||
#Made it here because user is not in the group itself. Now check for direct existance in the sub groups.
|
||||
#Now build a list of the subgroups for this group that the user is part of
|
||||
|
||||
### Check all of the sub groups for direct existance, caching all of the subgroups that we do not find the user
|
||||
### in our list of groups that need to be checked more deeply
|
||||
my @groups = ($gid); #Start checking sub groups of this group only
|
||||
my $loopLimit = 100; #Set a loop limit just to be safe
|
||||
while (scalar(@groups) && $loopLimit--) {
|
||||
### Check all of the groups of groups for all of the current @groups array. The query below
|
||||
### returns the group that was in the group along with whether or not the user is directly a member
|
||||
my $sqlInStr = $db->quoteAndJoin(\@groups);
|
||||
my $sth = $db->read(
|
||||
qq{ select
|
||||
groupGroupings.groupId, userId
|
||||
from
|
||||
groupGroupings
|
||||
left join groupings on groupGroupings.groupId=groupings.groupId and userId=?
|
||||
where
|
||||
inGroup in ($sqlInStr)
|
||||
}
|
||||
,[$uid]
|
||||
);
|
||||
### Create a subgroup cache for this pass of the loop so we know what groups to check next
|
||||
my $subgroupCache = {};
|
||||
while (my ($groupId,$userId) = $sth->array){
|
||||
next if ($subgroupCache->{$groupId}); #Skip subgroups we've already checked - nothing has changed
|
||||
### Return true if we find that the user is in the sub group from the session cache - no need to stow any caches here
|
||||
return 1 if ($isInGroup->{$uid}->{$groupId});
|
||||
### If the userId field is not null, that means that this user is directly a member of this sub group
|
||||
if($userId) {
|
||||
### Stow the result and return true;
|
||||
$isInGroup->{$uid}->{$groupId} = 1; #Cache the sub group results
|
||||
$isInGroup->{$uid}->{$gid} = 1; #Cache the results for the group we are checking
|
||||
$session->stow->set("isInGroup",$isInGroup); #Stow the Cache
|
||||
return 1;
|
||||
}
|
||||
### We made it here because the user is not directly in the subgroup.
|
||||
$subgroupCache->{$groupId} = 1; #Update the subgroup cache for the next outer loop pass
|
||||
$groupsToCheckDeeply->{$groupId} = 1; #We need to check this group more deeply
|
||||
}
|
||||
### Get the next level of sub groups to check from the subgroupCache keys.
|
||||
@groups = keys %{$subgroupCache};
|
||||
}
|
||||
|
||||
### Made it here because the user is not directly in the group itself or directly in any of it's subgroups
|
||||
### We should have a flattened list of groups in this group that we should now check one by one to see if the
|
||||
### user is is a member via one of the other methods available for groups
|
||||
|
||||
foreach my $groupIdInGroup (keys %{$groupsToCheckDeeply}) {
|
||||
### Instantiate the group
|
||||
my $groupToCheck = __PACKAGE__->new($session,$groupIdInGroup);
|
||||
### Check the 'has' method for each of the 'other' group methods available for this user
|
||||
### perform checks in a least -> most expensive manner. If we find the user, stow the cache and return true
|
||||
if( $groupToCheck->hasIpUser($uid)
|
||||
|| $groupToCheck->hasKarmaUser($uid)
|
||||
|| $groupToCheck->hasScratchUser($uid)
|
||||
|| $groupToCheck->hasDatabaseUser($uid)
|
||||
|| $groupToCheck->hasLDAPUser($uid)
|
||||
) {
|
||||
#Found the user in one of the 'other' group methods
|
||||
$isInGroup->{$uid}->{$groupIdInGroup} = 1; #Cache the results for this group so we don't have to check it again
|
||||
$isInGroup->{$uid}->{$gid} = 1; #Cache the results for the main group because we found the user in one of the subgroups
|
||||
$session->stow->set("isInGroup",$isInGroup); #Stow the cache
|
||||
return 1;
|
||||
}
|
||||
#Made it here because we did not find the user at all in this subgroup. Cache the result so we don't have to check this subgroup again.
|
||||
$isInGroup->{$uid}->{$groupIdInGroup} = 0;
|
||||
}
|
||||
|
||||
#If we made it here, that means the user is not in the group or any of it's sub groups
|
||||
#Cache the result, stow the cache, and return false as this group does not contain the user.
|
||||
$isInGroup->{$uid}->{$gid} = 0;
|
||||
$session->stow->set("isInGroup",$isInGroup);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -199,6 +199,26 @@ our $HELP = {
|
|||
related => [ ],
|
||||
},
|
||||
|
||||
'collaboration unsubscribe template' => {
|
||||
title => 'collaboration unsubscribe template title',
|
||||
body => '',
|
||||
fields => [],
|
||||
isa => [],
|
||||
variables => [
|
||||
{ name => 'formHeader',
|
||||
description => 'unsubscribe formHeader', },
|
||||
{ name => 'formSubmit',
|
||||
description => 'unsubscribe formSubmit', },
|
||||
{ name => 'formEmail',
|
||||
description => 'unsubscribe formEmail', },
|
||||
{ name => 'formFooter',
|
||||
description => 'unsubscribe formFooter', },
|
||||
{ name => 'formMessage',
|
||||
description => 'unsubscribe formMessage', },
|
||||
],
|
||||
related => [ ],
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -250,10 +250,18 @@ our $HELP = {
|
|||
name => 'form_keywords',
|
||||
description => 'helpvar form_keywords',
|
||||
},
|
||||
{
|
||||
name => 'form_location',
|
||||
description => 'helpvar form_location',
|
||||
},
|
||||
{
|
||||
name => 'form_friendsOnly',
|
||||
description => 'helpvar form_friendsOnly',
|
||||
},
|
||||
{
|
||||
name => 'form_sortBy',
|
||||
description => 'helpvar form_sortBy',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -184,6 +184,7 @@ A reference to the current session.
|
|||
|
||||
sub www_editProfile {
|
||||
my $session = shift;
|
||||
return $session->privilege->insufficient if $session->user->isVisitor;
|
||||
my $instance = WebGUI::Content::Account->createInstance($session,"profile");
|
||||
return $instance->displayContent($instance->callMethod("edit"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,20 +145,27 @@ A message to be displayed in the status bar.
|
|||
|
||||
=cut
|
||||
|
||||
{
|
||||
|
||||
# Keep the sprintf string short and don't recompute buffer breaker every time
|
||||
# update is called
|
||||
my $prefix = '<script type="text/javascript">
|
||||
/* ' . 'BUFFER BREAKER ' x 1000 . ' */
|
||||
updateWgProgressBar(';
|
||||
my $format = q"'%dpx', '%s'";
|
||||
my $suffix = ');
|
||||
</script>
|
||||
';
|
||||
|
||||
sub update {
|
||||
my $self = shift;
|
||||
my $message = shift;
|
||||
$message =~ s/'/\\'/g; ##Encode single quotes for JSON;
|
||||
$self->session->log->preventDebugOutput;
|
||||
$self->{_counter} += 1;
|
||||
my $counter = $self->{_counter} += 1;
|
||||
|
||||
my $modproxy_buffer_breaker = 'BUFFER BREAKER ' x 1000;
|
||||
my $text = sprintf(<<EOJS, $self->{_counter}, $message);
|
||||
<script type="text/javascript">
|
||||
/* $modproxy_buffer_breaker */
|
||||
updateWgProgressBar('%dpx', '%s');
|
||||
</script>
|
||||
EOJS
|
||||
my $text = $prefix . sprintf($format, $counter, $message) . $suffix;
|
||||
|
||||
local $| = 1; # Tell modperl not to buffer the output
|
||||
$self->session->output->print($text, 1); #skipMacros
|
||||
if ($self->{_counter} > 600) {
|
||||
|
|
@ -167,5 +174,92 @@ EOJS
|
|||
return '';
|
||||
}
|
||||
|
||||
1;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 run ( options )
|
||||
|
||||
starts and finishes a progress bar, running some code in the middle. It
|
||||
returns 'chunked' for convenience - if you don't use the return value, you
|
||||
should return 'chunked' yourself.
|
||||
|
||||
The following keyword arguments are accepted (either as a bare hash or a
|
||||
hashref).
|
||||
|
||||
=head3 code
|
||||
|
||||
A coderef to run in between starting and stopping the progress bar. It is
|
||||
passed the progress bar instance as its first and only argument. It should
|
||||
return the url to redirect to with finish(), or a false value.
|
||||
|
||||
=head3 arg
|
||||
|
||||
An argument (just one) to be passed to code when it is called.
|
||||
|
||||
=head3 title
|
||||
|
||||
See start().
|
||||
|
||||
=head3 icon
|
||||
|
||||
See start().
|
||||
|
||||
=head3 wrap
|
||||
|
||||
A hashref of subroutine names to code references. While code is being called,
|
||||
these subroutines will be wrapped with the provided code references, which
|
||||
will be passed the progress bar instance, the original code reference, and any
|
||||
arguments it would have received, similiar to a Moose 'around' method, e.g.
|
||||
|
||||
wrap => {
|
||||
'WebGUI::Asset::update' => sub {
|
||||
my $bar = shift;
|
||||
my $original = shift;
|
||||
$bar->update('some message');
|
||||
$original->(@_);
|
||||
}
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
sub run {
|
||||
my $self = shift;
|
||||
my $args = $_[0];
|
||||
$args = { @_ } unless ref $args eq 'HASH';
|
||||
|
||||
my %original;
|
||||
my $wrap = $args->{wrap};
|
||||
|
||||
$self->start($args->{title}, $args->{icon});
|
||||
|
||||
my $url = eval {
|
||||
for my $name (keys %$wrap) {
|
||||
my $original = $original{$name} = do { no strict 'refs'; \&$name };
|
||||
my $wrapper = $wrap->{$name};
|
||||
no strict 'refs';
|
||||
*$name = sub {
|
||||
unshift(@_, $self, $original);
|
||||
goto &$wrapper;
|
||||
};
|
||||
}
|
||||
|
||||
$args->{code}->($self, $args->{arg});
|
||||
};
|
||||
my $e = $@;
|
||||
|
||||
# Always, always restore coderefs
|
||||
for my $name (keys %original) {
|
||||
my $c = $original{$name};
|
||||
if (ref $c eq 'CODE') {
|
||||
no strict 'refs';
|
||||
*$name = $c;
|
||||
}
|
||||
}
|
||||
|
||||
die $e if $e;
|
||||
|
||||
return $self->finish($url || $self->session->url->page);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -183,9 +183,10 @@ the one in this user's current session.
|
|||
sub validToken {
|
||||
my ($self) = @_;
|
||||
my $session = $self->session;
|
||||
$session->log->debug('HTTP method: '. $session->request->method);
|
||||
$session->log->debug('CSRF token: '. $session->scratch->get('webguiCsrfToken'));
|
||||
$session->log->warn('HTTP method: '. $session->request->method);
|
||||
$session->log->warn('CSRF token: '. $session->scratch->get('webguiCsrfToken'));
|
||||
return 0 unless $session->request->method eq 'POST';
|
||||
$session->log->warn('Web token: '. $self->param('webguiCsrfToken'));
|
||||
return 0 unless $self->param('webguiCsrfToken') eq $session->scratch->get('webguiCsrfToken');
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -401,10 +401,16 @@ The string to make compliant. This is usually a page title or a filename.
|
|||
=cut
|
||||
|
||||
sub makeCompliant {
|
||||
my $self = shift;
|
||||
my $url = shift;
|
||||
my $i18n = WebGUI::International->new($self->session);
|
||||
return $i18n->makeUrlCompliant($url);
|
||||
my $self = shift;
|
||||
my $url = shift;
|
||||
$url =~ s{^\s+}{}; # remove leading whitespace
|
||||
$url =~ s{\s+$}{}; # remove trailing whitespace
|
||||
$url =~ s{^/+}{}; # remove leading slashes
|
||||
$url =~ s{/+$}{}; # remove trailing slashes
|
||||
$url =~ s{[^\w/:._-]+}{-}g; # replace anything aside from word or other allowed characters with dashes
|
||||
$url =~ s{//+}{/}g; # remove double slashes
|
||||
$url =~ s{--+}{-}g; # remove double dashes
|
||||
return $url;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -82,32 +82,33 @@ sub appendAddressFormVars {
|
|||
$properties ||= {};
|
||||
$prefix ||= '';
|
||||
$var ||= {};
|
||||
my $hasAddress = keys %{ $properties };
|
||||
for ( qw{ address1 address2 address3 label firstName lastName city state organization } ) {
|
||||
$var->{ $prefix . $_ . 'Field' } = WebGUI::Form::text( $session, {
|
||||
name => $prefix . $_,
|
||||
maxlength => 35,
|
||||
defaultValue => $properties->{ $_ } || $form->get($prefix . $_),
|
||||
defaultValue => $hasAddress ? $properties->{ $_ } : $form->get($prefix . $_),
|
||||
} );
|
||||
}
|
||||
$var->{ $prefix . 'countryField' } =
|
||||
WebGUI::Form::country( $session,{
|
||||
name => $prefix . 'country',
|
||||
defaultValue => $properties->{ country } || $form->get($prefix . 'country' ),
|
||||
defaultValue => $hasAddress ? $properties->{ country } : $form->get($prefix . 'country' ),
|
||||
} );
|
||||
$var->{ $prefix . 'codeField' } =
|
||||
WebGUI::Form::zipcode( $session, {
|
||||
name => $prefix . 'code',
|
||||
defaultValue => $properties->{ code } || $form->get($prefix . 'code' ),
|
||||
defaultValue => $hasAddress ? $properties->{ code } : $form->get($prefix . 'code' ),
|
||||
} );
|
||||
$var->{ $prefix . 'phoneNumberField' } =
|
||||
WebGUI::Form::phone( $session, {
|
||||
name => $prefix . 'phoneNumber',
|
||||
defaultValue => $properties->{ phoneNumber } || $form->get($prefix . 'phoneNumber' ),
|
||||
defaultValue => $hasAddress ? $properties->{ phoneNumber } : $form->get($prefix . 'phoneNumber' ),
|
||||
} );
|
||||
$var->{ $prefix . 'emailField' } =
|
||||
WebGUI::Form::email( $session, {
|
||||
name => $prefix . 'email',
|
||||
defaultValue => $properties->{ email } || $form->get($prefix . 'email' ),
|
||||
defaultValue => $hasAddress ? $properties->{ email } : $form->get($prefix . 'email' ),
|
||||
} );
|
||||
}
|
||||
|
||||
|
|
@ -328,7 +329,7 @@ sub missingFields {
|
|||
$addressData = $address;
|
||||
}
|
||||
my @missingFields = ();
|
||||
FIELD: foreach my $field (qw/label firstName lastName address1 city code country phoneNumber/) {
|
||||
FIELD: foreach my $field (qw/label firstName lastName address1 city state code country phoneNumber/) {
|
||||
push @missingFields, $field if $addressData->{$field} eq '';
|
||||
}
|
||||
return @missingFields;
|
||||
|
|
|
|||
|
|
@ -287,15 +287,39 @@ sub getBillingAddress {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getPaymentGateway ()
|
||||
=head2 getI18nError ()
|
||||
|
||||
Returns the WebGUI::Shop::PayDriver object that is attached to this cart for payment.
|
||||
Returns an internationalized version of the current error, if it exists.
|
||||
|
||||
=cut
|
||||
|
||||
sub getPaymentGateway {
|
||||
my $self = shift;
|
||||
return WebGUI::Shop::Pay->new($self->session)->getPaymentGateway($self->get("gatewayId"));
|
||||
sub getI18nError {
|
||||
my ($self) = @_;
|
||||
my $error = $self->error;
|
||||
my $i18n = WebGUI::International->new($self->session, 'Shop');
|
||||
return $error eq 'no billing address' ? $i18n->get('no billing address')
|
||||
: $error eq 'no shipping address' ? $i18n->get('no shipping address')
|
||||
: $error eq 'billing label' ? $i18n->get('billing label')
|
||||
: $error eq 'billing firstName' ? $i18n->get('billing firstName')
|
||||
: $error eq 'billing lastName' ? $i18n->get('billing lastName')
|
||||
: $error eq 'billing address1' ? $i18n->get('billing address1')
|
||||
: $error eq 'billing city' ? $i18n->get('billing city')
|
||||
: $error eq 'billing code' ? $i18n->get('billing code')
|
||||
: $error eq 'billing state' ? $i18n->get('billing state')
|
||||
: $error eq 'billing country' ? $i18n->get('billing country')
|
||||
: $error eq 'billing phoneNumber' ? $i18n->get('billing phoneNumber')
|
||||
: $error eq 'shipping label' ? $i18n->get('shipping label')
|
||||
: $error eq 'shipping firstName' ? $i18n->get('shipping firstName')
|
||||
: $error eq 'shipping lastName' ? $i18n->get('shipping lastName')
|
||||
: $error eq 'shipping address1' ? $i18n->get('shipping address1')
|
||||
: $error eq 'shipping city' ? $i18n->get('shipping city')
|
||||
: $error eq 'shipping code' ? $i18n->get('shipping code')
|
||||
: $error eq 'shipping state' ? $i18n->get('shipping state')
|
||||
: $error eq 'shipping country' ? $i18n->get('shipping country')
|
||||
: $error eq 'shipping phoneNumber' ? $i18n->get('shipping phoneNumber')
|
||||
: $error eq 'no shipping method set' ? $i18n->get('Choose a shipping method and update the cart to checkout')
|
||||
: $error eq 'no payment gateway set' ? $i18n->get('Choose a payment gateway and update the cart to checkout')
|
||||
: $error ;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -377,6 +401,19 @@ sub getItemsByAssetId {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getPaymentGateway ()
|
||||
|
||||
Returns the WebGUI::Shop::PayDriver object that is attached to this cart for payment.
|
||||
|
||||
=cut
|
||||
|
||||
sub getPaymentGateway {
|
||||
my $self = shift;
|
||||
return WebGUI::Shop::Pay->new($self->session)->getPaymentGateway($self->get("gatewayId"));
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getPosUser
|
||||
|
||||
Returns the userId of the user making a purchase. If there is a cashier and the cashier has specified a user, then that user will be returned. Otherwise, if it's a direct sale then $session->user will be returned.
|
||||
|
|
@ -542,7 +579,7 @@ sub readyForCheckout {
|
|||
}
|
||||
|
||||
if (my @missingFields = $book->missingFields($address->get)) {
|
||||
$self->error($missingFields[0]);
|
||||
$self->error('billing '.$missingFields[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -554,7 +591,7 @@ sub readyForCheckout {
|
|||
}
|
||||
|
||||
if (my @missingFields = $book->missingFields($shipAddress->get)) {
|
||||
$self->error($missingFields[0]);
|
||||
$self->error('shipping '.$missingFields[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -702,8 +739,9 @@ Updates the cart totals, the address fields and the shipping and billing options
|
|||
=cut
|
||||
|
||||
sub updateFromForm {
|
||||
my $self = shift;
|
||||
my $form = $self->session->form;
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $form = $session->form;
|
||||
foreach my $item (@{$self->getItems}) {
|
||||
if ($form->get("quantity-".$item->getId) ne "") {
|
||||
eval { $item->setQuantity($form->get("quantity-".$item->getId)) };
|
||||
|
|
@ -740,12 +778,12 @@ sub updateFromForm {
|
|||
my $address = $self->getBillingAddress();
|
||||
$address->update(\%billingData);
|
||||
}
|
||||
elsif ($billingAddressId ne 'new_address' && $billingAddressId) {
|
||||
elsif ($billingAddressId ne 'new_address' && $billingAddressId ne 'update_address' && $billingAddressId) {
|
||||
##User changed the address selector to another address field
|
||||
$cartProperties->{billingAddressId} = $billingAddressId;
|
||||
}
|
||||
elsif (@missingBillingFields) {
|
||||
$self->error('missing billing '.$missingBillingFields[0]);
|
||||
$self->error('billing '.$missingBillingFields[0]);
|
||||
}
|
||||
else {
|
||||
$self->session->log->warn('billing address: something else: ');
|
||||
|
|
@ -763,7 +801,7 @@ sub updateFromForm {
|
|||
my $shippingAddressId = $form->process('shippingAddressId');
|
||||
##No missing shipping fields, if we set to the same as the billing fields
|
||||
if (@missingShippingFields) {
|
||||
$self->error('missing shipping '.$missingShippingFields[0]);
|
||||
$self->error('shipping '.$missingShippingFields[0]);
|
||||
}
|
||||
if ($shippingAddressId eq 'new_address' && ! @missingShippingFields) {
|
||||
##Add a new address
|
||||
|
|
@ -775,7 +813,7 @@ sub updateFromForm {
|
|||
my $address = $self->getBillingAddress();
|
||||
$address->update(\%shippingData);
|
||||
}
|
||||
elsif ($shippingAddressId ne 'new_address' && $shippingAddressId) {
|
||||
elsif ($shippingAddressId ne 'new_address' && $shippingAddressId ne 'update_address' && $shippingAddressId) {
|
||||
$cartProperties->{shippingAddressId} = $shippingAddressId;
|
||||
}
|
||||
else {
|
||||
|
|
@ -921,7 +959,7 @@ sub www_update {
|
|||
##Handle rounding errors, and checkout immediately if the amount is 0 since
|
||||
##at least the ITransact driver won't accept $0 checkout.
|
||||
if (sprintf('%.2f', $total + $self->calculateShopCreditDeduction($total)) eq '0.00') {
|
||||
my $transaction = WebGUI::Shop::Transaction->create($session, {self => $self});
|
||||
my $transaction = WebGUI::Shop::Transaction->create($session, {cart => $self});
|
||||
$transaction->completePurchase('zero', 'success', 'success');
|
||||
$self->onCompletePurchase;
|
||||
$transaction->sendNotifications();
|
||||
|
|
@ -968,7 +1006,7 @@ sub www_view {
|
|||
|
||||
my %var = (
|
||||
%{$self->get},
|
||||
formHeader => WebGUI::Form::formHeader($session)
|
||||
formHeader => WebGUI::Form::formHeader($session, { extras => q|id="wgCartId"|, })
|
||||
. WebGUI::Form::hidden($session, {name=>"shop", value=>"cart"})
|
||||
. WebGUI::Form::hidden($session, {name=>"method", value=>"update"})
|
||||
. WebGUI::Form::hidden($session, {name=>"itemId", value=>""})
|
||||
|
|
@ -1117,7 +1155,7 @@ sub www_view {
|
|||
|
||||
my $billingAddressId = $self->get('billingAddressId');
|
||||
if ($billingAddressId) {
|
||||
$billingAddressOptions{'update_address'} = $i18n->get('Update this address');
|
||||
$billingAddressOptions{'update_address'} = sprintf $i18n->get('Update %s'), $self->getBillingAddress->get('label');
|
||||
}
|
||||
|
||||
%billingAddressOptions = (%billingAddressOptions, %addressOptions);
|
||||
|
|
@ -1133,7 +1171,7 @@ sub www_view {
|
|||
|
||||
my $shippingAddressId = $self->get('shippingAddressId');
|
||||
if ($shippingAddressId) {
|
||||
$shippingAddressOptions{'update_address'} = $i18n->get('Update this address');
|
||||
$shippingAddressOptions{'update_address'} = sprintf $i18n->get('Update %s'), $self->getShippingAddress->get('label');
|
||||
}
|
||||
%shippingAddressOptions = (%shippingAddressOptions, %addressOptions);
|
||||
|
||||
|
|
@ -1183,12 +1221,12 @@ sub www_view {
|
|||
$var{totalPrice} = $var{subtotalPrice} + $var{shippingPrice} + $var{tax};
|
||||
my $credit = WebGUI::Shop::Credit->new($session, $posUser->userId);
|
||||
$var{ inShopCreditAvailable } = $credit->getSum;
|
||||
$var{ inShopCreditDeduction } = $credit->calculateDeduction($var{totalPrice});
|
||||
$var{ inShopCreditDeduction } = $self->calculateShopCreditDeduction($var{totalPrice});
|
||||
$var{ totalPrice } = $self->formatCurrency($var{totalPrice} + $var{inShopCreditDeduction});
|
||||
foreach my $field (qw/subtotalPrice inShopCreditAvailable inShopCreditDeduction totalPrice shippingPrice tax/) {
|
||||
$var{$field} = sprintf q|<span id="%sWrap">%s</span>|, $field, $var{$field};
|
||||
}
|
||||
$var{ error } = $self->error;
|
||||
$var{ error } = $self->getI18nError;
|
||||
|
||||
# render the cart
|
||||
my $template = WebGUI::Asset->newById($session, $session->setting->get("shopCartTemplateId"));
|
||||
|
|
|
|||
|
|
@ -49,8 +49,11 @@ The reason for this adjustment.
|
|||
|
||||
sub adjust {
|
||||
my ($self, $amount, $comment) = @_;
|
||||
my $user = WebGUI::User->new($self->session, $self->userId);
|
||||
return 0 if $user->isVisitor;
|
||||
$self->session->db->write("insert into shopCredit (creditId, userId, amount, comment, dateOfAdjustment) values (?,?,?,?,now())",
|
||||
[$self->session->id->generate, $self->userId, $amount, $comment]);
|
||||
return $amount;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -179,11 +182,11 @@ sub www_adjust {
|
|||
my ($class, $session) = @_;
|
||||
my $admin = WebGUI::Shop::Admin->new($session);
|
||||
return $session->privilege->insufficient() unless $admin->canManage;
|
||||
my $form = $session->form;
|
||||
my $credit = $class->new($session, $form->get('userId'));
|
||||
$credit->adjust($form->get('amount'), $form->get('comment'));
|
||||
my $i18n = WebGUI::International->new($session, "Shop");
|
||||
my $message = sprintf $i18n->get('add credit message'), $form->get('amount'), WebGUI::User->new($session, $form->get('userId'))->username, $credit->getSum;
|
||||
my $form = $session->form;
|
||||
my $credit = $class->new($session, $form->get('userId'));
|
||||
my $amount = $credit->adjust($form->get('amount'), $form->get('comment'));
|
||||
my $i18n = WebGUI::International->new($session, "Shop");
|
||||
my $message = sprintf $i18n->get('add credit message'), $amount, WebGUI::User->new($session, $form->get('userId'))->username, $credit->getSum;
|
||||
return $class->www_manage($session, $message);
|
||||
}
|
||||
|
||||
|
|
@ -199,14 +202,16 @@ sub www_manage {
|
|||
my ($class, $session, $message) = @_;
|
||||
my $admin = WebGUI::Shop::Admin->new($session);
|
||||
return $session->privilege->insufficient() unless $admin->canManage;
|
||||
my $i18n = WebGUI::International->new($session, "Shop");
|
||||
my $f = WebGUI::HTMLForm->new($session);
|
||||
$f->hidden(name=>'shop',value=>'credit');
|
||||
$f->hidden(name=>'method',value=>'adjust');
|
||||
my $i18n = WebGUI::International->new($session, "Shop");
|
||||
my $f = WebGUI::HTMLForm->new($session);
|
||||
my $userId = $session->form->process('userId') || $session->user->userId;
|
||||
my $user = WebGUI::User->new($session, $userId);
|
||||
$f->hidden(name => 'shop', value => 'credit');
|
||||
$f->hidden(name => 'method', value => 'adjust');
|
||||
$f->user(
|
||||
name => 'userId',
|
||||
label => $i18n->get('username'),
|
||||
value => $session->user->userId,
|
||||
value => $userId,
|
||||
);
|
||||
$f->float(
|
||||
name => 'amount',
|
||||
|
|
@ -217,6 +222,10 @@ sub www_manage {
|
|||
label => $i18n->get('notes'),
|
||||
);
|
||||
$f->submit;
|
||||
if (! $message) {
|
||||
my $credit = $class->new($session, $userId);
|
||||
$message ||= sprintf $i18n->get('current credit message'), $user->username, $credit->getSum;
|
||||
}
|
||||
return $admin->getAdminConsole->render($message.$f->print, $i18n->get('in shop credit'));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -895,7 +895,7 @@ sub isEnabled {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 isInGroup ( [ groupId ] )
|
||||
=head2 isInGroup ( [groupId ] )
|
||||
|
||||
Returns a boolean (0|1) value signifying that the user has the required privileges. Always returns true for Admins.
|
||||
|
||||
|
|
@ -906,38 +906,47 @@ The group that you wish to verify against the user. Defaults to group with Id 3
|
|||
=cut
|
||||
|
||||
sub isInGroup {
|
||||
my ($self, $gid) = @_;
|
||||
$gid = 3 unless $gid;
|
||||
my $uid = $self->userId;
|
||||
### The following several checks are to increase performance. If this section were removed, everything would continue to work as normal.
|
||||
#my $eh = $self->session->errorHandler;
|
||||
#$eh->warn("Group Id is: $gid for ".$tgroup->name);
|
||||
return 1 if ($gid eq '7'); # everyone is in the everyone group
|
||||
return 1 if ($gid eq '1' && $uid eq '1'); # visitors are in the visitors group
|
||||
return 1 if ($gid eq '2' && $uid ne '1'); # if you're not a visitor, then you're a registered user
|
||||
### Get data for auxillary checks.
|
||||
my $isInGroup = $self->session->stow->get("isInGroup", { noclone => 1 });
|
||||
### Look to see if we've already looked up this group.
|
||||
return $isInGroup->{$uid}{$gid} if exists $isInGroup->{$uid}{$gid};
|
||||
### Lookup the actual groupings.
|
||||
my $group = WebGUI::Group->new($self->session,$gid);
|
||||
if ( !$group ) {
|
||||
$group = WebGUI::Group->new($self->session,3);
|
||||
}
|
||||
### Check for groups of groups.
|
||||
my $users = $group->getAllUsers();
|
||||
foreach my $user (@{$users}) {
|
||||
$isInGroup->{$user}{$gid} = 1;
|
||||
if ($uid eq $user) {
|
||||
$self->session->stow->set("isInGroup",$isInGroup);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
$isInGroup->{$uid}{$gid} = 0;
|
||||
$self->session->stow->set("isInGroup",$isInGroup);
|
||||
return 0;
|
||||
}
|
||||
my ($self, $gid) = @_;
|
||||
my $session = $self->session;
|
||||
my $uid = $self->userId;
|
||||
$gid = 3 unless $gid;
|
||||
|
||||
### The following several checks are to increase performance. If this section were removed, everything would continue to work as normal.
|
||||
return 1 if ($gid eq '7'); # everyone is in the everyone group
|
||||
return 1 if ($gid eq '1' && $uid eq '1'); # visitors are in the visitors group
|
||||
return 1 if ($gid eq '2' && $uid ne '1'); # if you're not a visitor, then you're a registered user
|
||||
|
||||
### Check stow before we check the cache. Stow is in memory and much faster
|
||||
my $stow = $session->stow->get("isInGroup", { noclone => 1 }) || {};
|
||||
return $stow->{$uid}->{$gid} if (exists $stow->{$uid}->{$gid});
|
||||
|
||||
### Don't bother checking File Cache if we already have a stow for this group.
|
||||
### We can find what we need there and save ourselves a bunch of time
|
||||
my $cache = undef;
|
||||
my $groupMembers = undef;
|
||||
unless ($stow->{$uid}->{$gid}) {
|
||||
$groupMembers = $session->cache->get("groupMembers".$gid) || {};
|
||||
#If we have this user's membership cached, return what we have stored
|
||||
if (exists $groupMembers->{$uid}) {
|
||||
return $groupMembers->{$uid}->{isMember} if (!$self->isVisitor);
|
||||
return $groupMembers->{$uid}->{$session->getId}->{isMember} #Include the session check for visitors
|
||||
}
|
||||
}
|
||||
|
||||
### Instantiate the group
|
||||
my $group = WebGUI::Group->new($session,$gid);
|
||||
if ( !$group ) {
|
||||
#Group is not valid, check the admin group
|
||||
$group = WebGUI::Group->new($session,3);
|
||||
}
|
||||
|
||||
#Check the group for membership
|
||||
my $isInGroup = $group->hasUser($self);
|
||||
|
||||
#Write what we found to file cache
|
||||
$group->cacheGroupings( $self, $isInGroup, $groupMembers );
|
||||
return $isInGroup;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -686,11 +686,15 @@ sub rollback {
|
|||
my $revision = WebGUI::Asset->newById($session, $id, $revisionDate);
|
||||
next REVISION unless $revision;
|
||||
$outputSub->(sprintf $i18n->get('Rolling back %s'), $revision->getTitle);
|
||||
$revision->purgeRevision;
|
||||
$revision->purgeRevision;
|
||||
}
|
||||
my $instance = $self->getWorkflowInstance;
|
||||
if ($instance) {
|
||||
$instance->delete;
|
||||
}
|
||||
$session->db->write("delete from assetVersionTag where tagId=?", [$tagId]);
|
||||
$self->clearWorking;
|
||||
return 1;
|
||||
$session->db->write("delete from assetVersionTag where tagId=?", [$tagId]);
|
||||
$self->clearWorking;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -113,7 +113,8 @@ sub www_pickStyle {
|
|||
my $f = $self->getForm;
|
||||
my $i18n = WebGUI::International->new( $session, "WebGUI" );
|
||||
|
||||
my $output = '<h1>' . $i18n->get('1073') . '</h1>';
|
||||
my $output = '<h1>' . $i18n->get('pick style') . '</h1>'
|
||||
. '<p>' . $i18n->get('pick style description') . '</p>';
|
||||
|
||||
my @styleIds
|
||||
= $session->db->buildArray(
|
||||
|
|
@ -144,8 +145,9 @@ sub www_pickStyle {
|
|||
my $class = ++$row % 2 ? " odd" : "";
|
||||
|
||||
# Prepare the synopsis
|
||||
my $synopsis = WebGUI::HTML::format( $style->get('synopsis') );
|
||||
my $synopsis = $style->get('synopsis');
|
||||
$synopsis =~ s{(https?://\S+)}{<a href="$1">$1</a>}g;
|
||||
$synopsis = WebGUI::HTML::format( $synopsis );
|
||||
|
||||
$f->raw(
|
||||
'<div class="stylePicker' . $class . '"><label><input type="radio" name="styleTemplateId" value="' . $style->getId . '"/>'
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ h1 {
|
|||
margin: 0;
|
||||
padding-left: 120px;
|
||||
|
||||
background: url(' . $session->url->extras('wg.gif') . ') no-repeat;
|
||||
background: url(' . $session->url->extras('wg.png') . ') no-repeat;
|
||||
line-height: 100px;
|
||||
}
|
||||
|
||||
|
|
@ -399,14 +399,13 @@ sub www_cleanup {
|
|||
$starterForm->hidden( name => "styleTemplateId", value => $self->get('styleTemplateId') );
|
||||
$starterForm->submit( value => $i18n->get( 'yes please' ) );
|
||||
|
||||
my $output = '<h1>' . $i18n->get('site starter title') . '</h1>';
|
||||
$output .= ' <p>' . $i18n->get('site starter body') . '</p>'
|
||||
my $homeForm = WebGUI::HTMLForm->new( $session, { action => $session->url->gateway, method => "GET" } );
|
||||
$homeForm->submit( value => $i18n->get('no thanks') );
|
||||
|
||||
my $output = '<h1>' . $i18n->get('page builder title') . '</h1>';
|
||||
$output .= ' <p>' . $i18n->get('page builder body') . '</p>'
|
||||
. '<div style="float: left">' . $starterForm->print . '</div>'
|
||||
. sprintf(
|
||||
'<div style="float: left"><a href="%s">%s</a></div>',
|
||||
$session->url->gateway,
|
||||
$i18n->get('no thanks'),
|
||||
)
|
||||
. '<div style="float: left">' . $homeForm->print . '</div>'
|
||||
. '<div style="clear: both"> </div>'
|
||||
;
|
||||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ sub execute {
|
|||
while (my $invite = $pending->hashRef) {
|
||||
my $sentOn = WebGUI::DateTime->new($session, $invite->{dateSent});
|
||||
if (DateTime::Duration->compare($now - $sentOn, $outdated) == 1) {
|
||||
WebGUI::Friends->new($session, WebGUI::User->new($session, $invite->{friendId}))->rejectAddRequest($invite->{inviteId});
|
||||
WebGUI::Friends->new($session, WebGUI::User->new($session, $invite->{friendId}))->rejectAddRequest($invite->{inviteId},$session->setting->get("sendRejectNotice"));
|
||||
}
|
||||
if (time() - $start > $ttl) {
|
||||
$pending->finish;
|
||||
|
|
|
|||
|
|
@ -208,7 +208,9 @@ sub execute {
|
|||
# Tag is approved
|
||||
elsif ( $instance->getScratch("status") eq "approved" ) {
|
||||
# Clean up after ourselves
|
||||
$self->setMessageCompleted( $instance );
|
||||
if (! $self->setMessageCompleted( $instance ) ) {
|
||||
return $self->ERROR;
|
||||
}
|
||||
$instance->deleteScratch( "status" );
|
||||
|
||||
# We're done here
|
||||
|
|
@ -278,7 +280,7 @@ sub sendMessage {
|
|||
groupId => $groupId,
|
||||
status => 'pending',
|
||||
});
|
||||
$messageIds = join ",", $messageIds, $message->getId;
|
||||
$messageIds = $messageIds ? join(",", $messageIds, $message->getId) : $message->getId;
|
||||
}
|
||||
|
||||
# Keep track of message Ids so we can complete them
|
||||
|
|
@ -335,23 +337,32 @@ workflow instance we're part of.
|
|||
=cut
|
||||
|
||||
sub setMessageCompleted {
|
||||
my $self = shift;
|
||||
my $instance = shift;
|
||||
my $inbox = WebGUI::Inbox->new( $self->session );
|
||||
my $self = shift;
|
||||
my $instance = shift;
|
||||
my $inbox = WebGUI::Inbox->new( $self->session );
|
||||
|
||||
# Set all messages to completed
|
||||
for my $messageId ( split /,/, $instance->getScratch("messageId") ) {
|
||||
if($messageId){
|
||||
my $message = $inbox->getMessage( $messageId );
|
||||
$message->setCompleted if $message;
|
||||
for my $messageId ( split /,/, $instance->getScratch("messageId") ) {
|
||||
if ($messageId) {
|
||||
my $message = $inbox->getMessage($messageId);
|
||||
if ($message) {
|
||||
$message->setCompleted;
|
||||
}
|
||||
else {
|
||||
$self->session->log->error("Could not get inbox message for messageId: $messageId");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$self->session->log->error("Malformed workflow instance scratch variable messageId for instance: ". $instance->getId);
|
||||
return 0;
|
||||
}
|
||||
} ## end for my $messageId ( split...)
|
||||
|
||||
$instance->deleteScratch( "messageId" );
|
||||
|
||||
return;
|
||||
}
|
||||
$instance->deleteScratch("messageId");
|
||||
|
||||
return 1;
|
||||
} ## end sub setMessageCompleted
|
||||
|
||||
1;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,16 +11,8 @@ our $LANGUAGE = {
|
|||
};
|
||||
|
||||
sub makeUrlCompliant {
|
||||
my $value = shift;
|
||||
$value =~ s/\s+$//; #removes trailing whitespace
|
||||
$value =~ s/^\s+//; #removes leading whitespace
|
||||
$value =~ s/ /-/g; #replaces whitespace with hyphens
|
||||
$value =~ s/\.$//; #removes trailing period
|
||||
$value =~ s/[^\w\-\.\_\/]//g; #removes characters that would interfere with the url
|
||||
$value =~ s/^\///; #removes a leading /
|
||||
$value =~ s/\/$//; #removes a trailing /
|
||||
$value =~ s/\/\//\//g; #removes double /
|
||||
return $value;
|
||||
my $url = shift;
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -431,7 +431,7 @@ our $I18N = {
|
|||
},
|
||||
|
||||
'invitation confirm message' => {
|
||||
message => q{The following users were notified:},
|
||||
message => q{The following actions were taken:},
|
||||
lastUpdated => 1225724810,
|
||||
},
|
||||
|
||||
|
|
@ -818,6 +818,18 @@ our $I18N = {
|
|||
lastUpdated => 1242274703,
|
||||
},
|
||||
|
||||
|
||||
'send reject notice' => {
|
||||
message => q|Send Reject Friend Notifications|,
|
||||
context => q|Site setting. A notification is an email that is sent to the user being rejected.|,
|
||||
lastUpdated => 1242274705,
|
||||
},
|
||||
|
||||
'send reject notice help' => {
|
||||
message => q|Choose whether or not, upon rejecting a friend request, a notification should be sent to the user being rejected.|,
|
||||
lastUpdated => 1242274703,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -320,6 +320,11 @@ our $I18N = {
|
|||
context => q|To remove an item from the clipboard, and put it on the current page.|
|
||||
},
|
||||
|
||||
'Copy Assets' => {
|
||||
message => q|Copy Assets|,
|
||||
lastUpdated => 1273518396,
|
||||
},
|
||||
|
||||
'Paste Assets' => {
|
||||
message => q|Paste Assets|,
|
||||
lastUpdated => 1245342798,
|
||||
|
|
|
|||
|
|
@ -597,6 +597,12 @@ our $I18N = {
|
|||
lastUpdated => 1109696029,
|
||||
},
|
||||
|
||||
'Unsubscribe from %s' => {
|
||||
message => q|Unsubscribe from %s|,
|
||||
lastUpdated => 1274216526,
|
||||
context => q|Label for the unsubscribe form. %s will be filled in with the title of the CS.|,
|
||||
},
|
||||
|
||||
'url' => {
|
||||
message => q|URL|,
|
||||
lastUpdated => 1109696029,
|
||||
|
|
@ -1580,17 +1586,37 @@ the Collaboration Asset, the user will be notified.|,
|
|||
message => q|The assetId of this Collaboration System. Unlike the variable assetId, this one will not be overridden by the assetIds inside of Threads or Posts.|,
|
||||
lastUpdated => 1170543345,
|
||||
},
|
||||
|
||||
|
||||
'subscription group label' => {
|
||||
message => q|Subscription Group|,
|
||||
lastUpdated => 1170543345,
|
||||
},
|
||||
|
||||
|
||||
'subscription group hoverHelp' => {
|
||||
message => q|Manage the users in the subscription group for this Collaboration System|,
|
||||
lastUpdated => 1170543345,
|
||||
},
|
||||
|
||||
'unsubscribe template' => {
|
||||
message => q|Unsubscribe Template|,
|
||||
lastUpdated => 1274208100,
|
||||
},
|
||||
|
||||
'unsubscribe template hoverHelp' => {
|
||||
message => q|Choose a template to help a user, who is not logged in, unsubscribe from either the CS or from a Thread within it.|,
|
||||
lastUpdated => 1274208493,
|
||||
},
|
||||
|
||||
'unsubscribe instructions' => {
|
||||
message => q|Please enter in the email address of the user who wants to unsubscribe|,
|
||||
lastUpdated => 1274208493,
|
||||
},
|
||||
|
||||
'no user email error message' => {
|
||||
message => q|No user with that email can be found.|,
|
||||
lastUpdated => 1274208493,
|
||||
},
|
||||
|
||||
'group to edit label' => {
|
||||
message => q|Group to Edit Posts|,
|
||||
lastUpdated => 1206733328,
|
||||
|
|
@ -1599,7 +1625,7 @@ the Collaboration Asset, the user will be notified.|,
|
|||
message => q|A group that is allowed to edit posts after they have been submitted.|,
|
||||
lastUpdated => 1269283819,
|
||||
},
|
||||
|
||||
|
||||
'use captcha label' => {
|
||||
message => q|Use Post Captcha|,
|
||||
lastUpdated => 1170543345,
|
||||
|
|
@ -1609,7 +1635,7 @@ the Collaboration Asset, the user will be notified.|,
|
|||
message => q|Choose whether or not to make users verify their humnanity before being able to post to this collaboration system|,
|
||||
lastUpdated => 1170543345,
|
||||
},
|
||||
|
||||
|
||||
'captcha label' => {
|
||||
message => q|Verify your humanity|,
|
||||
lastUpdated => 1170543345,
|
||||
|
|
@ -1631,7 +1657,7 @@ the Collaboration Asset, the user will be notified.|,
|
|||
message => q|Keywords|,
|
||||
lastUpdated => 1170543345,
|
||||
},
|
||||
|
||||
|
||||
'asset not committed' => {
|
||||
message => q{<h1>Error!</h1><p>You need to commit this collaboration system before you can create a new thread</p>},
|
||||
lastUpdated => 1166848379,
|
||||
|
|
@ -1683,6 +1709,48 @@ the Collaboration Asset, the user will be notified.|,
|
|||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'unsubscribe formHeader' => {
|
||||
message => q{HTML code to start the unsubscribe form.},
|
||||
context => q{Template variable help},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'unsubscribe formFooter' => {
|
||||
message => q{HTML code to end the unsubscribe form.},
|
||||
context => q{Template variable help},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'unsubscribe formSubmit' => {
|
||||
message => q{A button to submit the form.},
|
||||
context => q{Template variable help},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'unsubscribe formEmail' => {
|
||||
message => q{A text form with email completion.},
|
||||
context => q{Template variable help},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'unsubscribe formMessage' => {
|
||||
message => q{Internationalized messages to tell the user about errors and successes.},
|
||||
context => q{Template variable help},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'You have been unsubscribed' => {
|
||||
message => q{You have been unsubscribed.},
|
||||
context => q{status message},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'collaboration unsubscribe template title' => {
|
||||
message => q{Collaboration System Unsubscribe Template},
|
||||
context => q{status message},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -277,11 +277,21 @@ our $I18N = {
|
|||
message => 'The keywords for the files being uploaded.',
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'helpvar form_location' => {
|
||||
message => 'The location for the files being uploaded.',
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'helpvar form_friendsOnly' => {
|
||||
message => 'Should the file be friends only?',
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'helpvar form_sortBy' => {
|
||||
message => 'Property according to which photos should be sorted.',
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'helpvar url_yes' => {
|
||||
message => 'Confirm the delete of this Album.',
|
||||
|
|
@ -451,13 +461,43 @@ our $I18N = {
|
|||
lastUpdated => 0,
|
||||
context => 'Label for the "keywords" field of the Add Archive page',
|
||||
},
|
||||
|
||||
|
||||
'addArchive location' => {
|
||||
message => 'Location',
|
||||
lastUpdated => 0,
|
||||
context => 'Label for the "location" field of the Add Archive page',
|
||||
},
|
||||
|
||||
'addArchive friendsOnly' => {
|
||||
message => 'Friends Only',
|
||||
lastUpdated => 0,
|
||||
context => 'Label for the "friends only" field of the Add Archive page',
|
||||
context => 'Label for the "friendsOnly" field of the Add Archive page',
|
||||
},
|
||||
|
||||
'addArchive sortBy' => {
|
||||
message => 'Sort By',
|
||||
lastUpdated => 0,
|
||||
context => 'Label for the "sortBy" field of the Add Archive page',
|
||||
},
|
||||
|
||||
'addArchive sortBy name' => {
|
||||
message => 'Name',
|
||||
lastUpdated => 0,
|
||||
context => 'Label for the "Name" radio button',
|
||||
},
|
||||
|
||||
'addArchive sortBy date' => {
|
||||
message => 'Date',
|
||||
lastUpdated => 0,
|
||||
context => 'Label for the "Date" radio button',
|
||||
},
|
||||
|
||||
'addArchive sortBy fileOrder' => {
|
||||
message => 'File Order',
|
||||
lastUpdated => 0,
|
||||
context => 'Label for the "File Order" radio button',
|
||||
},
|
||||
|
||||
'template addArchive title' => {
|
||||
message => "Add Zip Archive",
|
||||
lastUpdated => 0,
|
||||
|
|
|
|||
|
|
@ -245,11 +245,33 @@ our $I18N = {
|
|||
},
|
||||
|
||||
'sortItemsLabel' => {
|
||||
message => q{Sort feed items by date?},
|
||||
message => q{Sort items by},
|
||||
},
|
||||
|
||||
'sortItemsLabel description' => {
|
||||
message => q{If enabled, items will be sorted by date. If disabled, items will be left in the order they appear in the original feed.},
|
||||
message => q{No order: items will be in semi-random order<br />
|
||||
Publication Date: sort by item pubDate<br />
|
||||
Feed Order: Items will be in the order they appeared in the feed}
|
||||
},
|
||||
|
||||
'no order' => {
|
||||
message => 'No Order',
|
||||
context => 'name for the sortItems value that indicates that no sorting should be done '
|
||||
},
|
||||
|
||||
'feed order' => {
|
||||
message => 'Feed Order',
|
||||
context => 'name for the sortItems value that indicates items should be in the order they appeared in the feed'
|
||||
},
|
||||
|
||||
'publication date ascending' => {
|
||||
message => 'Publication Date (oldest first)',
|
||||
context => 'name for the sortItems value that indicates items should be sorted by publication date from oldest to newest'
|
||||
},
|
||||
|
||||
'publication date descending' => {
|
||||
message => 'Publication Date (newest first)',
|
||||
context => 'name for the sortItems value that indicates items should be sorted by publication date from newest to oldest'
|
||||
},
|
||||
|
||||
'syndicated content asset template variables title' => {
|
||||
|
|
|
|||
|
|
@ -656,6 +656,12 @@ listing of pages that are related to a specific keyword?| },
|
|||
context => q{template variable help},
|
||||
},
|
||||
|
||||
'Sub-keywords' => {
|
||||
message => q{Sub-keywords},
|
||||
lastUpdated => 0,
|
||||
context => q{template label},
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -59,17 +59,6 @@ our $I18N = {
|
|||
context => q|Hover help for the summary template field in the configuration form of the Cash module.|
|
||||
},
|
||||
|
||||
'password' => {
|
||||
message => q|Password|,
|
||||
lastUpdated => 0,
|
||||
context => q|Form label in the configuration form of the iTransact module.|
|
||||
},
|
||||
'password help' => {
|
||||
message => q|The password for your ITransact account.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Hover help for the password field in the configuration form of the iTransact module.|
|
||||
},
|
||||
|
||||
'Pay' => {
|
||||
message => q|Pay|,
|
||||
lastUpdated => 0,
|
||||
|
|
|
|||
|
|
@ -567,6 +567,12 @@ our $I18N = {
|
|||
context => q|field label|
|
||||
},
|
||||
|
||||
'current credit message' => {
|
||||
message => q|%s has a total credit of %s.|,
|
||||
lastUpdated => 0,
|
||||
context => q|field label|
|
||||
},
|
||||
|
||||
'amount' => {
|
||||
message => q|Amount|,
|
||||
lastUpdated => 1213632324,
|
||||
|
|
@ -1695,6 +1701,12 @@ our $I18N = {
|
|||
context => q|Label to make the user choose a shipping method|,
|
||||
},
|
||||
|
||||
'Choose a payment gateway and update the cart to checkout' => {
|
||||
message => q|Choose a payment gateway and update the cart to checkout|,
|
||||
lastUpdated => 0,
|
||||
context => q|Label to make the user choose a payment gateway|,
|
||||
},
|
||||
|
||||
'receipt email template' => {
|
||||
message => q|Receipt Email Template|,
|
||||
lastUpdated => 0,
|
||||
|
|
@ -1755,10 +1767,10 @@ our $I18N = {
|
|||
context => q|form label for the cart. Allows user to build a new address.|
|
||||
},
|
||||
|
||||
'Update this address' => {
|
||||
message => q|Update this address|,
|
||||
'Update %s' => {
|
||||
message => q|Update address: %s|,
|
||||
lastUpdated => 0,
|
||||
context => q|form label for the cart. Allows user to build a new address.|
|
||||
context => q|form label for the cart. Allows user to edit an existing address. %s will be replaced by the label for the currently selected address, if there is one.|
|
||||
},
|
||||
|
||||
'Choose a payment method' => {
|
||||
|
|
@ -1773,6 +1785,126 @@ our $I18N = {
|
|||
context => q|form label for the cart. Allows user to choose a payment method. Bart Jol for Minister in 2012!|
|
||||
},
|
||||
|
||||
'no billing address' => {
|
||||
message => q|Please enter a billing address, or select an existing one.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'no shipping address' => {
|
||||
message => q|Please enter a shipping address, or select an existing one.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'billing label' => {
|
||||
message => q|Please enter a label for the billing address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'billing firstName' => {
|
||||
message => q|Please enter a first name for the billing address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'billing lastName' => {
|
||||
message => q|Please enter a last name for the billing address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'billing address1' => {
|
||||
message => q|Please enter a street address for the billing address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'billing city' => {
|
||||
message => q|Please enter a city for the billing address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'billing code' => {
|
||||
message => q|Please enter a postal code for the billing address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'billing state' => {
|
||||
message => q|Please enter a state or province for the billing address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'billing country' => {
|
||||
message => q|Please enter a country for the billing address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'billing phoneNumber' => {
|
||||
message => q|Please enter a phone number for the billing address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'shipping label' => {
|
||||
message => q|Please enter a label for the shipping address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'shipping firstName' => {
|
||||
message => q|Please enter a first name for the shipping address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'shipping lastName' => {
|
||||
message => q|Please enter a last name for the shipping address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'shipping address1' => {
|
||||
message => q|Please enter a street address for the shipping address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'shipping city' => {
|
||||
message => q|Please enter a city for the shipping address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'shipping code' => {
|
||||
message => q|Please enter a postal code for the shipping address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'shipping state' => {
|
||||
message => q|Please enter a state or province for the shipping address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'shipping country' => {
|
||||
message => q|Please enter a country for the shipping address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
'shipping phoneNumber' => {
|
||||
message => q|Please enter a phone number for the shipping address.|,
|
||||
lastUpdated => 0,
|
||||
context => q|Cart error message|
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -4237,14 +4237,14 @@ LongTruncOk=1</p>
|
|||
context => q{Description for site setting},
|
||||
},
|
||||
|
||||
'site starter title' => {
|
||||
message => q{Site Starter},
|
||||
'page builder title' => {
|
||||
message => q{Page Builder},
|
||||
lastUpdated => 0,
|
||||
context => q{Title for the site starter screen.},
|
||||
context => q{Title for the page builder screen.},
|
||||
},
|
||||
|
||||
'site starter body' => {
|
||||
message => q{Do you wish to use the WebGUI Site Starter, which will lead you through options to create a custom look and feel for your site, and set up some basic content areas?},
|
||||
'page builder body' => {
|
||||
message => q{Would you like to use the Page Builder to select a default set of pages to include on your site, such as an About Us page or discussion forum.},
|
||||
lastUpdated => 0,
|
||||
context => q{Body for the site starter screen.},
|
||||
},
|
||||
|
|
@ -4686,6 +4686,18 @@ Users may override this setting in their profile.
|
|||
context => 'Label for buttons that take you someplace else'
|
||||
},
|
||||
|
||||
'pick style' => {
|
||||
message => 'Choose a Design',
|
||||
lastUpdated => 0,
|
||||
context => 'Header for the pick style template page',
|
||||
},
|
||||
|
||||
'pick style description' => {
|
||||
message => 'Select a design to apply to your site. All designs are created from templates that you will have access to from your site, so modifications can be made later.',
|
||||
lastUpdate => 0,
|
||||
context => 'Description for pick style template page',
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ my $session = WebGUI::Test->session;
|
|||
|
||||
my @getTitleTests = getTitleTests($session);
|
||||
|
||||
plan tests => 120
|
||||
plan tests => 121
|
||||
+ 2*scalar(@getTitleTests) #same tests used for getTitle and getMenuTitle
|
||||
;
|
||||
|
||||
|
|
@ -300,6 +300,7 @@ $session->setting->set('urlExtension', undef);
|
|||
|
||||
is($importNode->fixUrl('1234'.'_'x235 . 'abcdefghij'), '1234'.'_'x235 . 'abcdefghij', 'fixUrl leaves long URLs under 250 characters alone');
|
||||
is($importNode->fixUrl('1234'.'_'x250 . 'abcdefghij'), '1234'.'_'x216, 'fixUrl truncates long URLs over 250 characters to 220 characters');
|
||||
is $importNode->fixUrl('---'), '-', '... 3 dashes are collapsed down to a single dash';
|
||||
|
||||
$session->config->set('extrasURL', '/extras');
|
||||
$session->config->set('uploadsURL', '/uploads');
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ use WebGUI::Asset;
|
|||
use WebGUI::VersionTag;
|
||||
|
||||
use Test::More; # increment this value for each test you create
|
||||
plan tests => 12;
|
||||
plan tests => 27;
|
||||
|
||||
my $session = WebGUI::Test->session;
|
||||
$session->user({userId => 3});
|
||||
|
|
@ -95,9 +95,66 @@ WebGUI::Test->addToCleanup($newVersionTag);
|
|||
####################################################
|
||||
|
||||
note "cut";
|
||||
is($topFolder->cut, 1, 'returns 1 if successful' );
|
||||
is($topFolder->state, 'clipboard', '... state set to trash on the trashed asset object');
|
||||
is($topFolder->cloneFromDb->state, 'clipboard', '... state set to trash in db on object');
|
||||
is($folder1a->cloneFromDb->state, 'clipboard-limbo', '... state set to clipboard-limbo on child #1');
|
||||
is($folder1b->cloneFromDb->state, 'clipboard-limbo', '... state set to clipboard-limbo on child #2');
|
||||
is($folder1a2->cloneFromDb->state, 'clipboard-limbo', '... state set to clipboard-limbo on grandchild #1-1');
|
||||
|
||||
is( $topFolder->cut, 1, 'cut: returns 1 if successful' );
|
||||
is($topFolder->get('state'), 'clipboard', '... state set to trash on the trashed asset object');
|
||||
is($topFolder->cloneFromDb->get('state'), 'clipboard', '... state set to trash in db on object');
|
||||
is($folder1a->cloneFromDb->get('state'), 'clipboard-limbo', '... state set to clipboard-limbo on child #1');
|
||||
is($folder1b->cloneFromDb->get('state'), 'clipboard-limbo', '... state set to clipboard-limbo on child #2');
|
||||
is($folder1a2->cloneFromDb->get('state'), 'clipboard-limbo', '... state set to clipboard-limbo on grandchild #1-1');
|
||||
|
||||
sub is_tree_of_folders {
|
||||
my ($asset, $depth, $pfx) = @_;
|
||||
my $recursive; $recursive = sub {
|
||||
my ($asset, $depth) = @_;
|
||||
my $pfx = " $pfx $depth";
|
||||
return 0 unless isa_ok($asset, 'WebGUI::Asset::Wobject::Folder',
|
||||
"$pfx: this object");
|
||||
|
||||
my $children = $asset->getLineage(
|
||||
['children'], {
|
||||
statesToInclude => ['clipboard', 'clipboard-limbo' ],
|
||||
returnObjects => 1,
|
||||
}
|
||||
);
|
||||
|
||||
return $depth < 2
|
||||
? is(@$children, 0, "$pfx: leaf childless")
|
||||
: is(@$children, 1, "$pfx: has child")
|
||||
&& $recursive->($children->[0], $depth - 1);
|
||||
};
|
||||
|
||||
my $pass = $recursive->($asset, $depth);
|
||||
undef $recursive;
|
||||
my $message = "$pfx is tree of folders";
|
||||
return $pass ? pass $message : fail $message;
|
||||
}
|
||||
|
||||
# test www_copy
|
||||
my $tag = WebGUI::VersionTag->create($session);
|
||||
$tag->setWorking;
|
||||
WebGUI::Test->addToCleanup($tag);
|
||||
|
||||
my $tempspace = WebGUI::Asset->getTempspace($session);
|
||||
my $folder = {className => 'WebGUI::Asset::Wobject::Folder'};
|
||||
my $root = $tempspace->addChild($folder);
|
||||
my $child = $root->addChild($folder);
|
||||
my $grandchild = $child->addChild($folder);
|
||||
|
||||
sub copied {
|
||||
for my $a (@{$tempspace->getAssetsInClipboard}) {
|
||||
if ($a->getParent->getId eq $tempspace->getId) {
|
||||
return $a;
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
my @methods = qw(Single Children Descendants);
|
||||
for my $i (0..2) {
|
||||
my $meth = "_wwwCopy$methods[$i]";
|
||||
$root->$meth();
|
||||
my $clip = copied();
|
||||
is_tree_of_folders($clip, $i+1, $meth);
|
||||
$clip->purge;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,10 @@ use Test::Deep;
|
|||
my $session = WebGUI::Test->session;
|
||||
my $node = WebGUI::Asset->getImportNode($session);
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Album Test"});
|
||||
|
||||
$versionTag->set({name=>"Add Archive to Album Test"});
|
||||
addToCleanup($versionTag);
|
||||
|
||||
my $gallery
|
||||
= $node->addChild({
|
||||
className => "WebGUI::Asset::Wobject::Gallery",
|
||||
|
|
@ -35,6 +38,7 @@ my $gallery
|
|||
groupIdEdit => 3, # Admins
|
||||
ownerUserId => 3, # Admin
|
||||
});
|
||||
|
||||
my $album
|
||||
= $gallery->addChild({
|
||||
className => "WebGUI::Asset::Wobject::GalleryAlbum",
|
||||
|
|
@ -46,48 +50,128 @@ my $album
|
|||
skipAutoCommitWorkflows => 1,
|
||||
});
|
||||
|
||||
$album->addArchive( WebGUI::Test->getTestCollateralPath('elephant_images.zip') );
|
||||
# Properties applied to every photo in the archive
|
||||
my $properties = {
|
||||
keywords => "something",
|
||||
location => "somewhere",
|
||||
friendsOnly => "1",
|
||||
};
|
||||
|
||||
$versionTag->commit;
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
plan tests => 5;
|
||||
plan tests => 11;
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Test the addArchive sub
|
||||
# elephant_images.zip contains three jpgs: Aana1.jpg, Aana2.jpg, Aana3.jpg
|
||||
|
||||
$versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$album->addArchive( WebGUI::Test->getTestCollateralPath('elephant_images.zip'), $properties );
|
||||
|
||||
my $images = $album->getLineage(['descendants'], { returnObjects => 1 });
|
||||
|
||||
is( scalar @$images, 3, "addArchive() adds one asset per image" );
|
||||
cmp_deeply(
|
||||
cmp_bag(
|
||||
[ map { $_->get("filename") } @$images ],
|
||||
bag( "Aana1.jpg", "Aana2.jpg", "Aana3.jpg" ),
|
||||
[ "Aana1.jpg", "Aana2.jpg", "Aana3.jpg" ],
|
||||
"Names of files attached to Photo assets match filenames in archive"
|
||||
);
|
||||
|
||||
cmp_deeply(
|
||||
cmp_bag(
|
||||
[ map { $_->get("title") } @$images ],
|
||||
bag( "Aana1", "Aana2", "Aana3" ),
|
||||
[ "Aana1", "Aana2", "Aana3" ],
|
||||
"Titles of Photo assets match filenames in archive excluding extensions"
|
||||
);
|
||||
|
||||
cmp_deeply(
|
||||
cmp_bag(
|
||||
[ map { $_->get("menuTitle") } @$images ],
|
||||
bag( "Aana1", "Aana2", "Aana3" ),
|
||||
[ "Aana1", "Aana2", "Aana3" ],
|
||||
"Menu titles of Photo assets match filenames in archive excluding extensions"
|
||||
);
|
||||
|
||||
cmp_deeply(
|
||||
cmp_bag(
|
||||
[ map { $_->get("url") } @$images ],
|
||||
bag(
|
||||
[
|
||||
$session->url->urlize( $album->getUrl . "/Aana1" ),
|
||||
$session->url->urlize( $album->getUrl . "/Aana2" ),
|
||||
$session->url->urlize( $album->getUrl . "/Aana3" ),
|
||||
),
|
||||
],
|
||||
"URLs of Photo assets match filenames in archive excluding extensions"
|
||||
);
|
||||
|
||||
cmp_bag(
|
||||
[ map { $_->get("keywords") } @$images ],
|
||||
[ "something", "something", "something" ],
|
||||
"Keywords of Photo assets match keywords in properties"
|
||||
);
|
||||
|
||||
cmp_bag(
|
||||
[ map { $_->get("location") } @$images ],
|
||||
[ "somewhere", "somewhere", "somewhere" ],
|
||||
"Location of Photo assets match keywords in properties"
|
||||
);
|
||||
|
||||
cmp_bag(
|
||||
[ map { $_->get("friendsOnly") } @$images ],
|
||||
[ "1", "1", "1" ],
|
||||
"Photo assets are viewable by friends only"
|
||||
);
|
||||
|
||||
# Empty gallery album
|
||||
$versionTag->rollback;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Test the sorting option of addArchive sub
|
||||
# gallery_archive_sorting_test.zip contains four jpgs: photo1.jpg, photo2.jpg, photo3.jpg and photo4.jpg
|
||||
# The following test covers sorting by date and name. Testing fileOrder is not possible, because
|
||||
# it's machine dependent.
|
||||
|
||||
$versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
# Add photos sorted by file order (default)
|
||||
$album->addArchive( WebGUI::Test->getTestCollateralPath('gallery_archive_sorting_test.zip'), $properties, 'fileOrder' );
|
||||
# Get all children
|
||||
my $images = $album->getLineage(['descendants'], { returnObjects => 1 });
|
||||
# Check order
|
||||
cmp_bag(
|
||||
[ map { $_->get("filename") } @{ $images } ],
|
||||
[ "photo1.jpg", "photo4.jpg", "photo3.jpg", "photo2.jpg", ],
|
||||
"Photos sorted by file order (all files exist)"
|
||||
);
|
||||
# Empty gallery album
|
||||
$versionTag->rollback;
|
||||
|
||||
$versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
# Add photos sorted by date
|
||||
$album->addArchive( WebGUI::Test->getTestCollateralPath('gallery_archive_sorting_test.zip'), $properties, 'date' );
|
||||
# Get all children
|
||||
my $images = $album->getLineage(['descendants'], { returnObjects => 1 });
|
||||
# Check order
|
||||
cmp_deeply(
|
||||
[ map { $_->get("filename") } @$images ],
|
||||
[ "photo4.jpg", "photo1.jpg", "photo3.jpg", "photo2.jpg" ],
|
||||
"Photos sorted by date"
|
||||
);
|
||||
# Empty gallery album
|
||||
$versionTag->rollback;
|
||||
|
||||
$versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
# Add photos sorted by name
|
||||
$album->addArchive( WebGUI::Test->getTestCollateralPath('gallery_archive_sorting_test.zip'), $properties, 'name' );
|
||||
# Get all children
|
||||
my $images = $album->getLineage(['descendants'], { returnObjects => 1 });
|
||||
# Check order
|
||||
cmp_deeply(
|
||||
[ map { $_->get("filename") } @$images ],
|
||||
[ "photo1.jpg", "photo2.jpg", "photo3.jpg", "photo4.jpg" ],
|
||||
"Photos sorted by name"
|
||||
);
|
||||
# Empty gallery album
|
||||
$versionTag->rollback;
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Test the www_addArchive page
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Cleanup
|
||||
END {
|
||||
$versionTag->rollback;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ $session->user({userId => 1});
|
|||
cmp_deeply(
|
||||
$templateVars,
|
||||
{
|
||||
canPostStories => 0,
|
||||
canPostStories => bool(0),
|
||||
mode => 'view',
|
||||
addStoryUrl => '',
|
||||
date_loop => [
|
||||
|
|
@ -411,9 +411,6 @@ $archive->update({storiesPerPage => 25});
|
|||
$templateVars = $archive->viewTemplateVariables('search');
|
||||
is($templateVars->{mode}, 'search', 'viewTemplateVariables mode == search');
|
||||
|
||||
use Data::Dumper;
|
||||
diag Dumper $templateVars->{date_loop};
|
||||
|
||||
cmp_bag(
|
||||
$templateVars->{date_loop},
|
||||
[
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use Data::Dumper;
|
|||
|
||||
use WebGUI::Test;
|
||||
use WebGUI::Session;
|
||||
use Test::More tests => 22; # increment this value for each test you create
|
||||
use Test::More tests => 27; # increment this value for each test you create
|
||||
use Test::Deep;
|
||||
use WebGUI::Asset::Wobject::SyndicatedContent;
|
||||
use XML::FeedPP;
|
||||
|
|
@ -113,7 +113,7 @@ ok($processed_template, "A response was received from processTemplate.");
|
|||
#
|
||||
####################################################################
|
||||
|
||||
##Construct a feed with no description, so the resulting template variables can
|
||||
##Construct a feed with no description so the resulting template variables can
|
||||
##be checked for an undef description
|
||||
my $feed = XML::FeedPP->new(<<EOFEED);
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
|
@ -140,37 +140,82 @@ EOFEED
|
|||
my $vars = $syndicated_content->getTemplateVariables($feed);
|
||||
ok( defined $vars->{item_loop}->[0]->{description}, 'getTemplateVariables: description is not undefined');
|
||||
|
||||
##Construct a feed with a wrapped description, to check for paragraph handling.
|
||||
$feed = XML::FeedPP->new(<<EOFEED);
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>The WebGUI buglist</title>
|
||||
<link>/tbb</link>
|
||||
<copyright /><pubDate>Mon, 12 Oct 2009 11:54:28 -0500</pubDate>
|
||||
<description />
|
||||
<item>
|
||||
<title>Description with wrapped HTML paragraphs</title>
|
||||
<link>http://www.webgui.org/use/bugs/tracker/11563</link>
|
||||
<author>serif</author>
|
||||
<epochDate>1254854387</epochDate>
|
||||
<guid isPermaLink="true">http://www.webgui.org/use/bugs/tracker/11563</guid>
|
||||
<pubDate>Mon, 14 May 2010 8:12:00 -0500</pubDate>
|
||||
<description>
|
||||
<p>In the attached feed, there is a hidden return line character from the
|
||||
Rich Text editor in the first sentence of the description. When using a Syndicated Content
|
||||
for the feed, the variable descriptionFirstParagraph variable cuts off at this return line
|
||||
character, creating invalid markup.</p>
|
||||
<p>No more text is shown of the first paragraph beyond the bold characters of the first line.</p>
|
||||
<p>Third paragraph, for completeness.</p>
|
||||
</description>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
EOFEED
|
||||
|
||||
$vars = $syndicated_content->getTemplateVariables($feed);
|
||||
is $vars->{item_loop}->[0]->{descriptionFirstParagraph},
|
||||
"<p>In the attached feed, there is a hidden return line character from the Rich Text editor in the first sentence of the description. When using a Syndicated Content for the feed, the variable descriptionFirstParagraph variable cuts off at this return line character, creating invalid markup.</p>",
|
||||
'... first paragraph, when HTML is used';
|
||||
is $vars->{item_loop}->[0]->{descriptionFirst2paragraphs},
|
||||
"<p>In the attached feed, there is a hidden return line character from the Rich Text editor in the first sentence of the description. When using a Syndicated Content for the feed, the variable descriptionFirstParagraph variable cuts off at this return line character, creating invalid markup.</p><p>No more text is shown of the first paragraph beyond the bold characters of the first line.</p>",
|
||||
'... first paragraph, when HTML is used';
|
||||
|
||||
####################################################################
|
||||
#
|
||||
# generateFeed, hasTerms
|
||||
#
|
||||
####################################################################
|
||||
|
||||
my $tbbUrl = 'http://www.plainblack.com/tbb.rss';
|
||||
$syndicated_content->update({
|
||||
rssUrl => $tbbUrl,
|
||||
hasTerms => 'WebGUI',
|
||||
});
|
||||
sub withCachedFeed {
|
||||
my ($url, $path, $block) = @_;
|
||||
$syndicated_content->update({ rssUrl => $url });
|
||||
|
||||
open my $rssFile, '<', WebGUI::Test->getTestCollateralPath('tbb.rss')
|
||||
or die "Unable to get RSS file";
|
||||
my $rssContent = do { local $/; <$rssFile>; };
|
||||
close $rssFile;
|
||||
$session->cache->set($tbbUrl, $rssContent, 60);
|
||||
open my $file, '<', WebGUI::Test->getTestCollateralPath($path)
|
||||
or die "Unable to get RSS file: $path";
|
||||
my $content = do { local $/; <$file> };
|
||||
close $file;
|
||||
|
||||
my $filteredFeed = $syndicated_content->generateFeed();
|
||||
$session->cache->set($url, $content, 60);
|
||||
$block->();
|
||||
$session->cache->remove($url);
|
||||
}
|
||||
|
||||
cmp_deeply(
|
||||
[ map { $_->title } $filteredFeed->get_item() ],
|
||||
[
|
||||
'Google Picasa Plugin for WebGUI Gallery',
|
||||
'WebGUI Roadmap',
|
||||
'WebGUI 8 Performance',
|
||||
],
|
||||
'generateFeed: filters items based on the terms being in title, or description'
|
||||
);
|
||||
sub titles_are {
|
||||
my ($expected, $message) = @_;
|
||||
my $feed = $syndicated_content->generateFeed;
|
||||
my @got = map { $_->title } $feed->get_item;
|
||||
cmp_deeply \@got, $expected, $message;
|
||||
}
|
||||
|
||||
$session->cache->remove($tbbUrl);
|
||||
$syndicated_content->update({ hasTerms => 'WebGUI' });
|
||||
|
||||
withCachedFeed 'http://www.plainblack.com/tbb.rss', 'tbb.rss', sub {
|
||||
titles_are(
|
||||
[
|
||||
'Google Picasa Plugin for WebGUI Gallery',
|
||||
'WebGUI Roadmap',
|
||||
'WebGUI 8 Performance',
|
||||
],
|
||||
'generateFeed: filters items based on the terms being in title, or description'
|
||||
);
|
||||
};
|
||||
|
||||
####################################################################
|
||||
#
|
||||
|
|
@ -178,25 +223,46 @@ $session->cache->remove($tbbUrl);
|
|||
#
|
||||
####################################################################
|
||||
|
||||
|
||||
##Feed with no links or pubDates.
|
||||
my $oncpUrl = 'http://www.oncp.gob.ve/oncp.xml';
|
||||
$syndicated_content->update({
|
||||
rssUrl => $oncpUrl,
|
||||
hasTerms => '',
|
||||
maxHeadlines => 50,
|
||||
});
|
||||
|
||||
open my $rssFile, '<', WebGUI::Test->getTestCollateralPath('oncp.xml')
|
||||
or die "Unable to get RSS file: oncp.xml";
|
||||
my $rssContent = do { local $/; <$rssFile>; };
|
||||
close $rssFile;
|
||||
$session->cache->set($oncpUrl, $rssContent, 60);
|
||||
withCachedFeed 'http://www.oncp.gob.ve/oncp.xml', 'oncp.xml', sub {
|
||||
my $oddFeed1 = $syndicated_content->generateFeed();
|
||||
|
||||
my $oddFeed1 = $syndicated_content->generateFeed();
|
||||
my @oddItems = $oddFeed1->get_item();
|
||||
is (@oddItems, 13, 'feed has items even without pubDates or links');
|
||||
};
|
||||
|
||||
my @oddItems = $oddFeed1->get_item();
|
||||
is (@oddItems, 13, 'feed has items even without pubDates or links');
|
||||
####################################################################
|
||||
#
|
||||
# sorting
|
||||
#
|
||||
####################################################################
|
||||
|
||||
$session->cache->remove($oncpUrl);
|
||||
withCachedFeed 'http://www.plainblack.com/tbb.rss', 'tbb_odd.rss', sub {
|
||||
my @ascending = (
|
||||
'I have arrived in Lisboa!',
|
||||
'WebGUI 8 Performance',
|
||||
'WebGUI Roadmap',
|
||||
'Google Picasa Plugin for WebGUI Gallery',
|
||||
);
|
||||
my @descending = reverse @ascending;
|
||||
my @feed = (
|
||||
'WebGUI Roadmap',
|
||||
'Google Picasa Plugin for WebGUI Gallery',
|
||||
'I have arrived in Lisboa!',
|
||||
'WebGUI 8 Performance',
|
||||
);
|
||||
|
||||
$syndicated_content->update({ sortItems => 'pubDate_asc' });
|
||||
titles_are \@ascending, 'ascending sort';
|
||||
|
||||
$syndicated_content->update({ sortItems => 'pubDate_des' });
|
||||
titles_are \@descending, 'descending sort';
|
||||
|
||||
$syndicated_content->update({ sortItems => 'feed' });
|
||||
titles_are \@feed, 'feed order';
|
||||
};
|
||||
|
|
|
|||
174
t/Group.t
174
t/Group.t
|
|
@ -73,8 +73,26 @@ my @ipTests = (
|
|||
},
|
||||
);
|
||||
|
||||
my @ldapTests = (
|
||||
{
|
||||
dn => 'uid=Byron Hadley,o=shawshank',
|
||||
comment => 'bad dn for group',
|
||||
expect => 0,
|
||||
},
|
||||
{
|
||||
dn => 'uid=Andy Dufresne,o=shawshank',
|
||||
comment => 'good dn for group',
|
||||
expect => 1,
|
||||
},
|
||||
{
|
||||
dn => 'uid=Bogs Diamond,o=shawshank',
|
||||
comment => 'another good dn for group',
|
||||
expect => 1,
|
||||
},
|
||||
);
|
||||
|
||||
plan tests => (151 + scalar(@scratchTests) + scalar(@ipTests)); # increment this value for each test you create
|
||||
|
||||
plan tests => (164 + (scalar(@scratchTests) * 2) + scalar(@ipTests)); # increment this value for each test you create
|
||||
|
||||
my $session = WebGUI::Test->session;
|
||||
$session->cache->remove('myTestKey');
|
||||
|
|
@ -165,16 +183,44 @@ $optionGroup->delete;
|
|||
#
|
||||
################################################################
|
||||
|
||||
my $ldapProps = WebGUI::Test->getSmokeLDAPProps();
|
||||
$session->db->setRow('ldapLink', 'ldapLinkId', $ldapProps, $ldapProps->{ldapLinkId});
|
||||
my $ldap = WebGUI::LDAPLink->new($session, $ldapProps->{ldapLinkId});
|
||||
is($ldap->getValue("ldapLinkId"),$ldapProps->{ldapLinkId},'ldap link created properly');
|
||||
addToCleanup($ldap);
|
||||
|
||||
my @shawshank;
|
||||
|
||||
foreach my $idx (0..$#ldapTests) {
|
||||
$shawshank[$idx] = WebGUI::User->new($session, "new");
|
||||
$shawshank[$idx]->username("shawshank$idx");
|
||||
$shawshank[$idx]->authMethod("LDAP");
|
||||
my $auth = $shawshank[$idx]->authInstance;
|
||||
$auth->saveParams($shawshank[$idx]->getId,$shawshank[$idx]->authMethod,{
|
||||
connectDN => $ldapTests[$idx]->{dn},
|
||||
ldapConnection => $ldap->getValue("ldapLinkId"),
|
||||
ldapUrl => $ldap->getValue("ldapUrl"),
|
||||
});
|
||||
}
|
||||
|
||||
WebGUI::Test->usersToDelete(@shawshank);
|
||||
|
||||
my $lGroup = WebGUI::Group->new($session, 'new');
|
||||
|
||||
$lGroup->ldapGroup('LDAP group');
|
||||
is($lGroup->ldapGroup(), 'LDAP group', 'ldapGroup set and fetched correctly');
|
||||
$lGroup->ldapGroup('cn=Convicts,o=shawshank');
|
||||
is($lGroup->ldapGroup(), 'cn=Convicts,o=shawshank', 'ldapGroup set and fetched correctly');
|
||||
|
||||
$lGroup->ldapGroupProperty('LDAP group property');
|
||||
is($lGroup->ldapGroupProperty(), 'LDAP group property', 'ldapGroup set and fetched correctly');
|
||||
$lGroup->ldapGroupProperty('member');
|
||||
is($lGroup->ldapGroupProperty(), 'member', 'ldapGroup set and fetched correctly');
|
||||
|
||||
$lGroup->ldapLinkId('LDAP link id');
|
||||
is($lGroup->ldapLinkId(), 'LDAP link id', 'ldapLinkId set and fetched correctly');
|
||||
$lGroup->ldapLinkId($ldapProps->{ldapLinkId});
|
||||
is($lGroup->ldapLinkId(),$ldapProps->{ldapLinkId}, 'ldapLinkId set and fetched correctly');
|
||||
|
||||
is_deeply(
|
||||
[ (map { $lGroup->hasLDAPUser($_->getId) } @shawshank) ],
|
||||
[0, 1, 1],
|
||||
'shawshank user 2, and 3 found in lGroup users from LDAP'
|
||||
);
|
||||
|
||||
$lGroup->ldapRecursiveProperty('LDAP recursive property');
|
||||
is($lGroup->ldapRecursiveProperty(), 'LDAP recursive property', 'ldapRecursiveProperty set and fetched correctly');
|
||||
|
|
@ -240,6 +286,7 @@ cmp_bag($gB->getGroupsIn(), [$gA->getId, 3], 'Group A is in Group B');
|
|||
cmp_bag($gA->getGroupsFor(), [$gB->getId], 'Group B contains Group A');
|
||||
cmp_bag($gA->getGroupsIn(), [3], 'Admin added to group A automatically');
|
||||
|
||||
diag $gA->getId;
|
||||
$gA->addGroups([$gB->getId]);
|
||||
cmp_bag($gA->getGroupsIn(), [3], 'Not allowed to create recursive group loops');
|
||||
|
||||
|
|
@ -414,7 +461,7 @@ cmp_ok($expirationDate-time(), '>', 50, 'checking expire offset override on addU
|
|||
|
||||
################################################################
|
||||
#
|
||||
# getDatabaseUsers
|
||||
# getDatabaseUsers & hasDatabaseUsers
|
||||
#
|
||||
################################################################
|
||||
|
||||
|
|
@ -435,7 +482,16 @@ cmp_bag($mobUsers, [map {$_->userId} @mob], 'verify SQL table built correctly');
|
|||
is( $gY->databaseLinkId, 0, "Group Y's databaseLinkId is set to WebGUI");
|
||||
$gY->dbQuery(q!select userId from myUserTable!);
|
||||
is( $session->stow->get('isInGroup'), undef, 'setting dbQuery clears cached isInGroup');
|
||||
$session->cache->remove($gZ->getId);
|
||||
|
||||
is( $mob[0]->isInGroup($gY->getId), 1, 'mob[0] is in group Y after setting dbQuery');
|
||||
is( $mob[0]->isInGroup($gZ->getId), 1, 'mob[0] isInGroup Z');
|
||||
|
||||
ok( isIn($mob[0]->userId, @{ $gY->getAllUsers() }), 'mob[0] in list of group Y users');
|
||||
ok( !isIn($mob[0]->userId, @{ $gZ->getUsers() }), 'mob[0] not in list of group Z users');
|
||||
|
||||
ok( isIn($mob[0]->userId, @{ $gZ->getAllUsers() }), 'mob[0] in list of group Z users, recursively');
|
||||
|
||||
$gY->clearCaches;
|
||||
|
||||
my @mobIds = map { $_->userId } @mob;
|
||||
|
||||
|
|
@ -445,13 +501,17 @@ cmp_bag(
|
|||
'all mob users in list of group Y users from database'
|
||||
);
|
||||
|
||||
is( $mob[0]->isInGroup($gY->getId), 1, 'mob[0] is in group Y after setting dbQuery');
|
||||
is( $mob[0]->isInGroup($gZ->getId), 1, 'mob[0] isInGroup Z');
|
||||
$session->db->write('delete from myUserTable where userId=?',[$mob[0]->getId]);
|
||||
my $inDb = $session->db->quickScalar("select count(*) from myUserTable where userId=?",[$mob[0]->getId]);
|
||||
ok ( !$inDb, 'mob[0] no longer in myUserTable');
|
||||
WebGUI::Cache->new($session, ["groupMembers",$gY->getId])->delete; #Delete cache so we get a good test
|
||||
$session->stow->delete("isInGroup"); #Delete stow so we get a good test
|
||||
|
||||
ok( isIn($mob[0]->userId, @{ $gY->getAllUsers() }), 'mob[0] in list of group Y users');
|
||||
ok( !isIn($mob[0]->userId, @{ $gZ->getUsers() }), 'mob[0] not in list of group Z users');
|
||||
|
||||
ok( isIn($mob[0]->userId, @{ $gZ->getAllUsers() }), 'mob[0] in list of group Z users, recursively');
|
||||
is_deeply(
|
||||
[ (map { $gY->hasDatabaseUser($_->getId) } @mob) ],
|
||||
[0, 1, 1],
|
||||
'mob users 1,2 found in list of group Y users from database'
|
||||
);
|
||||
|
||||
##Karma tests
|
||||
|
||||
|
|
@ -497,6 +557,12 @@ is_deeply(
|
|||
'karma disabled in settings, no users in group'
|
||||
);
|
||||
|
||||
is_deeply(
|
||||
[ (map { $gK->hasKarmaUser($_->getId) } @chameleons) ],
|
||||
[0, 0, 0, 0],
|
||||
'karma disabled in settings, group K has no users via karma threshold'
|
||||
);
|
||||
|
||||
$session->setting->set('useKarma', 1);
|
||||
$gK->clearCaches; ##Clear cache since previous data is wrong
|
||||
|
||||
|
|
@ -506,6 +572,12 @@ is_deeply(
|
|||
'chameleons 1, 2 and 3 are in group K via karma threshold'
|
||||
);
|
||||
|
||||
is_deeply(
|
||||
[ (map { $gK->hasKarmaUser($_->getId) } @chameleons) ],
|
||||
[0, 1, 1, 1],
|
||||
'group K has chameleons 1, 2 and 3 via karma threshold'
|
||||
);
|
||||
|
||||
cmp_bag(
|
||||
$gK->getKarmaUsers,
|
||||
[ (map { $_->userId() } @chameleons[1..3]) ],
|
||||
|
|
@ -560,10 +632,20 @@ foreach my $idx (0..$#scratchTests) {
|
|||
WebGUI::Test->addToCleanup(@itchies);
|
||||
WebGUI::Test->addToCleanup(@sessionBank);
|
||||
|
||||
#isInGroup test
|
||||
foreach my $scratchTest (@scratchTests) {
|
||||
is($scratchTest->{user}->isInGroup($gS->getId), $scratchTest->{expect}, $scratchTest->{comment});
|
||||
}
|
||||
|
||||
WebGUI::Cache->new($session, $gS->getId)->delete(); ##Delete cached key for testing
|
||||
$session->stow->delete("isInGroup");
|
||||
|
||||
#hasScratchUser test
|
||||
foreach my $scratchTest (@scratchTests) {
|
||||
is($gS->hasScratchUser($scratchTest->{user}->getId), $scratchTest->{expect}, $scratchTest->{comment}." - hasScratchUser");
|
||||
}
|
||||
|
||||
|
||||
cmp_bag(
|
||||
$gS->getScratchUsers,
|
||||
[ (map { $_->{user}->userId() } grep { $_->{expect} } @scratchTests) ],
|
||||
|
|
@ -576,6 +658,33 @@ cmp_bag(
|
|||
'getAllUsers for group with scratch'
|
||||
);
|
||||
|
||||
{ ##Add scope to force cleanup
|
||||
|
||||
note "Checking for user Visitor session leak";
|
||||
|
||||
my $remoteSession = WebGUI::Test->newSession;
|
||||
$remoteSession->user({userId => 1});
|
||||
$remoteSession->scratch->set('remote','nok');
|
||||
|
||||
my $localScratchGroup = WebGUI::Group->new($session, 'new');
|
||||
$localScratchGroup->name("Local IP Group");
|
||||
$localScratchGroup->scratchFilter('local=ok');
|
||||
|
||||
ok !$remoteSession->user->isInGroup($localScratchGroup->getId), 'Remote Visitor fails to be in the scratch group';
|
||||
|
||||
my $localSession = WebGUI::Test->newSession;
|
||||
WebGUI::Test->addToCleanup($localScratchGroup, $remoteSession, $localSession);
|
||||
$localSession->user({userId => 1});
|
||||
$remoteSession->scratch->set('local','ok');
|
||||
$localScratchGroup->clearCaches;
|
||||
|
||||
ok $localSession->user->isInGroup($localScratchGroup->getId), 'Local Visitor is in the scratch group';
|
||||
|
||||
$remoteSession->stow->delete('isInGroup');
|
||||
ok !$remoteSession->user->isInGroup($localScratchGroup->getId), 'Remove Visitor is not in the scratch group, even though a different Visitor passed';
|
||||
|
||||
}
|
||||
|
||||
@sessionBank = ();
|
||||
my @tcps = ();
|
||||
|
||||
|
|
@ -617,10 +726,45 @@ cmp_bag(
|
|||
'getUsers for group with IP filter'
|
||||
);
|
||||
|
||||
is_deeply(
|
||||
[ (map { $gI->hasIpUser($_->{user}->getId) } @ipTests) ],
|
||||
[ (map { $_->{expect} } @ipTests) ],
|
||||
'hasIpUsers for group with IP filter'
|
||||
);
|
||||
|
||||
foreach my $ipTest (@ipTests) {
|
||||
is($ipTest->{user}->isInGroup($gI->getId), $ipTest->{expect}, $ipTest->{comment});
|
||||
}
|
||||
|
||||
{ ##Add scope to force cleanup
|
||||
|
||||
note "Checking for user Visitor session leak";
|
||||
|
||||
$ENV{REMOTE_ADDR} = '191.168.1.1';
|
||||
my $remoteSession = WebGUI::Test->newSession;
|
||||
$remoteSession->user({userId => 1});
|
||||
|
||||
my $localIpGroup = WebGUI::Group->new($session, 'new');
|
||||
$localIpGroup->name("Local IP Group");
|
||||
$localIpGroup->ipFilter('192.168.33.0/24');
|
||||
|
||||
ok !$remoteSession->user->isInGroup($localIpGroup->getId), 'Remote Visitor fails to be in the group';
|
||||
|
||||
$ENV{REMOTE_ADDR} = '192.168.33.1';
|
||||
my $localSession = WebGUI::Test->newSession;
|
||||
WebGUI::Test->addToCleanup($localIpGroup, $remoteSession, $localSession);
|
||||
$localSession->user({userId => 1});
|
||||
$localIpGroup->clearCaches;
|
||||
|
||||
ok $localSession->user->isInGroup($localIpGroup->getId), 'Local Visitor is in the group';
|
||||
|
||||
$remoteSession->stow->delete('isInGroup');
|
||||
ok !$remoteSession->user->isInGroup($localIpGroup->getId), 'Remove Visitor is not in the group, even though a different Visitor passed';
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
##Cache check.
|
||||
|
||||
my $cacheDude = WebGUI::User->new($session, "new");
|
||||
|
|
|
|||
145
t/ProgressBar.t
Normal file
145
t/ProgressBar.t
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
#-------------------------------------------------------------------
|
||||
# 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
|
||||
#------------------------------------------------------------------
|
||||
|
||||
{
|
||||
package WebGUI::Test::ProgressBar;
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
sub new { bless {}, shift }
|
||||
|
||||
sub foo { $_[0]->{foo} = $_[1] }
|
||||
|
||||
sub bar { $_[0]->{bar} = $_[1] }
|
||||
}
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use FindBin;
|
||||
use lib "$FindBin::Bin/lib";
|
||||
|
||||
use Test::More;
|
||||
use Test::MockObject::Extends;
|
||||
use WebGUI::Test;
|
||||
use WebGUI::Session;
|
||||
|
||||
my $session = WebGUI::Test->session;
|
||||
|
||||
# Test the run method of ProgessBar -- it does some symbol table
|
||||
# manipulation...
|
||||
|
||||
my $TestTitle = 'test title';
|
||||
my $TestIcon = '/test/icon';
|
||||
my $TestUrl = 'http://test.com/url';
|
||||
|
||||
my ($started, $finished);
|
||||
my @updates = qw(one two not used);
|
||||
|
||||
sub mockbar {
|
||||
Test::MockObject::Extends->new(WebGUI::ProgressBar->new($session));
|
||||
}
|
||||
|
||||
my $pb = mockbar
|
||||
->mock(start => sub {
|
||||
my ($self, $title, $icon) = @_;
|
||||
is $title, $TestTitle, 'title';
|
||||
is $icon, $TestIcon, 'icon';
|
||||
ok !$started, q"hadn't started yet";
|
||||
$started = 1;
|
||||
})
|
||||
->mock(update => sub {
|
||||
my ($self, $message) = @_;
|
||||
my $expected = shift(@updates);
|
||||
is $message, $expected, 'message';
|
||||
})
|
||||
->mock(finish => sub {
|
||||
my ($self, $url) = @_;
|
||||
is $url, $TestUrl, 'url';
|
||||
ok !$finished, q"hadn't finished yet";
|
||||
$finished = 1;
|
||||
return 'chunked';
|
||||
});
|
||||
|
||||
my $object = WebGUI::Test::ProgressBar->new;
|
||||
ok !$object->{foo}, 'no foo';
|
||||
ok !$object->{bar}, 'no bar';
|
||||
|
||||
sub wrapper {
|
||||
my ($bar, $original, $obj, $val) = @_;
|
||||
$bar->update($val);
|
||||
$obj->$original($val);
|
||||
}
|
||||
|
||||
is $pb->run(
|
||||
arg => 'argument',
|
||||
title => $TestTitle,
|
||||
icon => $TestIcon,
|
||||
code => sub {
|
||||
my ($bar, $arg) = @_;
|
||||
isa_ok $bar, 'WebGUI::ProgressBar', 'code invocant';
|
||||
is $arg, 'argument', 'code argument';
|
||||
ok $started, 'started';
|
||||
ok !$finished, 'not finished yet';
|
||||
is $object->foo('one'), 'one', 'wrapped return';
|
||||
is $object->bar('two'), 'two', 'wrapped return (again)';
|
||||
return $TestUrl;
|
||||
},
|
||||
wrap => {
|
||||
'WebGUI::Test::ProgressBar::foo' => \&wrapper,
|
||||
'WebGUI::Test::ProgressBar::bar' => \&wrapper,
|
||||
}
|
||||
), 'chunked', 'run return value';
|
||||
|
||||
ok $finished, 'finished now';
|
||||
is $object->{foo}, 'one', 'foo original called';
|
||||
is $object->{bar}, 'two', 'bar original called';
|
||||
$object->foo('foo');
|
||||
is $object->{foo}, 'foo', 'foo still works';
|
||||
$object->bar('bar');
|
||||
is $object->{bar}, 'bar', 'bar still works';
|
||||
is @updates, 2, 'no shifting from updates after run';
|
||||
|
||||
delete @{$object}{qw(foo bar)};
|
||||
|
||||
my $updated;
|
||||
# make sure that the symbol table machinations work even when something dies
|
||||
$pb = mockbar->mock(start => sub {})
|
||||
->mock(finish => sub {})
|
||||
->mock(update => sub { $updated = 1 });
|
||||
|
||||
eval {
|
||||
$pb->run(
|
||||
code => sub {
|
||||
$object->foo('foo');
|
||||
$object->bar('bar');
|
||||
},
|
||||
wrap => {
|
||||
'WebGUI::Test::ProgressBar::foo' => \&wrapper,
|
||||
'WebGUI::Test::ProgressBar::bar' => sub { die "blar!\n" }
|
||||
}
|
||||
);
|
||||
};
|
||||
my $e = $@;
|
||||
|
||||
is $e, "blar!\n", 'exception propogated';
|
||||
is $object->{foo}, 'foo', 'foo after die';
|
||||
ok !$object->{bar}, 'bar did not get set';
|
||||
$object->bar('bar');
|
||||
is $object->{bar}, 'bar', 'but it works now';
|
||||
|
||||
ok $updated, 'update called for foo';
|
||||
$updated = 0;
|
||||
$object->foo('ignored');
|
||||
ok !$updated, 'update not called for foo';
|
||||
|
||||
done_testing;
|
||||
|
||||
#vim:ft=perl
|
||||
|
|
@ -50,7 +50,7 @@ my @getRefererUrlTests = (
|
|||
);
|
||||
|
||||
use Test::More;
|
||||
plan tests => 79 + scalar(@getRefererUrlTests);
|
||||
plan tests => 83 + scalar(@getRefererUrlTests);
|
||||
|
||||
my $session = WebGUI::Test->session;
|
||||
my $request = $session->request;
|
||||
|
|
@ -81,7 +81,7 @@ is( $url2, $url.'?a=b;c=d', 'append second pair');
|
|||
#
|
||||
#######################################
|
||||
|
||||
my $gateway = $session->config->get('gateway');
|
||||
WebGUI::Test->originalConfig('gateway');
|
||||
$session->config->set('gateway', '/');
|
||||
|
||||
is( $session->config->get('gateway'), '/', 'Set gateway for downstream tests');
|
||||
|
|
@ -127,10 +127,7 @@ my $setting_hostToUse = $session->setting->get('hostToUse');
|
|||
$session->setting->set('hostToUse', 'HTTP_HOST');
|
||||
my $sitename = $session->config->get('sitename')->[0];
|
||||
is( $session->url->getSiteURL, 'http://'.$sitename, 'getSiteURL from config as http_host');
|
||||
my $config_port;
|
||||
if ($session->config->get('webServerPort')) {
|
||||
$config_port = $session->config->get('webServerPort');
|
||||
}
|
||||
WebGUI::Test->originalConfig('webServerPort');
|
||||
|
||||
$session->url->setSiteURL('http://webgui.org');
|
||||
is( $session->url->getSiteURL, 'http://webgui.org', 'override config setting with setSiteURL');
|
||||
|
|
@ -147,7 +144,7 @@ $env->{HTTP_HOST} = "devsite.com";
|
|||
$session->url->setSiteURL(undef);
|
||||
is( $session->url->getSiteURL, 'http://'.$sitename, 'getSiteURL where requested host is not a configured site');
|
||||
|
||||
my @config_sitename = @{ $session->config->get('sitename') };
|
||||
WebGUI::Test->originalConfig('sitename');
|
||||
$session->config->addToArray('sitename', 'devsite.com');
|
||||
$session->url->setSiteURL(undef);
|
||||
is( $session->url->getSiteURL, 'http://devsite.com', 'getSiteURL where requested host is not the first configured site');
|
||||
|
|
@ -166,14 +163,7 @@ is( $session->url->getSiteURL, 'http://'.$sitename.':8880', 'getSiteURL with a n
|
|||
|
||||
$session->url->setSiteURL('http://'.$sitename);
|
||||
is( $session->url->getSiteURL, 'http://'.$sitename, 'restore config setting');
|
||||
$session->config->set('sitename', \@config_sitename);
|
||||
$session->setting->set('hostToUse', $setting_hostToUse);
|
||||
if ($config_port) {
|
||||
$session->config->set('webServerPort', $config_port);
|
||||
}
|
||||
else {
|
||||
$session->config->delete('webServerPort');
|
||||
}
|
||||
|
||||
$url = 'level1 /level2/level3 ';
|
||||
$url2 = 'level1-/level2/level3';
|
||||
|
|
@ -277,14 +267,10 @@ is($session->url->makeAbsolute('page1'), '/page1', 'makeAbsolute: default baseUr
|
|||
#
|
||||
#######################################
|
||||
|
||||
my $origExtras = $session->config->get('extrasURL');
|
||||
my $extras = $origExtras;
|
||||
my $extras = WebGUI::Test->originalConfig('extrasURL');
|
||||
|
||||
my $savecdn = $session->config->get('cdn');
|
||||
if ($savecdn) {
|
||||
$session->config->delete('cdn');
|
||||
}
|
||||
# Note: the CDN configuration will be reverted in the END
|
||||
WebGUI::Test->originalConfig('cdn');
|
||||
$session->config->delete('cdn');
|
||||
|
||||
is($session->url->extras, $extras.'/', 'extras method returns URL to extras with a trailing slash');
|
||||
is($session->url->extras('foo.html'), join('/', $extras,'foo.html'), 'extras method appends to the extras url');
|
||||
|
|
@ -322,11 +308,6 @@ is($session->url->extras('/dir1/foo.html'), join('', $cdnCfg->{extrasSsl}, 'dir1
|
|||
'extras using extrasSsl with HTTPS');
|
||||
$env->{'psgi.url_scheme'} = "http";
|
||||
|
||||
$session->config->set('extrasURL', $origExtras);
|
||||
|
||||
# partial cleanup here; complete cleanup in END block
|
||||
$session->config->delete('cdn');
|
||||
|
||||
#######################################
|
||||
#
|
||||
# escape and unescape
|
||||
|
|
@ -354,10 +335,14 @@ is($session->url->urlize('HOME/PATH1'), 'home/path1', 'urlize: urls are lower ca
|
|||
is($session->url->urlize('home/'), 'home', '... trailing slashes removed');
|
||||
is($session->url->urlize('home is where the heart is'), 'home-is-where-the-heart-is', '... makeCompliant translates spaces to dashes');
|
||||
is($session->url->urlize('/home'), 'home', '... removes initial slash');
|
||||
is($session->url->urlize('home/../out-of-bounds'), 'home/out-of-bounds', '... removes multiple ../');
|
||||
is($session->url->urlize('home/./here'), 'home/here', '... removes multiple ./');
|
||||
is($session->url->urlize('home/../out-of-bounds'), 'home/out-of-bounds', '... removes ../');
|
||||
is($session->url->urlize('home/./here'), 'home/here', '... removes ./');
|
||||
is($session->url->urlize('home/../../out-of-bounds'), 'home/out-of-bounds', '... removes multiple ../');
|
||||
is($session->url->urlize('home/././here'), 'home/here', '... removes multiple ./');
|
||||
is($session->url->urlize('home -- here'), 'home-here', 'multiple dashes collapsed');
|
||||
is($session->url->urlize('home!@#$%^&*here'), 'home-here', 'non-word characters collapsed to single dash');
|
||||
is($session->url->urlize("home\x{2267}here"), 'home-here', 'non-word international characters removed');
|
||||
is($session->url->urlize("home\x{1EE9}here"), "home\x{1EE9}here", 'word international characters not removed');
|
||||
|
||||
#######################################
|
||||
#
|
||||
|
|
@ -405,6 +390,7 @@ TODO: {
|
|||
}
|
||||
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
WebGUI::Test->addToCleanup($versionTag);
|
||||
my $statefulAsset = WebGUI::Asset->getRoot($session)->addChild({ className => 'WebGUI::Asset::Snippet' });
|
||||
$versionTag->commit;
|
||||
$session->asset( $statefulAsset );
|
||||
|
|
@ -436,7 +422,7 @@ is(
|
|||
#
|
||||
#######################################
|
||||
|
||||
my $origSSLEnabled = $session->config->get('sslEnabled');
|
||||
WebGUI::Test->originalConfig('sslEnabled');
|
||||
|
||||
##Test all the false cases, first
|
||||
|
||||
|
|
@ -472,9 +458,3 @@ ok($session->url->forceSecureConnection(), 'forced secure connection with no url
|
|||
ok($session->http->isRedirect, '... and redirect status code was set');
|
||||
is($session->http->getRedirectLocation, $secureUrl, '... and redirect status code was set');
|
||||
|
||||
$session->config->set('sslEnabled', $origSSLEnabled);
|
||||
|
||||
END { ##Always clean-up
|
||||
$session->asset($sessionAsset);
|
||||
$versionTag->rollback if defined $versionTag;
|
||||
}
|
||||
|
|
|
|||
BIN
t/supporting_collateral/gallery_archive_sorting_test.zip
Normal file
BIN
t/supporting_collateral/gallery_archive_sorting_test.zip
Normal file
Binary file not shown.
66
t/supporting_collateral/tbb_odd.rss
Normal file
66
t/supporting_collateral/tbb_odd.rss
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>The Black Blog</title>
|
||||
<link>/tbb</link>
|
||||
<copyright/>
|
||||
<pubDate>Mon, 12 Oct 2009 11:54:28 -0500</pubDate>
|
||||
<description/>
|
||||
<item>
|
||||
<title>WebGUI Roadmap</title>
|
||||
<link>http://www.plainblack.com/tbb/webgui-roadmap</link>
|
||||
<author>JT</author>
|
||||
<epochDate>1254325377</epochDate>
|
||||
<guid isPermaLink="true">http://www.plainblack.com/tbb/webgui-roadmap</guid>
|
||||
<pubDate>Wed, 30 Sep 2009 10:42:57 -0500</pubDate>
|
||||
<userDefined1/>
|
||||
<userDefined2/>
|
||||
<userDefined3/>
|
||||
<userDefined4/>
|
||||
<userDefined5/>
|
||||
<description>The new roadmap is online.</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>Google Picasa Plugin for WebGUI Gallery</title>
|
||||
<link>http://www.plainblack.com/tbb/google-picasa-plugin-for-webgui-gallery</link>
|
||||
<author>JT</author>
|
||||
<epochDate>1254854387</epochDate>
|
||||
<guid isPermaLink="true">http://www.plainblack.com/tbb/google-picasa-plugin-for-webgui-gallery</guid>
|
||||
<pubDate>Tue, 06 Oct 2009 13:39:47 -0500</pubDate>
|
||||
<userDefined1/>
|
||||
<userDefined2/>
|
||||
<userDefined3/>
|
||||
<userDefined4/>
|
||||
<userDefined5/>
|
||||
<description>Today we unveil the Google Picasa plugin for WebGUI Gallery.</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>I have arrived in Lisboa!</title>
|
||||
<link>http://www.plainblack.com/tbb/i-have-arrived-in-lisboa</link>
|
||||
<author>JT</author>
|
||||
<epochDate>1249140064</epochDate>
|
||||
<guid isPermaLink="true">http://www.plainblack.com/tbb/i-have-arrived-in-lisboa</guid>
|
||||
<pubDate>Sat, 01 Aug 2009 10:21:04 -0500</pubDate>
|
||||
<userDefined1/>
|
||||
<userDefined2/>
|
||||
<userDefined3/>
|
||||
<userDefined4/>
|
||||
<userDefined5/>
|
||||
<description>I'm in Lisbon, Portugal for YAPC::EU.</description>
|
||||
</item>
|
||||
<item>
|
||||
<title>WebGUI 8 Performance</title>
|
||||
<link>http://www.plainblack.com/tbb/webgui-8-performance</link>
|
||||
<author>JT</author>
|
||||
<epochDate>1254236976</epochDate>
|
||||
<guid isPermaLink="true">http://www.plainblack.com/tbb/webgui-8-performance</guid>
|
||||
<pubDate>Tue, 29 Sep 2009 10:09:36 -0500</pubDate>
|
||||
<userDefined1/>
|
||||
<userDefined2/>
|
||||
<userDefined3/>
|
||||
<userDefined4/>
|
||||
<userDefined5/>
|
||||
<description>WebGUI 8 is going to be the fastest version of WebGUI ever released.</description>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
|
|
@ -71,7 +71,7 @@ sub moveMaintenance {
|
|||
sub addMaintenancePageToConfig {
|
||||
my $session = shift;
|
||||
print "\tAdd maintenance page entry to the config file " unless $quiet;
|
||||
$session->config->set('maintenancePage', '/data/WebGUI/var/www/maintenance.html');
|
||||
$session->config->set('maintenancePage', '/data/WebGUI/www/maintenance.html');
|
||||
print "DONE!\n" unless $quiet;
|
||||
}
|
||||
|
||||
|
|
@ -79,9 +79,9 @@ sub moveFileLocations {
|
|||
my $session = shift;
|
||||
print "\tMoving preload files " unless $quiet;
|
||||
unlink '../../sbin/preload.custom.example';
|
||||
rename '../../sbin/preload.custom', File::Spec->catfile(WebGUI::Paths->etc, 'preload.custom');
|
||||
rename '../../sbin/preload.custom', File::Spec->catfile(WebGUI::Paths->configBase, 'preload.custom');
|
||||
unlink '../../sbin/preload.exclude.example';
|
||||
rename '../../sbin/preload.exclude', File::Spec->catfile(WebGUI::Paths->etc, 'preload.exclude');
|
||||
rename '../../sbin/preload.exclude', File::Spec->catfile(WebGUI::Paths->configBase, 'preload.exclude');
|
||||
unlink '../../lib/default.ttf';
|
||||
print "Done.\n" unless $quiet;
|
||||
}
|
||||
|
|
@ -242,7 +242,7 @@
|
|||
|
||||
var self = this,
|
||||
e = args.elements,
|
||||
f = document.forms[0],
|
||||
f = document.getElementById('wgCartId'),
|
||||
checks = f.sameShippingAsBilling,
|
||||
sameChange;
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 KiB |
BIN
www/extras/wg.png
Normal file
BIN
www/extras/wg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.3 KiB |
Loading…
Add table
Add a link
Reference in a new issue