Merge branch 'master' into 8-merge

Conflicts:
	docs/gotcha.txt
	lib/WebGUI.pm
	lib/WebGUI/Asset.pm
	lib/WebGUI/Asset/File/GalleryFile/Photo.pm
	lib/WebGUI/Asset/Post.pm
	lib/WebGUI/Asset/Story.pm
	lib/WebGUI/Asset/Template.pm
	lib/WebGUI/Asset/Wobject/Calendar.pm
	lib/WebGUI/Asset/Wobject/GalleryAlbum.pm
	lib/WebGUI/Asset/Wobject/Navigation.pm
	lib/WebGUI/AssetLineage.pm
	lib/WebGUI/AssetTrash.pm
	lib/WebGUI/Config.pm
	lib/WebGUI/Form/Template.pm
	lib/WebGUI/Group.pm
	lib/WebGUI/Inbox.pm
	lib/WebGUI/Workflow/Activity/DeleteExpiredSessions.pm
	lib/WebGUI/Workflow/Activity/TrashExpiredEvents.pm
	sbin/testEnvironment.pl
	t/AdSpace.t
	t/AdSpace/Ad.t
	t/Asset/Asset.t
	t/Asset/AssetExportHtml.t
	t/Asset/AssetLineage.t
	t/Asset/EMSSubmissionForm.t
	t/Asset/Event.t
	t/Asset/File/GalleryFile/Photo/00base.t
	t/Asset/File/GalleryFile/Photo/comment.t
	t/Asset/File/GalleryFile/Photo/download.t
	t/Asset/File/GalleryFile/Photo/edit.t
	t/Asset/File/GalleryFile/Photo/exif.t
	t/Asset/File/GalleryFile/Photo/makeResolutions.t
	t/Asset/File/GalleryFile/Photo/makeShortcut.t
	t/Asset/File/Image/setfile.t
	t/Asset/File/setfile.t
	t/Asset/Post.t
	t/Asset/Post/Thread/getAdjacentThread.t
	t/Asset/Sku.t
	t/Asset/Sku/ProductCollateral.t
	t/Asset/Story.t
	t/Asset/Template.t
	t/Asset/Template/HTMLTemplateExpr.t
	t/Asset/Wobject/Gallery/00base.t
	t/Asset/Wobject/GalleryAlbum/00base.t
	t/Asset/Wobject/GalleryAlbum/ajax.t
	t/Asset/Wobject/GalleryAlbum/delete.t
	t/Asset/Wobject/Matrix.t
	t/Asset/Wobject/StoryArchive.t
	t/Asset/Wobject/Survey/ExpressionEngine.t
	t/Asset/Wobject/Survey/Reports.t
	t/AssetAspect/RssFeed.t
	t/Auth/mech.t
	t/Config.t
	t/Group.t
	t/Help/isa.t
	t/International.t
	t/Mail/Send.t
	t/Operation/AdSpace.t
	t/Operation/Auth.t
	t/Pluggable.t
	t/Session.t
	t/Session/DateTime.t
	t/Session/ErrorHandler.t
	t/Session/Scratch.t
	t/Session/Stow.t
	t/Shop/Cart.t
	t/Shop/Pay.t
	t/Shop/PayDriver/ITransact.t
	t/Shop/PayDriver/PayPalStd.t
	t/Shop/Ship.t
	t/Shop/ShipDriver.t
	t/Shop/TaxDriver/EU.t
	t/Shop/TaxDriver/Generic.t
	t/Shop/Transaction.t
	t/Shop/Vendor.t
	t/VersionTag.t
	t/Workflow/Activity/ArchiveOldStories.t
	t/Workflow/Activity/ExpireIncompleteSurveyResponses.t
	t/lib/WebGUI/Test.pm
This commit is contained in:
Doug Bell 2010-07-09 11:48:30 -05:00
commit babfa74209
238 changed files with 4557 additions and 1287 deletions

View file

