diff --git a/docs/upgrades/upgrade_6.1.1-6.2.0.sql b/docs/upgrades/upgrade_6.1.1-6.2.0.sql index b1751acad..f8440a47a 100644 --- a/docs/upgrades/upgrade_6.1.1-6.2.0.sql +++ b/docs/upgrades/upgrade_6.1.1-6.2.0.sql @@ -56,3 +56,7 @@ alter table WobjectProxy add proxyCriteria text default NULL; alter table IndexedSearch add column (forceSearchRoots smallint(1) default 1); alter table DataForm_field add column (vertical smallint(1) default 1); alter table DataForm_field add column (extras varchar(128)); + +INSERT INTO groups VALUES (13,'Export Managers','Users in this group can export pages to disk.',314496000,1000000000,NULL,997938000,997938000,14,-14,NULL,0,NULL,0,0,0,3600,NULL,1,1); + +INSERT INTO groupGroupings VALUES (3,13); diff --git a/lib/WebGUI.pm b/lib/WebGUI.pm index 742c12a60..7e4e9ab5c 100644 --- a/lib/WebGUI.pm +++ b/lib/WebGUI.pm @@ -177,8 +177,16 @@ sub page { $cache->set($output, $ttl) if ($useCache); } my $httpHeader = WebGUI::HTTP::getHeader(); + + # This allows an operation or wobject to write directly to the browser. + if ($session{page}{empty}) { + $httpHeader = $output = undef; + } + WebGUI::Session::close() unless ($useExistingSession); + return $httpHeader.$output; + } diff --git a/lib/WebGUI/Export.pm b/lib/WebGUI/Export.pm new file mode 100644 index 000000000..93c8afe7d --- /dev/null +++ b/lib/WebGUI/Export.pm @@ -0,0 +1,283 @@ +package WebGUI::Export; + + +=head1 LEGAL + + ------------------------------------------------------------------- + WebGUI is Copyright 2001-2004 Plain Black LLC. + ------------------------------------------------------------------- + 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 + ------------------------------------------------------------------- + +=cut + +use strict; +use WebGUI::Session; +use WebGUI::HTML; + +=head1 NAME + +Package WebGUI::Export + +=head1 DESCRIPTION + +This package provides methods to export WebGUI content. + +=head1 SYNOPSIS + + use WebGUI::Export; + + # Generate an export of current page: + $e = new WebGUI::Export(); + $html = $e->generate; + + # Generate an export of pageId 238: + $e = new WebGUI::Export(); + $e->set(pageId=>238); + $html = $e->generate; + + # Some more options + $e = new WebGUI::Export( + pageId => 1021, + styleId => 1000, + userId => 3, + altSiteURL => "http://www.exportsite.nl/", + extrasURL => "http://www.webguisite.com/extras" + ); + $e->generate; + +=head1 METHODS + +These methods are available from this package: + +=cut + +#------------------------------------------------------------------- + +=head2 generate ( ) + +Executes the export and returns html content. + +=over + +=item filename + +Full path to a file. + +=back + +=cut + +sub generate { + my $self = shift; + my $fileName = shift; + + # Save current session information because we need to restore current session after + # the export has finished. + my %oldSession = %session; + + # Refresh session for userId, defaults to visitor + WebGUI::Session::refreshUserInfo($self->get('userId') || 1,$session{dbh}); + + # Delete all form parameters + delete $session{form}; + + # Admin bar + $session{var}{adminOn} = $self->get('adminOn'); + + # Set the page to export. + WebGUI::Session::refreshPageInfo($self->get('pageId')); + + # Caching + if($self->get('noCache')) { + $session{page}{cacheTimeout} = 0; + $session{page}{cacheTimeoutVisitor} = 0; + } + + # Uploads / Extras URL + $session{config}{uploadsURL} = $self->get('uploadsURL') || $session{config}{uploadsURL}; + $session{config}{extrasURL} = $self->get('extrasURL') || $session{config}{extrasURL}; + + # Disable printing of HTTP Header if requested. + if($self->get('noHttpHeader')) { + $session{page}{noHttpHeader} = 1; + } + + # Set alternate Site URL + if($self->get('altSiteURL')) { + $session{var}{altSiteURL} = $self->get('altSiteURL'); + } elsif ($self->get('relativeUrls')) { + $session{var}{altSiteURL} = "./"; + my $url = $session{page}{urlizedTitle}; + while ($url =~ /\//g) { + $session{var}{altSiteURL} .= "../"; + } + } + # !!! At this point we make URLs absolute only if altSiteURL is not set. + + # Set alternate Style + $session{page}{styleId} = $self->get('styleId') || $session{page}{styleId}; + + # Generate the page + my $content = WebGUI::page(undef, undef, 1); + + if($self->get('stripHTML')) { + $content = WebGUI::HTML::html2text($content); + } elsif (not $session{var}{altSiteURL}) { # Implies absolute links + $content = WebGUI::HTML::makeAbsolute($content); + } + + # Restore session + %session = %oldSession; + delete $session{page}{noHttpHeader}; + delete $session{var}{altSiteURL}; + return $content; + +} +#------------------------------------------------------------------- + +=head2 new ( [ options ] ) + +Constructor. + +Options can be set when a new Export object is constructed, or +afterwards with the set method. None of the options is required. + +=over + +=item pageId + +Sets the page to be generated. Defaults to current page. + +=item styleId + +Use this to override the default styleId. +Defaults to the page styleId. + +=item userId + +Runs the export as this user. Defaults to 1 (Visitor). + +=item altSiteURL + +Use this to override the absolute site URL. A valid value +would be "http://www.site.com/". Setting this negates the effect +of the relativeUrls option. + +=item noCache + +Is set to true by default. This will make sure +that the exported page is generated and not fetched from cache. + +=item noHttpHeader + +Turns off the inclusion of a HTTP header. By default this option +is set to true. + +=item adminOn + +Turns on / off the adminbar in the generated page. Is false by +default. + +=item stripHTML + +Strips HTML from the document and outputs only text. Is disabled +by default. + +=item relativeUrls + +If set, all navigation URL's will be constructed relative. By default +all links will be made absolute. This option is negated if altSiteURL +is set. + +=item extrasURL + +You can specify an alternate URL for the extras location. By default +the extrasURL setting from the config file is used. + +=item uploadsURL + +You can specify an alternate URL for the uploads location. By default +the uploadsURL setting from the config file is used. + +=back + +=cut + +sub new { + my $class = shift; + WebGUI::ErrorHandler::fatalError('WebGUI::Export->new() called with odd number of option parameters - should be of the form option => value') unless $#_ % 2;; + my %var = @_; + my $self = bless {}, $class; + my %default = ( + uploadsURL => $session{config}{uploadsURL}, + extrasURL => $session{config}{extrasURL}, + pageId => $session{page}{pageId}, + styleId => undef, + userId => 1, + noCache => 1, + noHttpHeader => 1, + adminOn => 0, + stripHTML => 0, + altSiteURL => undef, + relativeUrls => 0, + ); + %var = ( %default, %var); + $self->set(%var); + return $self; +} + +#------------------------------------------------------------------- + +=head2 get ( key ) + +Gets the value for key from the class. + +=over + +=item key + +See documentation on the "new" constructor for an overview of all options. + +=back + +=cut + +sub get { + my $self = shift; + my $key = shift; + return $self->{"_".$key}; +} + +#------------------------------------------------------------------- + +=head2 set ( options ) + +Sets properties for this export to the object. + +=over + +=item options + +See documentation on the "new" constructor for an overview of all options. + +=back + +=cut + +sub set { + my $self = shift; + my %var = @_; + foreach (keys %var) { + $self->{"_".$_} = $var{$_} + } +} + + +1; + + diff --git a/lib/WebGUI/Help/WebGUI.pm b/lib/WebGUI/Help/WebGUI.pm index 0b09b582a..63f72114a 100644 --- a/lib/WebGUI/Help/WebGUI.pm +++ b/lib/WebGUI/Help/WebGUI.pm @@ -1145,6 +1145,12 @@ our $HELP = { }, ], }, + 'page export' => { + title => 'Page, Export', + body => 'Page, Export body', + related => [ + ], + }, }; diff --git a/lib/WebGUI/Icon.pm b/lib/WebGUI/Icon.pm index 4fa11d9e7..af950bef2 100644 --- a/lib/WebGUI/Icon.pm +++ b/lib/WebGUI/Icon.pm @@ -23,7 +23,7 @@ use WebGUI::URL; our @ISA = qw(Exporter); our @EXPORT = qw(&helpIcon &becomeIcon &cutIcon ©Icon &deleteIcon &editIcon &manageIcon &moveBottomIcon &moveDownIcon &moveLeftIcon &moveRightIcon &moveTopIcon &moveUpIcon - &pageIcon &dragIcon &shortcutIcon &pasteIcon &wobjectIcon &viewIcon); + &pageIcon &dragIcon &shortcutIcon &pasteIcon &wobjectIcon &viewIcon &exportIcon); =head1 NAME @@ -209,6 +209,35 @@ sub editIcon { #------------------------------------------------------------------- +=head2 exportIcon ( urlParameters [, pageURL ] ) + +Generates an export button. + +=over + +=item urlParameters + +Any URL parameters that need to be tacked on to the current URL to accomplish whatever function this button represents. + +=item pageURL + +The URL to any page. Defaults to the current page. + +=back + +=cut + +sub exportIcon { + my ($output, $pageURL); + $pageURL = $_[1] || $session{page}{urlizedTitle}; + $output = ''; + # TODO Change icon to Jeffs export icon + $output .= 'Export'; + return $output; +} + +#------------------------------------------------------------------- + =head2 getToolbarOptions ( ) Returns a hash reference containing the list of toolbar icon sets to be selected in user profile. diff --git a/lib/WebGUI/Navigation.pm b/lib/WebGUI/Navigation.pm index 719ce6444..972516eb1 100644 --- a/lib/WebGUI/Navigation.pm +++ b/lib/WebGUI/Navigation.pm @@ -228,8 +228,7 @@ sub build { my (@page_loop, $lastPage, %unfolded); tie %unfolded, "Tie::IxHash"; - - unless (defined $cacheContent) { + unless (defined $cacheContent && ! $session{var}{altSiteURL}) { # The loop was not cached my @pages = eval $method; if ($@) { diff --git a/lib/WebGUI/Operation/Page.pm b/lib/WebGUI/Operation/Page.pm index f9b6c8b82..1039683cb 100644 --- a/lib/WebGUI/Operation/Page.pm +++ b/lib/WebGUI/Operation/Page.pm @@ -12,10 +12,12 @@ package WebGUI::Operation::Page; use Exporter; use strict; +use File::Path; use WebGUI::DateTime; use WebGUI::FormProcessor; use WebGUI::Grouping; use WebGUI::HTMLForm; +use WebGUI::HTTP; use WebGUI::Icon; use WebGUI::International; use WebGUI::Page; @@ -25,12 +27,14 @@ use WebGUI::SQL; use WebGUI::TabForm; use WebGUI::URL; use WebGUI::Utility; +use WebGUI::Export; our @ISA = qw(Exporter); our @EXPORT = qw(&www_viewPageTree &www_movePageUp &www_movePageDown &www_cutPage &www_deletePage &www_deletePageConfirm &www_editPage - &www_editPageSave &www_pastePage &www_moveTreePageUp &www_rearrangeWobjects - &www_moveTreePageDown &www_moveTreePageLeft &www_moveTreePageRight); + &www_editPageSave &www_exportPage &www_exportPageStatus www_exportPageGenerate + &www_pastePage &www_moveTreePageUp &www_rearrangeWobjects &www_moveTreePageDown + &www_moveTreePageLeft &www_moveTreePageRight); #------------------------------------------------------------------- =head2 _changeWobjectPrivileges ( page ) @@ -299,7 +303,6 @@ sub www_deletePageConfirm { } } -use WebGUI::TabForm; #------------------------------------------------------------------- =head2 www_editPage @@ -606,7 +609,189 @@ sub www_editPageSave { } #------------------------------------------------------------------- -=head2 www_moqvePageDown + +=head2 www_exportPage + +Displays the export page administrative interface + +=back + +=cut + +sub www_exportPage { + return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(13)); + + my $output; + $output .= helpIcon("page export"); + $output .= '

