From 09ad8d2a118a0c6242ac2656c718644115454989 Mon Sep 17 00:00:00 2001 From: Colin Kuskie Date: Fri, 24 Apr 2009 00:05:09 +0000 Subject: [PATCH] Remove subclass exportHtml_view in favor of a session scratch variable for telling when the asset is being exported. Keyword files are exported into a private directory to prevent filename collisions. --- lib/WebGUI/Asset/Wobject/StoryArchive.pm | 100 ++++++++++++----------- lib/WebGUI/Asset/Wobject/StoryTopic.pm | 24 +----- lib/WebGUI/AssetExportHtml.pm | 24 +++++- t/Asset/Wobject/StoryArchive.t | 13 +-- t/Asset/Wobject/StoryTopic.t | 4 +- 5 files changed, 85 insertions(+), 80 deletions(-) diff --git a/lib/WebGUI/Asset/Wobject/StoryArchive.pm b/lib/WebGUI/Asset/Wobject/StoryArchive.pm index 6004c8989..303bea09f 100644 --- a/lib/WebGUI/Asset/Wobject/StoryArchive.pm +++ b/lib/WebGUI/Asset/Wobject/StoryArchive.pm @@ -23,6 +23,7 @@ use WebGUI::Keyword; use WebGUI::Search; use Class::C3; use base qw/WebGUI::AssetAspect::RssFeed WebGUI::Asset::Wobject/; +use File::Path; use constant DATE_FORMAT => '%c_%D_%y'; @@ -187,40 +188,40 @@ sub exportAssetCollateral { my $basename = $basepath->basename; my $filedir; - my $filenameBase; - # We want our keyword files to "appear" at the same level as the asset. + # We want our keyword files to "appear" as children of the asset to avoid + # clashing with multiple story archives. if ($basename eq 'index.html') { - # Get the 2nd ancestor, since the asset url had no dot in it (and it therefore - # had its own directory created for it). - $filedir = $basepath->parent->parent->absolute->stringify; - # Get the parent dir's *path* (essentially the name of the dir) relative to - # its own parent dir. - $filenameBase = $basepath->parent->relative( $basepath->parent->parent )->stringify; + # Get the parent of the file index.html, which is the asset's directory. + $filedir = $basepath->parent->absolute->stringify; } else { - # Get the 1st ancestor, since the asset is a file recognized by apache, so - # we want our files in the same dir. - $filedir = $basepath->parent->absolute->stringify; - # just use the basename. - $filenameBase = $basename; + ##Create a directory that has the same base + my $dirname = $basename; + $dirname =~ s/\.\w+$//; + $filedir = $basepath->parent->subdir($dirname)->absolute->stringify; + eval { File::Path::mkpath($filedir) }; + if($@) { + WebGUI::Error->throw(error => "could not make directory " . $filedir); + } } if ( $reportSession && !$args->{quiet} ) { $reportSession->output->print('
'); } - # open another session as the user doing the exporting... - my $exportSession = WebGUI::Session->open( + # open another session to handle printing... + my $printSession = WebGUI::Session->open( $self->session->config->getWebguiRoot, $self->session->config->getFilename, undef, undef, $self->session->getId, ); + $printSession->scratch->set('isExporting', 1); - my $keywordObj = WebGUI::Keyword->new($exportSession); + my $keywordObj = WebGUI::Keyword->new($printSession); my $keywords = $keywordObj->findKeywords({ asset => $self, limit => 50, ##This is based on the tagcloud setting @@ -229,7 +230,7 @@ sub exportAssetCollateral { my $listTemplate = WebGUI::Asset->new($session, $self->get('keywordListTemplateId'), 'WebGUI::Asset::Template'); foreach my $keyword (@{ $keywords }) { ##Keywords may not be URL safe, so urlize them - my $keyword_url = $self->getKeywordStaticUrl($keyword); + my $keyword_url = $self->getKeywordFilename($keyword); my $dest = Path::Class::File->new($filedir, $keyword_url); # tell the user which asset we're exporting. @@ -242,10 +243,10 @@ sub exportAssetCollateral { # next, get the contents, open the file, and write the contents to the file. my $fh = eval { $dest->open('>:utf8') }; if($@) { - $exportSession->close; + $printSession->close; WebGUI::Error->throw(error => "can't open " . $dest->absolute->stringify . " for writing: $!"); } - $exportSession->output->setHandle($fh); + $printSession->output->setHandle($fh); my $storyIds = $keywordObj->getMatchingAssets({ startAsset => $self, @@ -268,7 +269,7 @@ sub exportAssetCollateral { }; my $output = $listTemplate->process($var); my $contents = $self->processStyle($output); - $exportSession->output->print($contents); + $printSession->output->print($contents); # tell the user we did this asset collateral correctly if ( $reportSession && !$args->{quiet} ) { @@ -277,30 +278,12 @@ sub exportAssetCollateral { $fh->flush; $fh->close; } - $exportSession->close; + $printSession->close; return $self->next::method($basepath, $args, $reportSession); } #------------------------------------------------------------------- -=head2 exportHtml_view ( ) - -Extend the base method to change how the tag cloud works and the search -interface. - -Sets an internal flag to indicate that it is exporting to signal viewTemplateVars -to make those changes. - -=cut - -sub exportHtml_view { - my $self = shift; - $self->{_exportMode} = 1; - return $self->next::method(@_); -} - -#------------------------------------------------------------------- - =head2 getFolder ( date ) Stories are stored in Folders under the Story Archive to prevent lineage issues. @@ -351,9 +334,9 @@ sub getFolder { #------------------------------------------------------------------- -=head2 getKeywordStaticUrl ( $keyword ) +=head2 getKeywordFilename ( $keyword ) -Returns the URL for the file containing stories that match this keyword. Used +Returns the name for the file containing stories that match this keyword. Used in exportAssetCollateral, and in viewTemplateVariables. =head3 $keyword @@ -362,13 +345,31 @@ The keyword to generate a URL for. =cut -sub getKeywordStaticUrl { +sub getKeywordFilename { my ($self,$keyword) = @_; return $self->session->url->urlize('keyword_'.$keyword.'.html'); } #------------------------------------------------------------------- +=head2 getKeywordStaticURL ( $keyword ) + +Returns the whole URL for the file containing stories that match this keyword. Used +in exportAssetCollateral. + +=head3 $keyword + +The keyword to generate a URL for. + +=cut + +sub getKeywordStaticURL { + my ($self,$keyword) = @_; + return join '/', $self->getUrl, $self->getKeywordFilename($keyword); +} + +#------------------------------------------------------------------- + =head2 getRssFeedItems ( ) Returns an arrayref of hashrefs, containing information on stories @@ -468,6 +469,7 @@ sub viewTemplateVariables { my $session = $self->session; my $keywords = $session->form->get('keyword'); my $query = $session->form->get('query'); + my $exporting = $session->scratch->get('isExporting'); my $p; my $var = $self->get(); if ($mode eq 'keyword') { @@ -500,7 +502,7 @@ sub viewTemplateVariables { orderByClause => 'creationDate desc, lineage', }); my $storiesPerPage = $self->get('storiesPerPage'); - if ($self->{_exportMode}) { + if ($exporting) { ##10 pages worth of data on 1 page in export mode $storiesPerPage *= 10; } @@ -508,7 +510,7 @@ sub viewTemplateVariables { $p->setDataByQuery($storySql); } my $storyIds = $p->getPageData(); - if (! $self->{_exportMode} ) { + if (! $exporting ) { ##Pagination variables aren't useful in export mode $p->appendTemplateVars($var); } @@ -540,19 +542,19 @@ sub viewTemplateVariables { $var->{addStoryUrl} = $var->{canPostStories} ? $self->getUrl('func=add;class=WebGUI::Asset::Story') : ''; - $var->{rssUrl} = $self->{_exportMode} ? $self->getStaticRssFeedUrl : $self->getRssFeedUrl; - $var->{atomUrl} = $self->{_exportMode} ? $self->getStaticAtomFeedUrl : $self->getAtomFeedUrl; + $var->{rssUrl} = $exporting ? $self->getStaticRssFeedUrl : $self->getRssFeedUrl; + $var->{atomUrl} = $exporting ? $self->getStaticAtomFeedUrl : $self->getAtomFeedUrl; my $cloudOptions = { startAsset => $self, displayFunc => 'view', }; ##In export mode, tags should link to the pages generated during the collateral export - if($self->{_exportMode}) { - $cloudOptions->{urlCallback} = 'getKeywordStaticUrl'; + if($exporting) { + $cloudOptions->{urlCallback} = 'getKeywordFilename'; $cloudOptions->{displayFunc} = ''; } $var->{keywordCloud} = WebGUI::Keyword->new($session)->generateCloud($cloudOptions); - if (! $self->{_exportMode}) { + if (! $exporting) { my $i18n = WebGUI::International->new($session, 'Asset'); $var->{searchHeader} = WebGUI::Form::formHeader($session, { action => $self->getUrl }) . WebGUI::Form::hidden($session, { name => 'func', value => 'view' }); diff --git a/lib/WebGUI/Asset/Wobject/StoryTopic.pm b/lib/WebGUI/Asset/Wobject/StoryTopic.pm index 3edc29f37..c9132012a 100644 --- a/lib/WebGUI/Asset/Wobject/StoryTopic.pm +++ b/lib/WebGUI/Asset/Wobject/StoryTopic.pm @@ -86,23 +86,6 @@ sub definition { #------------------------------------------------------------------- -=head2 exportHtml_view ( ) - -Extend the base method to change how stories are linked to. - -Sets an internal flag to indicate that it is exporting to signal viewTemplateVars -to make those changes. - -=cut - -sub exportHtml_view { - my $self = shift; - $self->{_exportMode} = 1; - return $self->next::method(@_); -} - -#------------------------------------------------------------------- - =head2 getRssFeedItems ( ) Returns an arrayref of hashrefs, containing information on stories @@ -176,6 +159,7 @@ Make template variables for the view template. sub viewTemplateVariables { my ($self) = @_; my $session = $self->session; + my $exporting = $session->scratch->get('isExporting'); my $numberOfStories = $self->{_standAlone} ? $self->get('storiesPer') : $self->get('storiesShort'); @@ -195,7 +179,7 @@ sub viewTemplateVariables { my $story = WebGUI::Asset->new($session, $storyId->{assetId}, $storyId->{className}, $storyId->{revisionDate}); next STORY unless $story; push @{$var->{story_loop}}, { - url => ( $self->{_exportMode} + url => ( $exporting ? $story->getUrl : $session->url->append($self->getUrl, 'func=viewStory;assetId='.$storyId->{assetId}) ), title => $story->getTitle, @@ -230,8 +214,8 @@ sub viewTemplateVariables { } } $var->{standAlone} = $self->{_standAlone}; - $var->{rssUrl} = $self->{_exportMode} ? $self->getStaticRssFeedUrl : $self->getRssFeedUrl; - $var->{atomUrl} = $self->{_exportMode} ? $self->getStaticAtomFeedUrl : $self->getAtomFeedUrl; + $var->{rssUrl} = $exporting ? $self->getStaticRssFeedUrl : $self->getRssFeedUrl; + $var->{atomUrl} = $exporting ? $self->getStaticAtomFeedUrl : $self->getAtomFeedUrl; return $var; } diff --git a/lib/WebGUI/AssetExportHtml.pm b/lib/WebGUI/AssetExportHtml.pm index de2ea66be..6722db17f 100644 --- a/lib/WebGUI/AssetExportHtml.pm +++ b/lib/WebGUI/AssetExportHtml.pm @@ -128,7 +128,22 @@ sub exportCheckPath { Main logic hub for export functionality. This method calls most of the rest of the methods that handle exporting. Any exceptions thrown by the called methods are returned as strings to the caller. Returns a status description upon -completion. Takes a hashref of arguments, containing the following keys: +completion. + +Internally, it sets two scratch variables in private sessions that it creates +for exporting. + +=over 4 + +=item exportMode + +If this scratch variable exists, and is true, then the Asset is being exported. + +=item exportUrl + +This scratch variable is used by the Widget Macro. + +Takes a hashref of arguments, containing the following keys: =head3 quiet @@ -287,8 +302,9 @@ sub exportAsHtml { my $exportSession = WebGUI::Session->open($self->session->config->getWebguiRoot, $self->session->config->getFilename); $exportSession->user( { userId => $userId } ); - # set a scratch variable for widgets to know we're exporting - $exportSession->scratch->set('exportUrl', $exportUrl); + # set a scratch variable for Assets and widgets to know we're exporting + $exportSession->scratch->set('isExporting', 1); + $exportSession->scratch->set('exportUrl', $exportUrl); my $asset = WebGUI::Asset->newByDynamicClass($exportSession, $assetId); my $fullPath = $asset->exportGetUrlAsPath; @@ -517,6 +533,8 @@ Translates a URL into an appropriate path and filename for exporting. For example, given C<'/foo/bar/baz'>, will return C<'/foo/bar/baz/index.html'> provided the value of indexFile as given to exportAsHtml was C<'index.html'>. +Returns a Path::Class::File object. + =head3 url URL of the asset we need an export path for diff --git a/t/Asset/Wobject/StoryArchive.t b/t/Asset/Wobject/StoryArchive.t index d3bb95a24..86a87123a 100644 --- a/t/Asset/Wobject/StoryArchive.t +++ b/t/Asset/Wobject/StoryArchive.t @@ -161,14 +161,14 @@ is($folder->getFirstChild->getTitle, 'First Story', '... and it is the correct c ################################################################ # -# getKeywordStaticUrl +# getKeywordFilename # ################################################################ ##Note, this method depends heavily on the default installed language pack. ##Because of that, we'll only test for whether or not url->urlize is called. -is ($archive->getKeywordStaticUrl('camelCase'), 'keyword_camelcase.html', 'getKeywordStaticUrl returns a lower case keyword with _keyword.html appended'); +is ($archive->getKeywordFilename('camelCase'), 'keyword_camelcase.html', 'getKeywordFilename returns a lower case keyword with _keyword.html appended'); ################################################################ # @@ -410,7 +410,8 @@ cmp_bag( # ################################################################ -$archive->{_exportMode} = 1; + +$session->scratch->set('isExporting', 1); $archive->update({ storiesPerPage => 3, }); $templateVars = $archive->viewTemplateVariables(); ok( ( !exists $templateVars->{searchHeader} @@ -437,7 +438,7 @@ foreach my $date_loop (@{ $templateVars->{date_loop} }) { cmp_ok($storyCount, '>', 3, '... export mode, pagination increased beyond storiesPerPage'); -$archive->{_exportMode} = 0; +$session->scratch->delete('isExporting'); ################################################################ # @@ -463,7 +464,7 @@ cmp_bag( # ################################################################ -$archive->{_exportMode} = 1; +$session->scratch->set('isExporting', 1); $templateVars = $archive->viewTemplateVariables(); @anchors = simpleHrefParser($templateVars->{keywordCloud}); @@ -477,7 +478,7 @@ cmp_bag( 'keywordCloud template variable has keywords and correct links in export mode', ); -$archive->{_exportMode} = 0; +$session->scratch->delete('isExporting'); ################################################################ # diff --git a/t/Asset/Wobject/StoryTopic.t b/t/Asset/Wobject/StoryTopic.t index 2f396941e..bf24e09d4 100644 --- a/t/Asset/Wobject/StoryTopic.t +++ b/t/Asset/Wobject/StoryTopic.t @@ -237,7 +237,7 @@ cmp_deeply( 'viewTemplateVariables: is only finding things with its keywords' ); -$topic->{_exportMode} = 1; +$session->scratch->set('isExporting', 1); $topic->update({ storiesShort => 3, }); @@ -271,7 +271,7 @@ cmp_deeply( }), '... export mode, RSS and Atom feed template variables show the static url' ); -$topic->{_exportMode} = 0; +$session->scratch->delete('isExporting'); ################################################################ #