@ -108,8 +108,7 @@ override applyConstraints => sub {
$storage->resize( $file, undef, undef, $gallery->imageDensity );
$storage->adjustMaxImageSize($file, $maxImageSize);
$self->generateThumbnail;
$self->setSize;
$self->generateThumbnail;
$self->updateExifDataFromFile;
super();
};
@ -229,10 +228,11 @@ sub getEditFormUploadControl {
}
# Control to upload a new file
$html .= WebGUI::Form::file( $session, {
name => 'newFile',
label => $i18n->get('new file'),
hoverHelp => $i18n->get('new file description'),
$html .= WebGUI::Form::image( $session, {
name => 'newFile',
label => $i18n->get('new file'),
hoverHelp => $i18n->get('new file description'),
forceImageOnly => 1,
});
return $html;
@ -378,11 +378,19 @@ contained in.
sub makeResolutions {
my $self = shift;
my $resolutions = shift;
my $session = $self->session;
my $error;
croak "Photo->makeResolutions: resolutions must be an array reference"
if $resolutions && ref $resolutions ne "ARRAY";
# # Return immediately if no image is available
# if ( $self->get("filename") eq '' )
# {
# $session->log->error("makeResolutions skipped since no image available");
# return;
# }
# Get default if necessary
$resolutions ||= $self->getGallery->getImageResolutions;
@ -413,13 +421,20 @@ Make the default title into the file name minus the extention.
override processPropertiesFromFormPost => sub {
my $self = shift;
my $i18n = WebGUI::International->new( $self->session,'Asset_Photo' );
my $form = $self->session->form;
my $errors = super() || [];
# Make sure there is an image file attached to this asset.
if ( !$self->get('filename') ) {
push @{ $errors }, $i18n->get('error no image');
}
# Return if errors
return $errors if @$errors;
### Passes all checks
# If no title was given, make it the file name
if ( !$form->get('title') ) {
my $title = $self->filename;
@ -586,6 +601,7 @@ sub www_edit {
$var->{ form_start }
= WebGUI::Form::formHeader( $session, {
action => $self->getParent->getUrl('func=editSave;assetId=new;class='.__PACKAGE__),
extras => 'name="photoAdd"',
})
. WebGUI::Form::hidden( $session, {
name => 'ownerUserId',
@ -597,6 +613,7 @@ sub www_edit {
$var->{ form_start }
= WebGUI::Form::formHeader( $session, {
action => $self->getUrl('func=editSave'),
extras => 'name="photoEdit"',
})
. WebGUI::Form::hidden( $session, {
name => 'ownerUserId',
@ -607,7 +624,7 @@ sub www_edit {
$var->{ form_start }
.= WebGUI::Form::hidden( $session, {
name => "proceed",
value => "showConfirmation",
value => $form->get('proceed') || "showConfirmation",
});
$var->{ form_end } = WebGUI::Form::formFooter( $session );

View file

@ -118,6 +118,7 @@ sub _fixReplyCount {
my $lastPostId = $asset->getLineage( [ qw{ self descendants } ], {
isa => 'WebGUI::Asset::Post',
orderByClause => 'assetData.revisionDate desc',
limit => 1,
} )->[0];
if (my $lastPost = WebGUI::Asset->newById( $self->session, $lastPostId ) ) {
@ -315,6 +316,53 @@ override cut => sub {
#-------------------------------------------------------------------
=head2 disqualifyAsLastPost ( )
This method should be called whenever something happens to the Post or Thread that would disqualify
it as being the last post in a Thread, or Collaboration System. Good examples are cutting to the
clipboard, trashing, or archiving.
If the Post was the last post, it will find the second to last post for each kind of parent asset,
and update that asset with that Post's information.
=cut
sub disqualifyAsLastPost {
my $self = shift;
my $thread = $self->getThread;
if ($thread->get('lastPostId') eq $self->getId) {
my $secondary_post = $thread->getLineage(['descendants'], {
returnObjects => 1,
includeOnlyClasses => ["WebGUI::Asset::Post", ],
limit => 1,
orderByClause => 'revisionDate,lineage DESC',
})->[0];
if ($secondary_post) { ##Handle edge case for no other
$thread->update({ lastPostId => $secondary_post->getId, lastPostDate => $secondary_post->get('creationDate'), });
}
else {
$thread->update({ lastPostId => '', lastPostDate => '', });
}
}
my $cs = $thread->getParent;
if ($cs->get('lastPostId') eq $self->getId) {
my $secondary_post = $cs->getLineage(['descendants'], {
returnObjects => 1,
includeOnlyClasses => ["WebGUI::Asset::Post","WebGUI::Asset::Post::Thread"],
limit => 1,
orderByClause => 'revisionDate DESC',
})->[0];
if ($secondary_post) { ##Handle edge case for no other
$cs->update({ lastPostId => $secondary_post->getId, lastPostDate => $secondary_post->get('creationDate'), });
}
else {
$cs->update({ lastPostId => '', lastPostDate => '', });
}
}
}
#-------------------------------------------------------------------
=head2 DESTROY
Extend the base method to delete the locally cached thread object.
@ -1102,6 +1150,22 @@ sub postProcess {
#-------------------------------------------------------------------
=head2 publish
Extend the base method to handle updating last post information in the parent Thread
and CS.
=cut
sub publish {
my $self = shift;
$self->next::method(@_);
$self->qualifyAsLastPost;
return 1;
}
#-------------------------------------------------------------------
=head2 purge
Extend the base method to handle cleaning up storage locations.
@ -1149,6 +1213,31 @@ override purgeRevision => sub {
#-------------------------------------------------------------------
=head2 qualifyAsLastPost ( )
This method should be called whenever something happens to the Post or Thread that would qualify
it as being the last post in a Thread, or Collaboration System. Good examples are pasting from
the clipboard, restoring from the trash, or changing the state from archiving.
It checks the parent Thread and CS to see if it is now the last Post, and updates that asset with
its information.
=cut
sub qualifyAsLastPost {
my ($self) = @_;
my $thread = $self->getThread();
if ($self->get('creationDate') > $thread->get('lastPostDate')) {
$thread->update({ lastPostId => $self->getId, lastPostDate => $self->get('creationDate'), });
}
my $cs = $thread->getParent;
if ($self->get('creationDate') > $cs->get('lastPostDate')) {
$cs->update({ lastPostId => $self->getId, lastPostDate => $self->get('creationDate'), });
}
}
#-------------------------------------------------------------------
=head2 rate ( rating )
@ -1253,14 +1342,16 @@ override setParent => sub {
=head2 setStatusArchived ( )
Sets the status of this post to archived.
Sets the status of this post to archived. Updates the parent thread and CS to remove
the lastPost, if this post is the last post.
=cut
sub setStatusArchived {
my ($self) = @_;
$self->update({status=>'archived'});
my ($self) = @_;
$self->update({status=>'archived'});
$self->disqualifyAsLastPost;
}
@ -1269,20 +1360,23 @@ sub setStatusArchived {
=head2 setStatusUnarchived ( )
Sets the status of this post to approved, but does so without any of the normal notifications and other stuff.
Updates the last post information in the parent Thread and CS if applicable.
=cut
sub setStatusUnarchived {
my ($self) = @_;
$self->update({status=>'approved'}) if ($self->status eq "archived");
my ($self) = @_;
$self->update({status=>'approved'}) if ($self->get("status") eq "archived");
$self->qualifyAsLastPost;
}
#-------------------------------------------------------------------
=head2 trash ( )
Moves post to the trash, updates reply counter on thread and recalculates the thread rating.
Moves post to the trash, updates reply counter on thread, recalculates the thread rating,
and updates any lastPost information in the parent Thread, and CS.
=cut
@ -1291,22 +1385,8 @@ override trash => sub {
super();
$self->getThread->sumReplies if ($self->isReply);
$self->getThread->updateThreadRating;
if ($self->getThread->lastPostId eq $self->getId) {
my $threadLineage = $self->getThread->lineage;
my ($id, $date) = $self->session->db->quickArray("select assetId, creationDate from asset where
lineage like ? and assetId<>? and asset.state='published' and className like 'WebGUI::Asset::Post%'
order by creationDate desc",[$threadLineage.'%', $self->getId]);
$self->getThread->update({lastPostId=>$id, lastPostDate=>$date});
}
if ($self->getThread->getParent->lastPostId eq $self->getId) {
my $forumLineage = $self->getThread->getParent->lineage;
my ($id, $date) = $self->session->db->quickArray("select assetId, creationDate from asset where
lineage like ? and assetId<>? and asset.state='published' and className like 'WebGUI::Asset::Post%'
order by creationDate desc",[$forumLineage.'%', $self->getId]);
$self->getThread->getParent->update({lastPostId=>$id, lastPostDate=>$date});
}
};
$self->disqualifyAsLastPost;
}
#-------------------------------------------------------------------
@ -1506,6 +1586,7 @@ sub www_edit {
$var{'archive.form'} = WebGUI::Form::yesNo($session, {
name=>"archive"
});
$var{'isSubscribedToCs'} = $self->getThread->getParent->isSubscribed;
$var{'form.header'} .= WebGUI::Form::hidden($session, {
name=>"proceed",
value=>"showConfirmation"

View file

@ -501,12 +501,14 @@ property of the Asset.
=cut
sub getRssData {
my $self = shift;
my $self = shift;
my $session = $self->session;
my $url = $session->url->getSiteURL.$self->getUrl;
my $data = {
title => $self->headline || $self->getTitle,
description => $self->story,
'link' => $self->getUrl,
guid => $self->getUrl,
'link' => $url,
guid => $url,
author => $self->byline,
date => $self->lastModified,
pubDate => $self->session->datetime->epochToMail($self->creationDate),

View file

@ -134,29 +134,77 @@ These methods are available from this class:
#-------------------------------------------------------------------
=head2 addAttachments ( attachments )
=head2 definition ( session, definition )
Adds attachments to this template. Attachments is an arrayref of hashrefs,
where each hashref should have at least url, type, and sequence as keys.
Defines the properties of this asset.
=head3 session
A reference to an existing session.
=head3 definition
A hash reference passed in from a subclass definition.
=cut
sub addAttachments {
my ($self, $attachments) = @_;
my $db = $self->session->db;
foreach my $a (@$attachments) {
my %params = (
templateId => $self->getId,
revisionDate => $self->revisionDate,
url => $a->{url},
type => $a->{type},
sequence => $a->{sequence},
attachId => 'new',
);
$db->setRow('template_attachments', 'attachId', \%params);
}
sub definition {
my $class = shift;
my $session = shift;
my $definition = shift;
my $i18n = WebGUI::International->new($session,"Asset_Template");
push @{$definition}, {
assetName => $i18n->get('assetName'),
icon => 'template.gif',
tableName => 'template',
className => 'WebGUI::Asset::Template',
properties => {
template => {
fieldType => 'codearea',
syntax => "html",
defaultValue => undef,
filter => 'packTemplate',
},
isEditable => {
noFormPost => 1,
fieldType => 'hidden',
defaultValue => 1,
},
isDefault => {
fieldType => 'hidden',
defaultValue => 0,
},
showInForms => {
fieldType => 'yesNo',
defaultValue => 1,
},
parser => {
noFormPost => 1,
fieldType => 'selectBox',
defaultValue => [$session->config->get("defaultTemplateParser")],
},
namespace => {
fieldType => 'combo',
defaultValue => undef,
},
templatePacked => {
fieldType => 'hidden',
defaultValue => undef,
noFormPost => 1,
},
usePacked => {
fieldType => 'yesNo',
defaultValue => 0,
},
storageIdExample => {
fieldType => 'image',
},
attachmentsJson => {
fieldType => 'JsonTable',
},
},
};
return $class->SUPER::definition($session,$definition);
}
#-------------------------------------------------------------------
@ -171,7 +219,6 @@ override addRevision => sub {
my ( $self, $properties, @args ) = @_;
my $asset = super();
delete $properties->{templatePacked};
$asset->addAttachments($self->getAttachments);
return $asset;
};
@ -207,7 +254,6 @@ override duplicate => sub {
my $self = shift;
my $newTemplate = super();
$newTemplate->update({isDefault => 0});
$newTemplate->addAttachments($self->getAttachments);
if ( my $storageId = $self->get('storageIdExample') ) {
my $newStorage = WebGUI::Storage->get( $self->session, $storageId )->copy;
$newTemplate->update({ storageIdExample => $newStorage->getId });
@ -225,8 +271,7 @@ Override to add attachments to package data
override exportAssetData => sub {
my ( $self ) = @_;
my $data = super();
$data->{template_attachments} = $self->getAttachments;
my $data = $self->SUPER::exportAssetData;
if ( $self->get('storageIdExample') ) {
push @{$data->{storage}}, $self->get('storageIdExample');
}
@ -249,27 +294,24 @@ If defined, will limit the attachments to this type; e.g., passing
sub getAttachments {
my ( $self, $type ) = @_;
my @params = ($self->getId, $self->revisionDate);
my $typeString;
if ($type) {
$typeString = 'AND type = ?';
push(@params, $type);
}
return [] if !$self->get('attachmentsJson');
my $sql = qq{
SELECT
*
FROM
template_attachments
WHERE
templateId = ?
AND revisionDate = ?
$typeString
ORDER BY
type, sequence ASC
};
return $self->session->db->buildArrayRefOfHashRefs($sql, \@params);
my $attachments = JSON->new->decode( $self->get('attachmentsJson') );
# We want it all and we want it now
if ( !$type ) {
return $attachments;
}
my $output = [];
for my $attach ( @{$attachments} ) {
if ( $attach->{type} eq $type ) {
push @{$output}, $attach;
}
}
return $output;
}
#-------------------------------------------------------------------
@ -344,75 +386,31 @@ override getEditForm => sub {
);
}
### Template attachments
my $session = $self->session;
my @headers = map { '<th>' . $i18n->get("attachment header $_") . '</th>' }
qw(index type url remove);
tie my %attachmentTypeNames, 'Tie::IxHash' => (
stylesheet => $i18n->get('css label'),
headScript => $i18n->get('js head label'),
bodyScript => $i18n->get('js body label'),
$tabform->getTab('properties')->jsonTable(
name => 'attachmentsJson',
value => $self->get('attachmentsJson'),
label => $i18n->get("attachments display label"),
fields => [
{
type => "text",
name => "url",
label => $i18n->get('attachment header url'),
size => '48',
},
{
type => "select",
name => "type",
label => $i18n->get('attachment header type'),
options => [
stylesheet => $i18n->get('css label'),
headScript => $i18n->get('js head label'),
bodyScript => $i18n->get('js body label'),
],
},
],
);
my $table = '<table id="attachmentDisplay">';
$table .= "<thead><tr>@headers</tr></thead><tbody id='addAnchor'>";
foreach my $a ( @{ $self->getAttachments } ) {
my ($seq, $type, $url) = @{$a}{qw(sequence type url)};
# escape macros in the url so they don't get processed
$url =~ s/\^/&#94;/g;
my $del = WebGUI::Form::checkbox(
$session, {
name => 'removeAttachment',
value => $url,
extras => 'class="id"',
}
);
my @data = (
"<td class='index'>$seq</td>",
"<td class='type'>$type</td>",
"<td class='url'>$url</td>",
"<td>$del</td>",
);
$table .= "<tr class='existingAttachment'>@data</tr>";
}
$table .= '</tbody></table>';
my $properties = $tabform->getTab('properties');
my $label = $i18n->get('attachment display label');
$properties->raw("<tr><td>$label</td><td>$table</td></tr>");
my @data = map { "<td>$_</td>" } (
WebGUI::Form::integer(
$session, { size => '2', id => 'addBoxIndex' }
),
WebGUI::Form::selectBox(
$session, { options => \%attachmentTypeNames, id => 'addBoxType' }
),
WebGUI::Form::text($session, { id => 'addBoxUrl', size => 40 }),
WebGUI::Form::button(
$session, {
value => $i18n->get('attachment add button'),
extras => 'onclick="addClick()"'
}
),
);
my ($style, $url) = $self->session->quick(qw(style url));
$style->setScript($url->extras('yui/build/yahoo/yahoo-min.js'));
$style->setScript($url->extras('yui/build/json/json-min.js'));
$style->setScript($url->extras('yui/build/dom/dom-min.js'));
$style->setScript($url->extras('yui/build/event/event-min.js'));
$style->setScript($url->extras('yui/build/connection/connection-min.js'));
$style->setScript($url->extras('yui-webgui/build/i18n/i18n.js'));
pop(@headers);
my $scriptUrl = $url->extras('templateAttachments.js');
$table = "<table id='addBox'><tr>@headers</tr><tr>@data</tr></table>";
$table .= qq(<script type="text/javascript" src="$scriptUrl"></script>);
$label = $i18n->get('attachment add field label');
$properties->raw("<tr><td>$label</td><td>$table</td></tr>");
$properties->image(
$tabform->getTab('properties')->image(
name => 'storageIdExample',
value => $self->getValue('storageIdExample'),
label => $i18n->get('field storageIdExample'),
@ -667,6 +665,7 @@ Extends the master class to handle template parsers, namespaces and template att
override processPropertiesFromFormPost => sub {
my $self = shift;
super();
my $session = $self->session;
# TODO: Perhaps add a way to check template syntax before it blows stuff up?
my %data;
my $needsUpdate = 0;
@ -688,28 +687,7 @@ override processPropertiesFromFormPost => sub {
}
### Template attachments
my $f = $self->session->form;
my $p = $f->paramsHashRef;
my @nums = grep {$_} map { my ($i) = /^attachmentUrl(\d+)$/; $i } keys %$p;
my @add;
# Remove all attachments first, then re-add whatever's left in the form
$self->removeAttachments;
foreach my $n (@nums) {
my ($index, $type, $url) =
map { $f->process('attachment' . $_ . $n) }
qw(Index Type Url);
push(
@add, {
sequence => $index,
url => $url,
type => $type,
}
);
}
$self->addAttachments(\@add);
$self->update({ attachmentsJson => $session->form->process( 'attachmentsJson', 'JsonTable' ), });
return;
};
@ -749,66 +727,25 @@ sub processRaw {
#-------------------------------------------------------------------
=head2 purge ( )
=head2 update
Extend the master to purge attachments in all revisions.
Override update from Asset.pm to handle backwards compatibility with the old
packages that contain headBlocks. This will be removed in the future. Don't plan
on this being here.
=cut
sub purge {
sub update {
my $self = shift;
$self->session->db->write('delete from template_attachments where templateId=?', [$self->getId]);
return $self->SUPER::purge(@_);
}
my $requestedProperties = shift;
my $properties = clone($requestedProperties);
#-------------------------------------------------------------------
=head2 purgeRevision ( )
Extend the master purgeRevision to purge attachments
=cut
override purgeRevision => sub {
my $self = shift;
$self->removeAttachments;
return super();
};
#-------------------------------------------------------------------
=head2 removeAttachments ( urls )
Removes attachments. C<urls> is an arrayref of URLs to remove. If C<urls>
is not defined, will remove all attachments for this revision.
=cut
sub removeAttachments {
my ($self, $urls) = @_;
my $db = $self->session->db;
my $dbh = $db->dbh;
my $rmsql = qq{
DELETE FROM
template_attachments
WHERE
templateId = ?
AND revisionDate = ?
};
if ( $urls && @{$urls} ) {
my $in = join(',', map { $dbh->quote($_) } @{$urls});
$rmsql .= qq{
AND url IN ($in)
};
if (exists $properties->{headBlock}) {
$properties->{extraHeadTags} .= $properties->{headBlock};
delete $properties->{headBlock};
}
my @params = (
$self->getId,
$self->get('revisionDate'),
);
$db->write($rmsql, \@params);
$self->SUPER::update($properties);
}
#-------------------------------------------------------------------

View file

@ -241,12 +241,36 @@ sub _listViewPageInterval_builder {
}
property icalFeeds => (
noFormPost => 1,
fieldType => "textarea",
default => sub { return []; },
traits => ['Array', 'WebGUI::Definition::Meta::Property::Serialize',],
isa => 'WebGUI::Type::JSONArray',
coerce => 1,
fieldType => "JsonTable",
defaultValue => [],
serialize => 1,
tab => "feeds",
fields => [
{
name => 'feedId',
type => 'id',
},
{
name => 'url',
type => 'text',
size => '40',
label => $i18n->get('Feed URL'),
},
{
name => 'status',
type => 'readonly',
label => $i18n->get('434','WebGUI'),
},
{
name => 'lastUpdated',
type => 'readonly',
label => $i18n->get('454', 'WebGUI'),
},
],
);
property icalInterval => (
@ -511,169 +535,17 @@ sub deleteFeed {
#----------------------------------------------------------------------------
=head2 getEditForm
=head2 getEditTabs ( )
Adds an additional tab for feeds.
TODO: Abstract the Javascript enough to export into extras/yui-webgui for use
in other areas.
Add the feeds tab to the edit form
=cut
override getEditForm => sub {
my $self = shift;
my $session = $self->session;
my $form = super();
my $i18n = WebGUI::International->new($session,"Asset_Calendar");
my $tab = $form->addTab("feeds",$i18n->get("feeds"), 6);
$tab->raw("<tr><td>");
$tab->raw(<<'ENDJS');
<script type="text/javascript">
var FeedsManager = new Object();
FeedsManager.addFeed = function (table,rowId,params) {
// TODO: Verify that feed URL is valid
var table = document.getElementById(table);
// If id is "new"
// Add a number on the end.
if (rowId == "new")
rowId = "new" + Math.round(Math.random() * 10000000000000000);
// Create 5 cells
var cells = new Array();
for (var i = 0; i < 5; i++)
cells[i] = document.createElement("td");
/*** [0] - Delete button */
var button = document.createElement("img");
button.setAttribute("src","/extras/wobject/Calendar/images/delete.gif");
button.setAttribute("border","0");
var deleteLink = document.createElement("a");
deleteLink.setAttribute("href","#");
YAHOO.util.Event.addListener(deleteLink, "click", function (e, rowId) {
FeedsManager.deleteFeed('feeds',rowId);
YAHOO.util.Event.preventDefault(e);
}, rowId);
deleteLink.appendChild(button);
cells[0].appendChild(deleteLink);
/*** [1] - Feed link for teh clicking and form element for teh saving */
var feedLink = document.createElement("a");
feedLink.setAttribute("href",params.url);
feedLink.setAttribute("target","_new"); // TODO: Use JS to open window. target="" is deprecated
feedLink.appendChild(document.createTextNode(params.url));
var formElement = document.createElement("input");
formElement.setAttribute("type","hidden");
formElement.setAttribute("name","feeds-"+rowId);
formElement.setAttribute("value",params.url);
cells[1].appendChild(feedLink);
cells[1].appendChild(formElement);
/*** [2] - Result (new) */
if (params.lastResult == undefined)
params.lastResult = "new";
var lastResult = document.createTextNode(params.lastResult);
cells[2].appendChild(lastResult);
/*** [3] - Last updated */
if (params.lastUpdated == undefined)
params.lastUpdated = "never";
var lastUpdated = document.createTextNode(params.lastUpdated);
cells[3].appendChild(lastUpdated);
/*** [4] - Update now! */
/* TODO */
/* Add the row to the table */
var row = document.createElement("tr");
row.setAttribute("id",rowId);
for (var i = 0; i < cells.length; i++)
row.appendChild(cells[i]);
var tbody = table.getElementsByTagName('tbody')[0];
if (tbody)
tbody.appendChild(row);
else
table.appendChild(row);
FeedsManager.updateFeed(table.getAttribute("id"),rowId);
}
FeedsManager.updateFeed = function (table,rowId) {
/* TODO */
}
FeedsManager.deleteFeed = function (table,rowId) {
row = document.getElementById(rowId);
row.parentNode.removeChild(row);
}
FeedsManager.setFeed = function (table,rowId,params) {
}
</script>
ENDJS
my $addFeed = $i18n->get('Add a feed');
my $add = $i18n->get('Add');
my $feedUrl = $i18n->get('Feed URL');
my $status = $i18n->get('434', 'WebGUI');
my $lastUpdated = $i18n->get('454', 'WebGUI');
$tab->raw(<<"ENDHTML");
<label for="addFeed">$addFeed</label>
<input type="text" size="60" id="addFeed" name="addFeed" value="" />
<input type="button" value="$add" onclick="FeedsManager.addFeed('feeds','new',{ 'url' : this.form.addFeed.value }); this.form.addFeed.value=''" />
<table id="feeds" style="width: 100%;">
<thead>
<th style="width: 30px;">&nbsp;</th>
<th style="width: 50%;">$feedUrl</th>
<th>$status</th>
<th>$lastUpdated</th>
<th>&nbsp;</th>
</thead>
</table>
ENDHTML
# Add the existing feeds
my $feeds = $self->getFeeds();
$tab->raw('<script type="text/javascript">'."\n");
for my $feed (@{ $feeds }) {
my $feedId = $feed->{feedId};
$tab->raw("FeedsManager.addFeed('feeds','".$feedId."',".JSON->new->encode( $feed ).");\n");
}
$tab->raw('</script>');
$tab->raw("</td></tr>");
return $form;
};
sub getEditTabs {
my ( $self ) = @_;
my $i18n = WebGUI::International->new($self->session,"Asset_Calendar");
return $self->SUPER::getEditTabs, ["feeds",$i18n->get("feeds"), 6];
}
#----------------------------------------------------------------------------
@ -769,7 +641,7 @@ sub getEventsIn {
&& Event.endTime IS NULL
&&
!(
Event.startDate > '$endDate'
Event.startDate > SUBDATE('$endDate', INTERVAL 1 DAY)
|| Event.endDate < '$startDate'
)
)
@ -794,7 +666,7 @@ sub getEventsIn {
my $orderby = join ',', @order_priority;
my $events
= $self->getLineage(["descendants"], {
= $self->getLineage(["children"], {
returnObjects => 1,
includeOnlyClasses => ['WebGUI::Asset::Event'],
joinClass => 'WebGUI::Asset::Event',
@ -1004,37 +876,6 @@ override processPropertiesFromFormPost => sub {
$self->createSubscriptionGroup();
}
$self->session->errorHandler->info( "DEFAULT VIEW:" . $self->defaultView );
### Get feeds from the form
# Workaround WebGUI::Session::Form->param bug that returns duplicate
# names.
my %feeds;
for my $feedId ( grep /^feeds-/, ($form->param()) ) {
$feedId =~ s/^feeds-//;
$feeds{$feedId}++;
}
my @feedsFromForm = keys %feeds;
# Delete old feeds that are not in @feeds
my @oldFeeds = map { $_->{feedId} } @{ $self->getFeeds };
for my $feedId (@oldFeeds) {
if (!isIn($feedId, @feedsFromForm)) {
$self->deleteFeed($feedId);
}
}
# Create new feeds
for my $feedId (grep /^new(\d+)/, @feedsFromForm) {
$self->addFeed({
url => $form->param("feeds-".$feedId),
feedType => "ical",
lastUpdated => 'never',
lastResult => '',
});
}
return;
};

View file

@ -1176,7 +1176,7 @@ sub getThreadsPaginator {
$sortBy =~ s/^\w+\.//;
# Sort by the thread rating instead of the post rating. other places don't care about threads.
$sortBy = $sortBy eq 'rating' ? 'threadRating' : $sortBy;
if (! WebGUI::Utility::isIn($sortBy, qw/userDefined1 userDefined2 userDefined3 userDefined4 userDefined5 title lineage revisionDate creationDate karmaRank threadRating/)) {
if (! WebGUI::Utility::isIn($sortBy, qw/userDefined1 userDefined2 userDefined3 userDefined4 userDefined5 title lineage revisionDate creationDate karmaRank threadRating views replies lastPostDate/)) {
$sortBy = 'revisionDate';
}
if ($sortBy eq 'assetId' || $sortBy eq 'revisionDate') {

View file

@ -411,7 +411,7 @@ sub view {
$rules{assetToPedigree} = $current if (isIn("pedigree",@includedRelationships));
$rules{ancestorLimit} = $self->ancestorEndPoint;
$rules{orderByClause} = 'rpad(asset.lineage, 255, 9) desc' if ($self->reversePageLoop);
my $assets = $start->getLineage(\@includedRelationships,\%rules);
my $assetIter = $start->getLineageIterator(\@includedRelationships,\%rules);
my $currentLineage = $current->lineage;
my $lineageToSkip = "noskip";
my $absoluteDepthOfLastPage;
@ -419,7 +419,15 @@ sub view {
my %lastChildren;
my $previousPageData = undef;
my $eh = $self->session->errorHandler;
while ( my $asset = $assets->() ) {
while ( 1 ) {
my $asset;
eval { $asset = $assetIter->() };
if ( my $x = WebGUI::Error->caught('WebGUI::Error::ObjectNotFound') ) {
$self->session->log->error($x->full_message);
next;
}
last unless $asset;
# skip pages we shouldn't see
my $pageLineage = $asset->lineage;
next if ($pageLineage =~ m/^$lineageToSkip/);

View file

@ -288,9 +288,14 @@ sub getFolder {
##For a fully automatic commit, save the current tag, create a new one
##with the commit without approval workflow, commit it, then restore
##the original if it exists
my $oldVersionTag = WebGUI::VersionTag->getWorking($session, 'noCreate');
my $newVersionTag = WebGUI::VersionTag->create($session, { workflowId => 'pbworkflow00000000003', });
$newVersionTag->setWorking;
my ($oldVersionTag, $newVersionTag);
$oldVersionTag = WebGUI::VersionTag->getWorking($session, 'noCreate');
if ($self->hasBeenCommitted) {
$newVersionTag = WebGUI::VersionTag->create($session, { workflowId => 'pbworkflow00000000003', });
$newVersionTag->setWorking;
$newVersionTag->set({ name => 'Adding folder '. $folderName. ' to archive '. $self->getUrl});
}
##Call SUPER because my addChild calls getFolder
$folder = $self->addChild({
@ -301,7 +306,7 @@ sub getFolder {
isHidden => 1,
styleTemplateId => $self->styleTemplateId,
});
$newVersionTag->commit();
$newVersionTag->commit() if $newVersionTag;
##Restore the old one, if it exists
$oldVersionTag->setWorking() if $oldVersionTag;

View file

@ -996,20 +996,8 @@ sub getFormPlugin {
eval { WebGUI::Pluggable::load($class) };
if ($class->isa('WebGUI::Form::List')) {
delete $param{size};
my $values = WebGUI::Operation::Shared::secureEval($session,$data->{possibleValues});
if (ref $values eq 'HASH') {
$param{options} = $values;
}
else{
my %options;
tie %options, 'Tie::IxHash';
foreach (split(/\n/x, $data->{possibleValues})) {
s/\s+$//x; # remove trailing spaces
$options{$_} = $_;
}
$param{options} = \%options;
}
$param{options} = $values;
}
if ($data->{fieldType} eq "YesNo") {
@ -2408,6 +2396,8 @@ sub editThingData {
my $thingId = shift || $session->form->process('thingId');
my $thingDataId = shift || $session->form->process('thingDataId') || "new";
my $thingProperties = shift || $self->getThing($thingId);
my $errors = shift;
my $resetForm = shift;
my $i18n = WebGUI::International->new($self->session, "Asset_Thingy");
my $canEditThingData = $self->canEditThingData($thingId, $thingDataId, $thingProperties);
@ -2417,7 +2407,7 @@ sub editThingData {
my (%thingData, $fields,@field_loop,$fieldValue, $privilegedGroup);
my $var = $self->get;
my $url = $self->getUrl;
my $errors = shift;
$var->{error_loop} = $errors if ($errors);
$var->{canEditThings} = $self->canEdit;
@ -2465,14 +2455,17 @@ sub editThingData {
,[$self->getId,$thingId]);
while (my %field = $fields->hash) {
my $fieldName = 'field_'.$field{fieldId};
if ($session->form->process("func") eq "editThingDataSave"){
$fieldValue = $session->form->process($fieldName,$field{fieldType},$field{defaultValue});
$fieldValue = undef;
unless ($resetForm) {
if ($session->form->process("func") eq "editThingDataSave"){
$fieldValue = $session->form->process($fieldName,$field{fieldType},$field{defaultValue});
}
else{
$fieldValue = $thingData{"field_".$field{fieldId}};
}
}
else{
$fieldValue = $thingData{"field_".$field{fieldId}};
}
$field{value} = $fieldValue || $field{defaultValue};
my $formElement .= $self->getFormElement(\%field);
$field{value} = $fieldValue || $field{defaultValue};
my $formElement .= $self->getFormPlugin(\%field,($resetForm eq ""))->toHtml;
my $hidden = ($field{status} eq "hidden" && !$self->session->var->isAdminOn);
my $value = $field{value};
@ -2546,7 +2539,7 @@ sub www_editThingDataSave {
return $self->www_viewThingData($thingId,$newThingDataId);
}
elsif ($thingProperties->{afterSave} eq "addThing") {
return $self->www_editThingData($thingId,"new");
return $self->www_editThingData($thingId,"new",undef,undef,"resetForm");
}
elsif ($thingProperties->{afterSave} =~ m/^searchOther_/x){
$otherThingId = $thingProperties->{afterSave};
@ -2556,7 +2549,7 @@ sub www_editThingDataSave {
elsif ($thingProperties->{afterSave} =~ m/^addOther_/x){
$otherThingId = $thingProperties->{afterSave};
$otherThingId =~ s/^addOther_//x;
return $self->www_editThingData($otherThingId,"new");
return $self->www_editThingData($otherThingId,"new",undef,undef,"resetForm");
}
# if afterSave is thingy default or in any other case return www_view()
else {
@ -3233,7 +3226,7 @@ $self->session->form->process($_) eq "") {
sequenceNumber');
while (my $field = $fields->hashRef) {
if ($field->{searchIn}){
my $searchForm = $self->getFormElement($field);
my $searchForm = $self->getFormPlugin($field, 1);
my $searchTextForm = WebGUI::Form::Text($self->session, {
name=>"field_".$field->{fieldId},
size=>25,
@ -3248,9 +3241,10 @@ sequenceNumber');
push(@searchFields_loop, {
"searchFields_fieldId" => $field->{fieldId},
"searchFields_label" => $field->{label},
"searchFields_form" => $searchForm,
"searchFields_form" => $searchForm->toHtml,
"searchFields_textForm" => $searchTextForm,
"searchFields_is".$fieldType => 1,
"searchFields_listType" => $searchForm->isa('WebGUI::Form::List'),
});
my @searchValue = $session->form->process("field_".$field->{fieldId});

View file

@ -353,7 +353,7 @@ sub view {
my $url = $self->session->url;
my $i18n = WebGUI::International->new($self->session, "Asset_UserList");
my (%var, @users, @profileField_loop, @profileFields);
my ($defaultPublicProfile, $defaultPublicEmail, $user, $sth, $sql, $profileField);
my ($user, $sth, $sql, $profileField);
my $currentUrlWithoutSort = $self->getUrl();
foreach ($form->param) {
@ -505,9 +505,6 @@ sub view {
$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'");
($defaultPublicEmail) = $self->session->db->quickArray("SELECT dataDefault FROM userProfileField WHERE fieldName='publicEmail'");
my $paginatePage = $form->param('pn') || 1;
my $currentUrl = $self->getUrl();
foreach ($form->param) {