'.WebGUI::International::get('Export Page').'

'; + $output .= _checkExportPath(); + + my $f = WebGUI::HTMLForm->new; + $f->hidden("op","exportPageStatus"); + $f->integer( + -label=>WebGUI::International::get('Depth'), + -name=>"depth", + -value=>99, + ); + $f->selectList( + -label=>WebGUI::International::get('Export as user'), + -name=>"userId", + -options=>WebGUI::SQL->buildHashRef("select userId, username from users"), + -value=>[1], + ); + tie my %templates, 'Tie::IxHash'; + %templates = ("", WebGUI::International::get(139), %{WebGUI::Template::getList('style')}); + $f->selectList( + -label=>WebGUI::International::get('Alternate style'), + -name=>"styleId", + -options=>\%templates, + ); + $f->text( + -label=>WebGUI::International::get('Extras URL'), + -name=>"extrasURL", + -value=>$session{config}{extrasURL} + ); + $f->text( + -label=>WebGUI::International::get('Uploads URL'), + -name=>"uploadsURL", + -value=>$session{config}{uploadsURL} + ); + $f->submit; + $output .= $f->print; + return $output; +} + +#------------------------------------------------------------------- + +=head2 www_exportPageStatus + +Displays the export status page + +=back + +=cut + + +sub www_exportPageStatus { + return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(13)); + + my $iframeUrl = WebGUI::URL::page('op=exportPageGenerate'); + $iframeUrl = WebGUI::URL::append($iframeUrl, 'depth='.$session{form}{depth}); + $iframeUrl = WebGUI::URL::append($iframeUrl, 'styleId='.$session{form}{styleId}); + $iframeUrl = WebGUI::URL::append($iframeUrl, 'userId='.$session{form}{userId}); + $iframeUrl = WebGUI::URL::append($iframeUrl, 'pageId='.$session{page}{pageId}); + $iframeUrl = WebGUI::URL::append($iframeUrl, 'extrasURL='.$session{form}{extrasURL}); + $iframeUrl = WebGUI::URL::append($iframeUrl, 'uploadsURL='.$session{form}{uploadsURL}); + + + my $output; + $output .= '

