Better integration of Fork into AssetHelpers, fork startup

This commit is contained in:
Paul Driver 2010-11-08 07:54:47 -06:00
parent bb8753cd2a
commit a4edea1e3c
12 changed files with 162 additions and 160 deletions

View file

@ -2,11 +2,14 @@ use strict;
use Plack::Builder; use Plack::Builder;
use WebGUI::Paths -inc; use WebGUI::Paths -inc;
use WebGUI::Config; use WebGUI::Config;
use WebGUI::Fork;
if ($ENV{PLACK_ENV} ne 'development') { if ($ENV{PLACK_ENV} ne 'development') {
WebGUI::Paths->preloadAll; WebGUI::Paths->preloadAll;
} }
WebGUI::Fork->init();
builder { builder {
my $first_app; my $first_app;
for my $config_file (WebGUI::Paths->siteConfigs) { for my $config_file (WebGUI::Paths->siteConfigs) {

View file

@ -883,6 +883,8 @@ sub forkWithStatusPage {
$args->{plugin}, { $args->{plugin}, {
title => $i18n->get( $args->{title} ), title => $i18n->get( $args->{title} ),
icon => 'assets', icon => 'assets',
dialog => $args->{dialog},
message => $args->{message},
proceed => $args->{redirect} || '', proceed => $args->{redirect} || '',
} }
); );
@ -2612,7 +2614,8 @@ sub urlExists {
=head2 valid_parent_classes ( ) =head2 valid_parent_classes ( )
The default view method for any asset that doesn't define one. Under all normal circumstances this should be overridden or your asset won't have any output. Returns an arrayref of classes that this asset is allowed to be a child of. If
a candidate parent passes ->isa for any of these it is a valid parent.
=cut =cut

View file

@ -46,8 +46,9 @@ paste a wiki page anywhere else but a wiki master.
=cut =cut
sub canPaste { sub canPaste {
my $self = shift; my $self = shift;
return $self->validParent($self->session); ##Lazy call to a class method my $class = ref $self;
return $class->validParent($self->session);
} }
#------------------------------------------------------------------- #-------------------------------------------------------------------
@ -61,7 +62,7 @@ WebGUI::Fork method called by www_copy
sub copyInFork { sub copyInFork {
my ($process, $args) = @_; my ($process, $args) = @_;
my $session = $process->session; my $session = $process->session;
my $asset = WebGUI::Asset->new($session, $args->{assetId}); my $asset = WebGUI::Asset->newById($session, $args->{assetId});
my @pedigree = ('self'); my @pedigree = ('self');
my $childrenOnly = 0; my $childrenOnly = 0;
if ($args->{childrenOnly}) { if ($args->{childrenOnly}) {
@ -285,11 +286,7 @@ sub paste {
# Update lineage in search index. # Update lineage in search index.
$self->purgeCache; $self->purgeCache;
my $assetIter = $pastedAsset->getLineageIterator( my $assetIter = $pastedAsset->getLineageIterator( ['self', 'descendants'] );
['self', 'descendants'], {
statesToInclude => ['clipboard','clipboard-limbo']
}
);
while ( 1 ) { while ( 1 ) {
my $asset; my $asset;
eval { $asset = $assetIter->() }; eval { $asset = $assetIter->() };
@ -298,9 +295,7 @@ sub paste {
next; next;
} }
last unless $asset; last unless $asset;
$outputSub->(sprintf $i18n->get('indexing %s'), $pastedAsset->getTitle) if defined $outputSub; $outputSub->(sprintf $i18n->get('indexing %s'), $pastedAsset->getTitle) if defined $outputSub;
$asset->setState('published');
$asset->indexContent(); $asset->indexContent();
} }
$pastedAsset->updateHistory("pasted to parent ".$self->getId); $pastedAsset->updateHistory("pasted to parent ".$self->getId);
@ -321,8 +316,10 @@ WebGUI::Fork method called by www_pasteList
sub pasteInFork { sub pasteInFork {
my ( $process, $args ) = @_; my ( $process, $args ) = @_;
my $session = $process->session; my $session = $process->session;
my $self = WebGUI::Asset->new( $session, $args->{assetId} ); my $self = WebGUI::Asset->newById( $session, $args->{assetId} );
my @roots = grep { $_ && $_->canEdit } $session->asset($self);
my @roots = grep { $_ && $_->canEdit }
map { WebGUI::Asset->newPending( $session, $_ ) } @{ $args->{list} }; map { WebGUI::Asset->newPending( $session, $_ ) } @{ $args->{list} };
my @ids = map { my @ids = map {
@ -733,7 +730,7 @@ sub www_pasteList {
my $self = shift; my $self = shift;
my $session = $self->session; my $session = $self->session;
my $form = $session->form; my $form = $session->form;
return $session->privilege->insufficient() unless $self->canEdit && $session->form->validToken; return $session->privilege->insufficient() unless $self->canEdit;
$self->forkWithStatusPage( { $self->forkWithStatusPage( {
plugin => 'ProgressTree', plugin => 'ProgressTree',

View file

@ -660,7 +660,7 @@ specified asset and keeps a json structure as the status.
sub exportInFork { sub exportInFork {
my ( $process, $args ) = @_; my ( $process, $args ) = @_;
my $session = $process->session; my $session = $process->session;
my $self = WebGUI::Asset->new( $session, delete $args->{assetId} ); my $self = WebGUI::Asset->newById( $session, delete $args->{assetId} );
$args->{indexFileName} = delete $args->{index}; $args->{indexFileName} = delete $args->{index};
my $assetIds = $self->exportGetDescendants( undef, $args->{depth} ); my $assetIds = $self->exportGetDescendants( undef, $args->{depth} );
my $tree = WebGUI::ProgressTree->new( $session, $assetIds ); my $tree = WebGUI::ProgressTree->new( $session, $assetIds );

View file

@ -80,59 +80,21 @@ Perform the copy operation, showing the progress.
=cut =cut
sub www_copy { sub www_copy {
my ( $class, $asset ) = @_; my ($class, $asset) = @_;
my $session = $asset->session; my $session = $asset->session;
my $i18n = WebGUI::International->new($session, 'Asset');
my $childrenOnly = lc $session->form->get('with') eq 'children'; $asset->forkWithStatusPage({
plugin => 'ProgressTree',
return $session->response->stream( sub { title => 'Copy Assets',
my ( $session ) = @_; method => 'copyInFork',
my @stack; dialog => 1,
message => 'Your assets are now copied!',
my $pb = WebGUI::ProgressBar->new($session); args => {
return $pb->run( childrenOnly => $session->form->get('with') eq 'Children',
admin => 1, assetId => $asset->getId,
title => $i18n->get('Copy Assets'),
icon => $session->url->extras('adminConsole/assets.gif'),
code => sub {
my $bar = shift;
# First calculate the total
$bar->update("Preparing copy (i18n)");
$bar->total( $asset->getDescendantCount + 1 );
my $newAsset = $asset->duplicateBranch( $childrenOnly );
$bar->update($i18n->get('cut'));
my $title = sprintf("%s (%s)", $asset->getTitle, $i18n->get('copy'));
$newAsset->update({ title => $title });
$newAsset->cut;
my $result = WebGUI::VersionTag->autoCommitWorkingIfEnabled(
$session, {
allowComments => 1,
returnUrl => $asset->getUrl,
}
);
if ( $result eq 'redirect' ) {
return $asset->getUrl;
}
return;
},
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);
},
} }
); }
} ); );
} }
1; 1;

View file

@ -157,50 +157,25 @@ Displays the export status page
sub www_exportStatus { sub www_exportStatus {
my ($class, $asset) = @_; my ($class, $asset) = @_;
my $session = $asset->session; my $session = $asset->session;
return $session->privilege->insufficient() unless ($session->user->isInGroup(13)); return $session->privilege->insufficient
my $i18n = WebGUI::International->new($session, "Asset"); unless $session->user->isInGroup(13);
my $pb = WebGUI::ProgressBar->new( $session ); my $form = $session->form;
my @vars = qw(
my $args = { index depth userId extrasUploadsAction rootUrlAction exportUrl
quiet => 1, # We'll wrap subs to update the ProgressBar );
userId => $session->form->process('userId'), $asset->forkWithStatusPage({
indexFileName => $session->form->process('index'), plugin => 'ProgressTree',
extrasUploadAction => $session->form->process('extrasUploadsAction'), title => 'Page Export Status',
rootUrlAction => $session->form->process('rootUrlAction'), method => 'exportInFork',
depth => $session->form->process('depth'), dialog => 1,
exportUrl => $session->form->process('exportUrl'), message => 'Your assets have been exported!',
}; groupId => 13,
args => {
return $session->response->stream( sub { assetId => $asset->getId,
my ( $session ) = @_; map { $_ => scalar $form->get($_) } @vars
return $pb->run( }
admin => 1, }
title => $i18n->get('edit branch'), );
icon => $session->url->extras('adminConsole/assets.gif'),
code => sub {
my ( $bar ) = @_;
$bar->update( 'Preparing...' );
$bar->total( $asset->getDescendantCount );
$bar->update( 'Asset ID ' . $asset->getId );
my $message;
eval {
$message = $asset->exportAsHtml( $args );
};
if ( $@ ) {
return { error => "$@" };
}
return { message => $message || "Export successful!" };
},
wrap => {
'WebGUI::Asset::exportWriteFile' => sub {
my ($bar, $original, $asset, @args) = @_;
$bar->update( "Exporting " . $asset->getTitle );
return $asset->$original(@args);
},
},
);
} );
} }
1; 1;

View file

@ -17,6 +17,7 @@ package WebGUI::Asset;
use strict; use strict;
use Carp qw( croak ); use Carp qw( croak );
use Scalar::Util qw( weaken ); use Scalar::Util qw( weaken );
use List::Util qw(first);
=head1 NAME =head1 NAME
@ -1063,9 +1064,9 @@ sub swapRank {
#------------------------------------------------------------------- #-------------------------------------------------------------------
=head2 validParent ([$asset]) =head2 validParent ([$session, $asset])
Find out whether a potential parent can have this asset as a child. Find out whether assets of this class can be children of the given asset.
This is a class method. This is a class method.
@ -1076,15 +1077,10 @@ The potential parent. If not passed, uses $session->asset;
=cut =cut
sub validParent { sub validParent {
my $class = shift; my $class = shift;
my $session = shift; my $session = shift;
my $asset = shift || $session->asset; my $asset = shift || $session->asset || return 0;
return 0 unless $asset; return first { $asset->isa($_) } @{ $class->valid_parent_classes };
my $parent_classes = $class->valid_parent_classes;
foreach my $parentClass (@{ $class->valid_parent_classes}) {
return 1 if $asset->isa($parentClass);
}
return 0;
} }
#------------------------------------------------------------------- #-------------------------------------------------------------------

View file

@ -35,6 +35,23 @@ These subroutines are available from this package:
use Template; use Template;
use HTML::Entities; use HTML::Entities;
use JSON; use JSON;
use URI;
my $blank = <<'TEMPLATE';
<html>
<head>
<title>[% title %]</title>
[% FOREACH sheet IN stylesheets %]
<link rel='stylesheet' href='[% sheet %]'></link>
[% END %]
[% FOREACH script IN scripts %]
<script src='[% script %]'></script>
[% END %]
</head>
<div><a href='[% bookmark.url %]'>[% bookmark.label %]</a></div>
[% content %]
</html>
TEMPLATE
my $template = <<'TEMPLATE'; my $template = <<'TEMPLATE';
<div id='loading'>[% i18n('WebGUI', 'Loading...') %]</div> <div id='loading'>[% i18n('WebGUI', 'Loading...') %]</div>
@ -64,7 +81,7 @@ my $template = <<'TEMPLATE';
document.getElementById('ui').style.display = 'block'; document.getElementById('ui').style.display = 'block';
}, },
finish : function() { finish : function() {
YAHOO.WebGUI.Fork.redirect(params.redirect); YAHOO.WebGUI.Fork.redirect(params);
}, },
error : function (msg) { error : function (msg) {
alert(msg); alert(msg);
@ -87,40 +104,50 @@ sub handler { renderBar( shift, $template ) }
#------------------------------------------------------------------- #-------------------------------------------------------------------
=head2 renderBar ( process, template ) =head2 renderBar ( process, template, extras )
Renders $template, passing a "params" variable to it that is JSON of a Renders $template, passing a "params" variable to it that is JSON of a
statusUrl to poll and a page to redirect to and an i18n function. Includes statusUrl to poll and a page to redirect to and an i18n function. Includes
WebGUI.Fork.redirect, poll, and ProgressBar js and CSS (as well as all their WebGUI.Fork.redirect, poll, and ProgressBar js and CSS (as well as all their
YUI dependancies), and puts the whole template inside an adminConsole rendered YUI dependancies), and puts the whole template inside an adminConsole rendered
based off some form parameters. based off some form parameters. Extras is a hashref, optionally containing two
keys (css and js) which will be added to the page.
=cut =cut
sub renderBar { sub renderBar {
my ( $process, $template ) = @_; my ( $process, $template, $extras ) = @_;
my $session = $process->session; my $session = $process->session;
my $url = $session->url; my $url = $session->url;
my $form = $session->form; my $f = $session->form->paramsHashRef;
my $style = $session->style;
my $tt = Template->new; my $tt = Template->new;
my %vars = ( my $dialog = delete $f->{dialog};
my %params = (
statusUrl => $url->page( $process->contentPairs('Status') ),
);
if ($dialog) {
$params{message} = $f->{message};
}
else {
$params{redirect} = $f->{proceed};
}
my %vars = (
i18n => sub { i18n => sub {
my ($namespace, $key) = @_; my ($namespace, $key) = @_;
return WebGUI::International->new($session, $namespace)->get($key); return WebGUI::International->new($session, $namespace)->get($key);
}, },
params => JSON::encode_json( { params => JSON::encode_json(\%params),
statusUrl => $url->page( $process->contentPairs('Status') ),
redirect => scalar $form->get('proceed'),
}
),
); );
$tt->process( \$template, \%vars, \my $content ) or die $tt->error; $tt->process( \$template, \%vars, \my $content ) or die $tt->error;
my $console = WebGUI::AdminConsole->new( $session, $form->get('icon') ); my @sheets = (
$style->setLink( $url->extras("Fork/ProgressBar.css"), { rel => 'stylesheet' } ); $url->extras("Fork/ProgressBar.css"),
$style->setScript( $url->extras("$_.js") ) @{ $extras->{css} || []}
for ( ( );
my @scripts = ( (
map { $url->extras("$_.js") } (
map {"yui/build/$_"} map {"yui/build/$_"}
qw( qw(
yahoo/yahoo-min yahoo/yahoo-min
@ -133,8 +160,39 @@ sub renderBar {
'Fork/ProgressBar', 'Fork/ProgressBar',
'Fork/poll', 'Fork/poll',
'Fork/redirect' 'Fork/redirect'
),
@{ $extras->{js} || []}
);
my $link = URI->new($url->page);
my $title = encode_entities( $f->{title} );
my $label =
WebGUI::International->new( $session, 'Fork_ProgressBar' )
->get('link to this page');
if ($dialog) {
$link->query_form($f);
my %vars = (
content => $content,
scripts => \@scripts,
stylesheets => \@sheets,
title => $title,
bookmark => {
url => $link,
label => $label,
}
); );
return $console->render( $content, encode_entities( $form->get('title') ) ); $tt->process( \$blank, \%vars, \my $styled ) or die $tt->error;
return $styled;
}
else {
my $console = WebGUI::AdminConsole->new( $session, $f->{icon} );
my $style = $session->style;
$link->query_form($f);
$console->addSubmenuItem( $link->as_string, $label );
$style->setLink($_, { rel => 'stylesheet' }) for @sheets;
$style->setScript($_) for @scripts;
return $console->render( $content, $title );
}
} ## end sub renderBar } ## end sub renderBar
1; 1;

View file

@ -114,7 +114,7 @@ my $template = <<'TEMPLATE';
document.getElementById('ui').style.display = 'block'; document.getElementById('ui').style.display = 'block';
}, },
finish : function () { finish : function () {
YAHOO.WebGUI.Fork.redirect(params.redirect); YAHOO.WebGUI.Fork.redirect(params);
}, },
error : function (msg) { error : function (msg) {
alert(msg) alert(msg)
@ -125,15 +125,6 @@ my $template = <<'TEMPLATE';
</script> </script>
TEMPLATE TEMPLATE
my $stylesheet = <<'STYLESHEET';
<style>
#tree li { color: black }
#tree li.focus { color: cyan }
#tree li.failure { color: red }
#tree li.success { color: green }
</style>
STYLESHEET
#------------------------------------------------------------------- #-------------------------------------------------------------------
=head2 handler ( process ) =head2 handler ( process )
@ -145,11 +136,12 @@ See WebGUI::Operation::Fork.
sub handler { sub handler {
my $process = shift; my $process = shift;
my $session = $process->session; my $session = $process->session;
my $style = $session->style;
my $url = $session->url; my $url = $session->url;
$style->setRawHeadTags($stylesheet); WebGUI::Fork::ProgressBar::renderBar($process, $template, {
$style->setScript($url->extras('underscore/underscore-min.js')); css => [ $url->extras('Fork/ProgressTree.css') ],
WebGUI::Fork::ProgressBar::renderBar($process, $template); js => [ $url->extras('underscore/underscore-min.js') ],
}
);
} }
1; 1;

View file

@ -3,6 +3,11 @@ package WebGUI::i18n::English::Fork_ProgressBar;
use strict; use strict;
our $I18N = { our $I18N = {
'link to this page' => {
message => 'Link to this page',
lastUpdated => 1288884190,
context => 'Label for the link to this status page',
},
'time elapsed' => { 'time elapsed' => {
message => 'Time Elapsed', message => 'Time Elapsed',
lastUpdated => 1286466369, lastUpdated => 1286466369,

View file

@ -3,14 +3,24 @@
(function () { (function () {
var ns = YAHOO.namespace('WebGUI.Fork'); var ns = YAHOO.namespace('WebGUI.Fork');
ns.redirect = function (redir, after) { ns.redirect = function (params, after) {
if (!redir) { var redir, msg, admin, fn;
return; if (redir = params.redirect) {
fn = function () {
// The idea here is to only allow local redirects
var loc = window.location;
loc.href = loc.protocol + '//' + loc.host + redir;
};
}
else if (msg = params.message) {
fn = function () {
admin = window.parent.admin;
admin.processPlugin({ message: msg });
admin.closeModalDialog();
};
}
if (fn) {
setTimeout(fn, after || 1000);
} }
setTimeout(function() {
// The idea here is to only allow local redirects
var loc = window.location;
loc.href = loc.protocol + '//' + loc.host + redir;
}, after || 1000);
}; };
}()); }());

View file

@ -354,7 +354,8 @@ WebGUI.Admin.prototype.addPasteHandler
*/ */
WebGUI.Admin.prototype.pasteAsset WebGUI.Admin.prototype.pasteAsset
= function ( id ) { = function ( id ) {
var url = appendToUrl( this.currentAssetDef.url, 'func=paste;assetId=' + id ); var url = appendToUrl( this.currentAssetDef.url, 'func=pasteList&assetId=' + id );
console.log(url);
this.gotoAsset( url ); this.gotoAsset( url );
}; };