From a4edea1e3c146b011dc61e97359deb2f6a13a3d7 Mon Sep 17 00:00:00 2001 From: Paul Driver Date: Mon, 8 Nov 2010 07:54:47 -0600 Subject: [PATCH] Better integration of Fork into AssetHelpers, fork startup --- app.psgi | 3 + lib/WebGUI/Asset.pm | 5 +- lib/WebGUI/AssetClipboard.pm | 23 +++--- lib/WebGUI/AssetExportHtml.pm | 2 +- lib/WebGUI/AssetHelper/CopyBranch.pm | 62 +++----------- lib/WebGUI/AssetHelper/ExportHtml.pm | 63 +++++--------- lib/WebGUI/AssetLineage.pm | 18 ++-- lib/WebGUI/Fork/ProgressBar.pm | 92 +++++++++++++++++---- lib/WebGUI/Fork/ProgressTree.pm | 20 ++--- lib/WebGUI/i18n/English/Fork_ProgressBar.pm | 5 ++ www/extras/Fork/redirect.js | 26 ++++-- www/extras/admin/admin.js | 3 +- 12 files changed, 162 insertions(+), 160 deletions(-) diff --git a/app.psgi b/app.psgi index bace19496..fe5ff6122 100644 --- a/app.psgi +++ b/app.psgi @@ -2,11 +2,14 @@ use strict; use Plack::Builder; use WebGUI::Paths -inc; use WebGUI::Config; +use WebGUI::Fork; if ($ENV{PLACK_ENV} ne 'development') { WebGUI::Paths->preloadAll; } +WebGUI::Fork->init(); + builder { my $first_app; for my $config_file (WebGUI::Paths->siteConfigs) { diff --git a/lib/WebGUI/Asset.pm b/lib/WebGUI/Asset.pm index 2777240a0..ce7a8f497 100644 --- a/lib/WebGUI/Asset.pm +++ b/lib/WebGUI/Asset.pm @@ -883,6 +883,8 @@ sub forkWithStatusPage { $args->{plugin}, { title => $i18n->get( $args->{title} ), icon => 'assets', + dialog => $args->{dialog}, + message => $args->{message}, proceed => $args->{redirect} || '', } ); @@ -2612,7 +2614,8 @@ sub urlExists { =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 diff --git a/lib/WebGUI/AssetClipboard.pm b/lib/WebGUI/AssetClipboard.pm index 61fe3fb07..e9e63c8ef 100644 --- a/lib/WebGUI/AssetClipboard.pm +++ b/lib/WebGUI/AssetClipboard.pm @@ -46,8 +46,9 @@ paste a wiki page anywhere else but a wiki master. =cut sub canPaste { - my $self = shift; - return $self->validParent($self->session); ##Lazy call to a class method + my $self = shift; + my $class = ref $self; + return $class->validParent($self->session); } #------------------------------------------------------------------- @@ -61,7 +62,7 @@ WebGUI::Fork method called by www_copy sub copyInFork { my ($process, $args) = @_; my $session = $process->session; - my $asset = WebGUI::Asset->new($session, $args->{assetId}); + my $asset = WebGUI::Asset->newById($session, $args->{assetId}); my @pedigree = ('self'); my $childrenOnly = 0; if ($args->{childrenOnly}) { @@ -285,11 +286,7 @@ sub paste { # Update lineage in search index. $self->purgeCache; - my $assetIter = $pastedAsset->getLineageIterator( - ['self', 'descendants'], { - statesToInclude => ['clipboard','clipboard-limbo'] - } - ); + my $assetIter = $pastedAsset->getLineageIterator( ['self', 'descendants'] ); while ( 1 ) { my $asset; eval { $asset = $assetIter->() }; @@ -298,9 +295,7 @@ sub paste { next; } last unless $asset; - $outputSub->(sprintf $i18n->get('indexing %s'), $pastedAsset->getTitle) if defined $outputSub; - $asset->setState('published'); $asset->indexContent(); } $pastedAsset->updateHistory("pasted to parent ".$self->getId); @@ -321,8 +316,10 @@ WebGUI::Fork method called by www_pasteList sub pasteInFork { my ( $process, $args ) = @_; my $session = $process->session; - my $self = WebGUI::Asset->new( $session, $args->{assetId} ); - my @roots = grep { $_ && $_->canEdit } + my $self = WebGUI::Asset->newById( $session, $args->{assetId} ); + $session->asset($self); + + my @roots = grep { $_ && $_->canEdit } map { WebGUI::Asset->newPending( $session, $_ ) } @{ $args->{list} }; my @ids = map { @@ -733,7 +730,7 @@ sub www_pasteList { my $self = shift; my $session = $self->session; my $form = $session->form; - return $session->privilege->insufficient() unless $self->canEdit && $session->form->validToken; + return $session->privilege->insufficient() unless $self->canEdit; $self->forkWithStatusPage( { plugin => 'ProgressTree', diff --git a/lib/WebGUI/AssetExportHtml.pm b/lib/WebGUI/AssetExportHtml.pm index 99e5a57ec..a82ab6017 100644 --- a/lib/WebGUI/AssetExportHtml.pm +++ b/lib/WebGUI/AssetExportHtml.pm @@ -660,7 +660,7 @@ specified asset and keeps a json structure as the status. sub exportInFork { my ( $process, $args ) = @_; 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}; my $assetIds = $self->exportGetDescendants( undef, $args->{depth} ); my $tree = WebGUI::ProgressTree->new( $session, $assetIds ); diff --git a/lib/WebGUI/AssetHelper/CopyBranch.pm b/lib/WebGUI/AssetHelper/CopyBranch.pm index 5da8145cc..3dd3413cf 100644 --- a/lib/WebGUI/AssetHelper/CopyBranch.pm +++ b/lib/WebGUI/AssetHelper/CopyBranch.pm @@ -80,59 +80,21 @@ Perform the copy operation, showing the progress. =cut sub www_copy { - my ( $class, $asset ) = @_; + my ($class, $asset) = @_; my $session = $asset->session; - my $i18n = WebGUI::International->new($session, 'Asset'); - my $childrenOnly = lc $session->form->get('with') eq 'children'; - - return $session->response->stream( sub { - my ( $session ) = @_; - my @stack; - - my $pb = WebGUI::ProgressBar->new($session); - return $pb->run( - admin => 1, - 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); - }, + $asset->forkWithStatusPage({ + plugin => 'ProgressTree', + title => 'Copy Assets', + method => 'copyInFork', + dialog => 1, + message => 'Your assets are now copied!', + args => { + childrenOnly => $session->form->get('with') eq 'Children', + assetId => $asset->getId, } - ); - } ); + } + ); } 1; diff --git a/lib/WebGUI/AssetHelper/ExportHtml.pm b/lib/WebGUI/AssetHelper/ExportHtml.pm index 599bf506b..60e2f0329 100644 --- a/lib/WebGUI/AssetHelper/ExportHtml.pm +++ b/lib/WebGUI/AssetHelper/ExportHtml.pm @@ -157,50 +157,25 @@ Displays the export status page sub www_exportStatus { my ($class, $asset) = @_; my $session = $asset->session; - return $session->privilege->insufficient() unless ($session->user->isInGroup(13)); - my $i18n = WebGUI::International->new($session, "Asset"); - my $pb = WebGUI::ProgressBar->new( $session ); - - my $args = { - quiet => 1, # We'll wrap subs to update the ProgressBar - userId => $session->form->process('userId'), - indexFileName => $session->form->process('index'), - extrasUploadAction => $session->form->process('extrasUploadsAction'), - rootUrlAction => $session->form->process('rootUrlAction'), - depth => $session->form->process('depth'), - exportUrl => $session->form->process('exportUrl'), - }; - - return $session->response->stream( sub { - my ( $session ) = @_; - 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); - }, - }, - ); - } ); + return $session->privilege->insufficient + unless $session->user->isInGroup(13); + my $form = $session->form; + my @vars = qw( + index depth userId extrasUploadsAction rootUrlAction exportUrl + ); + $asset->forkWithStatusPage({ + plugin => 'ProgressTree', + title => 'Page Export Status', + method => 'exportInFork', + dialog => 1, + message => 'Your assets have been exported!', + groupId => 13, + args => { + assetId => $asset->getId, + map { $_ => scalar $form->get($_) } @vars + } + } + ); } 1; diff --git a/lib/WebGUI/AssetLineage.pm b/lib/WebGUI/AssetLineage.pm index 4ef53848b..e914485a4 100644 --- a/lib/WebGUI/AssetLineage.pm +++ b/lib/WebGUI/AssetLineage.pm @@ -17,6 +17,7 @@ package WebGUI::Asset; use strict; use Carp qw( croak ); use Scalar::Util qw( weaken ); +use List::Util qw(first); =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. @@ -1076,15 +1077,10 @@ The potential parent. If not passed, uses $session->asset; =cut sub validParent { - my $class = shift; - my $session = shift; - my $asset = shift || $session->asset; - return 0 unless $asset; - my $parent_classes = $class->valid_parent_classes; - foreach my $parentClass (@{ $class->valid_parent_classes}) { - return 1 if $asset->isa($parentClass); - } - return 0; + my $class = shift; + my $session = shift; + my $asset = shift || $session->asset || return 0; + return first { $asset->isa($_) } @{ $class->valid_parent_classes }; } #------------------------------------------------------------------- diff --git a/lib/WebGUI/Fork/ProgressBar.pm b/lib/WebGUI/Fork/ProgressBar.pm index 4969980bb..c3982fae9 100644 --- a/lib/WebGUI/Fork/ProgressBar.pm +++ b/lib/WebGUI/Fork/ProgressBar.pm @@ -35,6 +35,23 @@ These subroutines are available from this package: use Template; use HTML::Entities; use JSON; +use URI; + +my $blank = <<'TEMPLATE'; + + + [% title %] + [% FOREACH sheet IN stylesheets %] + + [% END %] + [% FOREACH script IN scripts %] + + [% END %] + +
[% bookmark.label %]
+ [% content %] + +TEMPLATE my $template = <<'TEMPLATE';
[% i18n('WebGUI', 'Loading...') %]
@@ -64,7 +81,7 @@ my $template = <<'TEMPLATE'; document.getElementById('ui').style.display = 'block'; }, finish : function() { - YAHOO.WebGUI.Fork.redirect(params.redirect); + YAHOO.WebGUI.Fork.redirect(params); }, error : function (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 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 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 sub renderBar { - my ( $process, $template ) = @_; + my ( $process, $template, $extras ) = @_; my $session = $process->session; my $url = $session->url; - my $form = $session->form; - my $style = $session->style; + my $f = $session->form->paramsHashRef; 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 { my ($namespace, $key) = @_; return WebGUI::International->new($session, $namespace)->get($key); }, - params => JSON::encode_json( { - statusUrl => $url->page( $process->contentPairs('Status') ), - redirect => scalar $form->get('proceed'), - } - ), + params => JSON::encode_json(\%params), ); $tt->process( \$template, \%vars, \my $content ) or die $tt->error; - my $console = WebGUI::AdminConsole->new( $session, $form->get('icon') ); - $style->setLink( $url->extras("Fork/ProgressBar.css"), { rel => 'stylesheet' } ); - $style->setScript( $url->extras("$_.js") ) - for ( ( + my @sheets = ( + $url->extras("Fork/ProgressBar.css"), + @{ $extras->{css} || []} + ); + my @scripts = ( ( + map { $url->extras("$_.js") } ( map {"yui/build/$_"} qw( yahoo/yahoo-min @@ -133,8 +160,39 @@ sub renderBar { 'Fork/ProgressBar', 'Fork/poll', '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 1; diff --git a/lib/WebGUI/Fork/ProgressTree.pm b/lib/WebGUI/Fork/ProgressTree.pm index 5ad75f1fc..d361e2608 100644 --- a/lib/WebGUI/Fork/ProgressTree.pm +++ b/lib/WebGUI/Fork/ProgressTree.pm @@ -114,7 +114,7 @@ my $template = <<'TEMPLATE'; document.getElementById('ui').style.display = 'block'; }, finish : function () { - YAHOO.WebGUI.Fork.redirect(params.redirect); + YAHOO.WebGUI.Fork.redirect(params); }, error : function (msg) { alert(msg) @@ -125,15 +125,6 @@ my $template = <<'TEMPLATE'; TEMPLATE -my $stylesheet = <<'STYLESHEET'; - -STYLESHEET - #------------------------------------------------------------------- =head2 handler ( process ) @@ -145,11 +136,12 @@ See WebGUI::Operation::Fork. sub handler { my $process = shift; my $session = $process->session; - my $style = $session->style; my $url = $session->url; - $style->setRawHeadTags($stylesheet); - $style->setScript($url->extras('underscore/underscore-min.js')); - WebGUI::Fork::ProgressBar::renderBar($process, $template); + WebGUI::Fork::ProgressBar::renderBar($process, $template, { + css => [ $url->extras('Fork/ProgressTree.css') ], + js => [ $url->extras('underscore/underscore-min.js') ], + } + ); } 1; diff --git a/lib/WebGUI/i18n/English/Fork_ProgressBar.pm b/lib/WebGUI/i18n/English/Fork_ProgressBar.pm index 8556eb06e..66a36bd22 100644 --- a/lib/WebGUI/i18n/English/Fork_ProgressBar.pm +++ b/lib/WebGUI/i18n/English/Fork_ProgressBar.pm @@ -3,6 +3,11 @@ package WebGUI::i18n::English::Fork_ProgressBar; use strict; our $I18N = { + 'link to this page' => { + message => 'Link to this page', + lastUpdated => 1288884190, + context => 'Label for the link to this status page', + }, 'time elapsed' => { message => 'Time Elapsed', lastUpdated => 1286466369, diff --git a/www/extras/Fork/redirect.js b/www/extras/Fork/redirect.js index bf4c061e3..cfabed151 100644 --- a/www/extras/Fork/redirect.js +++ b/www/extras/Fork/redirect.js @@ -3,14 +3,24 @@ (function () { var ns = YAHOO.namespace('WebGUI.Fork'); - ns.redirect = function (redir, after) { - if (!redir) { - return; + ns.redirect = function (params, after) { + var redir, msg, admin, fn; + 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); }; }()); diff --git a/www/extras/admin/admin.js b/www/extras/admin/admin.js index 0f91c6e1a..25aa47a7e 100644 --- a/www/extras/admin/admin.js +++ b/www/extras/admin/admin.js @@ -354,7 +354,8 @@ WebGUI.Admin.prototype.addPasteHandler */ WebGUI.Admin.prototype.pasteAsset = 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 ); };