'.WebGUI::International::get('Page Export Status').'

'; + $output .= ''; + + return $output; +} + +#------------------------------------------------------------------- + +=head2 www_exportPageGenerate + +Executes the export process and displays real time status. This operation is displayed +by exportPageStatus in an IFRAME. + +=back + +=cut + + +sub www_exportPageGenerate { + return WebGUI::Privilege::insufficient unless (WebGUI::Grouping::isInGroup(13)); + + # This routine is called in an IFRAME and prints status output directly to the browser. + $|++; # Unbuffered data output + $session{page}{empty} = 1; # Write directly to the browser + + print WebGUI::HTTP::getHeader(); + + my $startTime = time(); + my $error = _checkExportPath(); + if ($error) { + print $error; + return; + } + my $userId = $session{form}{userId}; + my $styleId = $session{form}{styleId}; + my $extrasURL = $session{form}{extrasURL}; + my $uploadsURL = $session{form}{uploadsURL}; + + # Get the pages + my $p = WebGUI::Page->getPage($session{form}{page}); + my @pages = $p->self_and_descendants(depth=>$session{form}{depth}); + unless (@pages) { + print "There are no pages to export"; + return; + } + foreach my $page (@pages) { + my ($path, $file); + print "Exporting page ".$page->{urlizedTitle}."......"; + + # Create path + $page->{urlizedTitle} =~ /^(.*)\/(.*)$/; + $path = $1; + if($path) { + $path = $session{config}{exportPath} . $session{os}{slash} . $path; + eval { mkpath($path) }; + if($@) { + print "Couldn't create $path: $@"; + return; + } + } + # initiate export object + my $e = WebGUI::Export->new( + pageId => $page->{pageId}, + userId => $userId || 1, + styleId => $styleId, + relativeUrls => 1, + extrasURL => $extrasURL, + uploadsURL => $uploadsURL + ); + # Open file + $file = $session{config}{exportPath} . $session{os}{slash} . $page->{urlizedTitle}; + open(FILE, "> $file") || die "Can't open $file: $!"; + print FILE $e->generate; + close(FILE); + + print "DONE
"; + } + print "

Exported ".scalar(@pages)." pages in ".(time()-$startTime)." seconds.

"; + print ''.WebGUI::International::get(493).''; + + return; + +} + +#------------------------------------------------------------------- +sub _checkExportPath { + my $error; + if(defined $session{config}{exportPath}) { + if(-d $session{config}{exportPath}) { + unless (-w $session{config}{exportPath}) { + $error .= 'Error: The export path '.$session{config}{exportPath}.' is not writable.
+ Make sure that the webserver has permissions to write to that directory'; + } + } else { + $error .= 'Error: The export path '.$session{config}{exportPath}.' does not exists.'; + } + } else { + $error.= 'Error: The export path is not configured. Please set the exportPath variable in the WebGUI config file'; + } + $error = '

'.$error.'

' if $error; + return $error; +} + +#------------------------------------------------------------------- +=head2 www_movePageDown Moves page down in the context of it's sisters. diff --git a/lib/WebGUI/Page.pm b/lib/WebGUI/Page.pm index 96d20f723..e5e138978 100644 --- a/lib/WebGUI/Page.pm +++ b/lib/WebGUI/Page.pm @@ -462,6 +462,7 @@ sub generate { .moveUpIcon('op=movePageUp') .moveDownIcon('op=movePageDown') .cutIcon('op=cutPage'); + $var{'page.controls'} .= exportIcon('op=exportPage') if defined ($session{config}{exportPath}); my $sth = WebGUI::SQL->read("select * from wobject where pageId=".$session{page}{pageId}." order by sequenceNumber, wobjectId",WebGUI::SQL->getSlave); while (my $wobject = $sth->hashRef) { my $wobjectToolbar = wobjectIcon() @@ -1368,8 +1369,10 @@ Returns an array of hashrefs containing the page properties of this node and it' sub self_and_descendants { my ($self); $self = shift; + my @options = @_; return @{$self->get_self_and_children_flat( - id => $self->get('pageId') + id => $self->get('pageId'), + @options )}; } diff --git a/lib/WebGUI/URL.pm b/lib/WebGUI/URL.pm index 478c169fd..d7bd1c2c0 100644 --- a/lib/WebGUI/URL.pm +++ b/lib/WebGUI/URL.pm @@ -174,7 +174,8 @@ Returns a constructed site url from protocol to gateway. =cut -sub getSiteURL { +sub getSiteURL { + return $session{var}{altSiteURL} if (defined $session{var}{altSiteURL}); my $site; my @sitenames; if (ref $session{config}{sitename} eq "ARRAY") { diff --git a/lib/WebGUI/i18n/English/WebGUI.pm b/lib/WebGUI/i18n/English/WebGUI.pm index 17ab15b0a..291a5ebd6 100644 --- a/lib/WebGUI/i18n/English/WebGUI.pm +++ b/lib/WebGUI/i18n/English/WebGUI.pm @@ -7128,10 +7128,75 @@ each wobject under the tab "Metadata" in the wobject properties.

lastUpdated => 1089039511, context => q|Metadata help| }, - - - - + 'Export Page' => { + message => q|Export Page|, + lastUpdated => 1089039511, + context => q|Title for the Export Page operation| + }, + 'Page to export' => { + message => q|Page to export|, + lastUpdated => 1089039511, + context => q|Field label for the Export Page operation| + }, + 'Export as user' => { + message => q|Export as user|, + lastUpdated => 1089039511, + context => q|Field label for the Export Page operation| + }, + 'Alternate style' => { + message => q|Alternate style|, + lastUpdated => 1089039511, + context => q|Field label for the Export Page operation| + }, + 'Page Export Status' => { + message => q|Page Export Status|, + lastUpdated => 1089039511, + context => q|Title for the Page Export Status operation| + }, + 'Depth' => { + message => q|Depth|, + lastUpdated => 1089039511, + context => q|Field label for the Export Page operation| + }, + 'Extras URL' => { + message => q|Extras URL|, + lastUpdated => 1089039511, + context => q|Field label for the Export Page operation| + }, + 'Uploads URL' => { + message => q|Uploads URL|, + lastUpdated => 1089039511, + context => q|Field label for the Export Page operation| + }, + 'Page, Export' => { + message => q|Page, Export|, + lastUpdated => 1089039511, + context => q|Help title for Page Export operation| + }, + 'Page, Export body' => { + message => q| +

The Export Page function allows you to export WebGUI pages to static HTML +files on disk.
+The "exportPath" variable in the WebGUI config file must be enabled +for this function to work properly.

+

Depth
+
Sets the depth of the page tree to export. Use a depth of 0 to export only +the current page.

+

Export as user
+
Run the export as this user. Defaults to Visitor.

+

 Alternate style
+
Sets an alternate style for the export. If this option is set, all pages +will be exported using the selected style.

+

Extras URL
+
Sets the Extras URL. Defaults to the configured extrasURL in the WebGUI +config file.

+

Uploads URL
+
Sets the Uploads URL. Defaults to the configured uploadsURL in the WebGUI +config file.

+ |, + lastUpdated => 1089039511, + context => q|Help body for Page Export operation| + }, }; diff --git a/sbin/generateContent.pl b/sbin/generateContent.pl index 6e533297b..ee41a5e00 100644 --- a/sbin/generateContent.pl +++ b/sbin/generateContent.pl @@ -23,12 +23,11 @@ use Getopt::Long; use strict qw(subs vars); use WebGUI; use WebGUI::Session; -use WebGUI::HTML; -use WebGUI::Utility; +use WebGUI::Export; $|=1; -my ($configFile, $pageId, $userId, $styleId, $toFile, $stripHTML, $help); +my ($configFile, $pageId, $userId, $styleId, $toFile, $stripHTML, $help, $relativeUrls); $userId = 1; @@ -39,7 +38,8 @@ GetOptions( 'styleId:i'=>\$styleId, 'toFile:s'=>\$toFile, 'stripHTML'=>\$stripHTML, - 'help'=>\$help + 'help'=>\$help, + 'relativeUrls'=>\$relativeUrls, ); if ($help || $configFile eq '' ) { @@ -70,44 +70,32 @@ Options: output only text. NOTE: The resulting text may have formatting problems as a result. - + + --relativeUrls If set, all navigation URL's will be relative + instead of absolute. Defaults to "0" (absolute + URLs) + STOP exit; } -# Open output file if necessary -if ($toFile) { - open (TOFILE, ">$toFile") or die "Can't open file $toFile for writing. $!"; -} - # Open WebGUI session WebGUI::Session::open($webguiRoot,$configFile); -WebGUI::Session::refreshUserInfo($userId,$session{dbh}); -WebGUI::Session::refreshPageInfo($pageId); +WebGUI::Session::refreshUserInfo(3,$session{dbh}); -# No HTTP header as we're browserless -$session{page}{noHttpHeader} = 1; +my $e = WebGUI::Export->new( + pageId => $pageId, + userId => $userId, + styleId => $styleId, + stripHTML => $stripHTML, + relativeUrls => $relativeUrls + ); -# Alternate style -if (defined $styleId) { - $session{form}{makePrintable}++; # prevent caching - $session{page}{styleId} = $styleId; -} - -# Retrieve content -my $content = WebGUI::page(undef, undef, 1); - -# stripHTML -if ($stripHTML) { - $content = WebGUI::HTML::html2text($content); -} else { - # Make links absolute - $content = WebGUI::HTML::makeAbsolute($content); -} - -# Print result +my $content = $e->generate; if ($toFile) { + open (TOFILE, ">$toFile") or die "Can't open file $toFile for writing. $!"; print TOFILE $content; + close (TOFILE); } else { print $content; } @@ -116,7 +104,4 @@ if ($toFile) { WebGUI::Session::end($session{var}{sessionId}); WebGUI::Session::close(); -# Close output file if necessary -close(TOFILE) if ($toFile); - exit; diff --git a/www/extras/toolbar/metal/export.gif b/www/extras/toolbar/metal/export.gif new file mode 100644 index 000000000..77f5b649b Binary files /dev/null and b/www/extras/toolbar/metal/export.gif differ diff --git a/www/extras/toolbar/metal/import.gif b/www/extras/toolbar/metal/import.gif new file mode 100644 index 000000000..fb5ee0cb5 Binary files /dev/null and b/www/extras/toolbar/metal/import.gif differ