Ready for 7.10.29 development.

This commit is contained in:
Colin Kuskie 2013-03-20 21:38:23 -07:00
commit c806f99b7b
4236 changed files with 1217679 additions and 0 deletions

View file

@ -0,0 +1,180 @@
package WebGUI::Content::Account;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
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::Exception;
use Carp qw(croak);
=head1 NAME
Package WebGUI::Content::Account
=head1 DESCRIPTION
A content handler that opens up all the account functionality. Account modules are accessed via the url like this:
/pagename?op=module;do=www_method
For example:
/home?op=profile;do=edit
In the above we're accessing the www_edit method in the WebGUI::Account::Profile module.
Module op relationships are stored in the config file as such
account : {
"profile" : "WebGUI::Account::Profile",
"inbox" : "WebGUI::Account::Inbox",
"network" : "WebGUI::Account::Network",
"user" : "WebGUI::Account::User",
"custom" : "WebGUI::Account::Custom"
}
=head1 SYNOPSIS
use WebGUI::Content::Account;
my $output = WebGUI::Content::Account::handler($session);
=head1 SUBROUTINES
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 createInstance ( session, module )
Creates an instance of an account pluggin
=head3 session
WebGUI::Session object
=head3 module
Module the method is in. Defaults to the profileModuleIdentifier in the config file
=cut
sub createInstance {
my $class = shift;
my $session = shift;
my $module = shift || $session->config->get("profileModuleIdentifier");
#Get the account config to work with
my $configs = $session->config->get("account");
my $config = __PACKAGE__->getAccountConfig($session,$module,$configs);
#Throw an error if the config file isn't found
unless (defined $config) {
WebGUI::Error->throw( error => qq{Could not locate module $module in the account system});
return undef;
}
#Create Pluggin Object
#Don't eval this as pluggable will croak and we want the calling module to handle the exception
my $pluggin = WebGUI::Pluggable::instanciate(
$config->{className},
"new",
[ $session, $module ]
);
#Check to make sure pluggin is a subclass of WebGUI::Account
unless($pluggin->isa('WebGUI::Account')) {
my $plugginType = ref $pluggin;
WebGUI::Error::InvalidObject->throw(
expected => 'WebGUI::Account',
got => $plugginType,
error => '$plugginType is not a subclass of WebGUI::Accout'
);
return undef;
}
return $pluggin;
}
#-------------------------------------------------------------------
=head2 getAccountConfig ( op, configs )
Searches the account config array passed in and returns the hash reference which
contains the op value passed in. If no op value is found, undef is returned;
=head3 op
op to search for
=head3 configs
array ref with account config hashes
=cut
sub getAccountConfig {
my $class = shift;
my $session = shift;
my $module = shift;
my $configs = shift || $session->config->get("account");
foreach my $config (@{$configs}) {
return $config if ($config->{identifier} eq $module);
}
return undef;
}
#-------------------------------------------------------------------
=head2 handler ( session )
The content handler for this package.
=cut
sub handler {
my $session = shift;
my $form = $session->form;
my $setting = $session->setting;
#Pass through if it's not the account op
return undef unless ($form->get("op") eq "account");
#Visitor cannot access the acccount system
return $session->privilege->noAccess if($session->user->isVisitor);
my $module = $form->get("module");
my $method = $form->get("do");
my $uid = $form->get("uid");
my $instance = __PACKAGE__->createInstance($session,$module);
#Let the content handler handle trapping errors
my $output = $instance->callMethod($method,[],$uid);
return undef unless (defined $output);
return $instance->displayContent($output);
}
1;

View file

@ -0,0 +1,73 @@
package WebGUI::Content::AjaxI18N;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
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 JSON ();
=head1 NAME
Package WebGUI::Content::AjaxI18N
=head1 DESCRIPTION
A content handler to get i18n data using the WebGUI.i18n JavaScript object.
=head1 SYNOPSIS
use WebGUI::Content::AjaxI18N
my $output = WebGUI::Content::AjaxI18N::handler($session);
=head1 SUBROUTINES
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 handler ( session )
The content handler for this package.
=cut
sub handler {
my ( $session ) = @_;
# Only handle op=ajaxGetI18N
return undef unless ( $session->form->get( "op" ) eq "ajaxGetI18N" );
my $response = {};
my $json = $session->form->get( "request" );
my $namespaces = eval { JSON->new->decode( $json ) };
unless ($@) {
my $i18n = WebGUI::International->new( $session );
for my $ns ( keys %{ $namespaces } ) {
for my $key ( @{ $namespaces->{ $ns } } ) {
$response->{ $ns }->{ $key } = $i18n->get( $key, $ns );
}
}
}
else {
$session->log->warn("User ".$session->user->username." tried to execute ajaxGetI18n but could not decode JSON string: $json");
}
$session->http->setMimeType( "application/json" );
return JSON->new->encode( $response );
}
1;

213
lib/WebGUI/Content/Asset.pm Normal file
View file

@ -0,0 +1,213 @@
package WebGUI::Content::Asset;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
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 LWP::MediaTypes qw(guess_media_type);
use Time::HiRes;
use WebGUI::Asset;
use WebGUI::PassiveAnalytics::Logging;
use Apache2::Const -compile => qw(OK);
=head1 NAME
Package WebGUI::Content::MyHandler
=head1 DESCRIPTION
A content handler that serves up assets.
=head1 SYNOPSIS
use WebGUI::Content::Asset;
my $output = WebGUI::Content::Asset::handler($session);
=head1 SUBROUTINES
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 dispatch ( $session, $assetUrl )
Attempts to return the output from an asset, based on its url. All permutations of the
URL are tried, to find an asset that matches. If it finds an Asset, then it calls the
dispatch method on it. An Asset's dispatch always returns SOMETHING, so if a matching
asset is found, this is the last stop.
=head3 $session
A WebGUI::Session object.
=head4 $assetUrl
The URL for this request.
=cut
sub dispatch {
my $session = shift;
my $assetUrl = shift;
$assetUrl =~ s{/$}{};
my $permutations = getUrlPermutations($assetUrl);
foreach my $url (@{ $permutations }) {
if (my $asset = getAsset($session, $url)) {
##Passive Analytics Logging
WebGUI::PassiveAnalytics::Logging::log($session, $asset);
# display from cache if page hasn't been modified.
if ($session->user->isVisitor
&& !$session->http->ifModifiedSince($asset->getContentLastModified, $session->setting->get('maxCacheTimeout'))) {
$session->http->setStatus("304","Content Not Modified");
$session->http->sendHeader;
$session->close;
return "chunked";
}
my $fragment = $assetUrl;
$fragment =~ s/$url//;
$session->asset($asset);
my $output = eval { $asset->dispatch($fragment); };
return $output if defined $output;
}
}
$session->clearAsset;
if ($session->var->isAdminOn) {
my $asset = WebGUI::Asset->newByUrl($session, $session->url->getRefererUrl) || WebGUI::Asset->getDefault($session);
return $asset->addMissing($assetUrl);
}
return undef;
}
#-------------------------------------------------------------------
=head2 getAsset ( session [, assetUrl ] )
Returns an asset based upon the requested asset URL, or optionally pass one in.
=cut
sub getAsset {
my $session = shift;
my $assetUrl = shift;
my $asset = eval{WebGUI::Asset->newByUrl($session,$assetUrl,$session->form->process("revision"))};
if ($@) {
$session->errorHandler->warn("Couldn't instantiate asset for url: ".$assetUrl." Root cause: ".$@);
}
return $asset;
}
#-------------------------------------------------------------------
=head2 getRequestedAssetUrl ( session [, assetUrl ] )
Returns an asset based upon the requested asset URL, or optionally pass one in.
=cut
sub getRequestedAssetUrl {
my $session = shift;
my $assetUrl = shift || $session->url->getRequestedUrl;
return $assetUrl;
}
#-------------------------------------------------------------------
=head2 getUrlPermutations ( $url )
Returns an array reference of permutations for the URL.
=head3 $url
The URL to permute.
=cut
sub getUrlPermutations {
my $url = shift;
##Handle empty urls (sitename only)
return ['/'] if !$url
|| $url eq '/';
my @permutations = ();
if ($url =~ /\.\w+$/) {
push @permutations, $url;
$url =~ s/\.\w+$//;
}
my @fragments = split /\//, $url;
FRAG: while (@fragments) {
last FRAG if $fragments[-1] eq '';
push @permutations, join "/", @fragments;
pop @fragments;
}
return \@permutations;
}
#-------------------------------------------------------------------
=head2 handler ( session )
The content handler for this package.
=cut
sub handler {
my ($session) = @_;
my ($errorHandler, $http, $var, $asset, $request, $config) = $session->quick(qw(errorHandler http var asset request config));
my $output = "";
if ($errorHandler->canShowPerformanceIndicators) { #show performance indicators if required
my $t = [Time::HiRes::gettimeofday()];
$output = dispatch($session, getRequestedAssetUrl($session));
$t = Time::HiRes::tv_interval($t) ;
if ($output =~ /<\/title>/) {
$output =~ s/<\/title>/ : ${t} seconds<\/title>/i;
}
else {
# Kludge.
my $mimeType = $http->getMimeType();
if ($mimeType eq 'text/css') {
$session->output->print("\n/* Page generated in $t seconds. */\n");
}
elsif ($mimeType =~ m{text/html}) {
$session->output->print("\nPage generated in $t seconds.\n");
}
else {
# Don't apply to content when we don't know how
# to modify it semi-safely.
}
}
}
else {
$output = dispatch($session, getRequestedAssetUrl($session));
}
my $filename = $http->getStreamedFile();
if ((defined $filename) && ($config->get("enableStreamingUploads") eq "1")) {
my $ct = guess_media_type($filename);
my $oldContentType = $request->content_type($ct);
if ($request->sendfile($filename) ) {
$session->close;
return Apache2::Const::OK;
}
else {
$request->content_type($oldContentType);
}
}
return $output;
}
1;

View file

@ -0,0 +1,148 @@
package WebGUI::Content::AssetDiscovery;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
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 JSON;
use WebGUI::Asset;
use WebGUI::Utility;
use XML::Simple;
=head1 NAME
Package WebGUI::Content::AssetDiscovery
=head1 DESCRIPTION
Allows web services to find a list of assets of a given type.
=head1 SYNOPSIS
use WebGUI::Content::AssetDiscovery;
my $output = WebGUI::Content::AssetDiscovery::handler($session);
From the web call any WebGUI URL. The discovery asset will limit your query to the assets below that URL in the asset tree. Here's an example:
http://admin:123qwe@www.example.com/some-page?op=findAssets;className=WebGUI::Asset::Wobject::Article
Only the assets that you can view according to your user's privileges will be returned. The following are the parameters you can pass along the URL:
=head2 op
Required. Its value must be 'findAssets'.
=head2 className
Required. Its value must be a valid WebGUI asset classname.
=head2 as
Defaults to 'json'. You may override it by setting its value to 'xml'. This setting determines how the result set will come back. If it is 'json' it will look like:
{
"assets" : [
{
"lastUpdated" : "2006-05-14 16:35:15",
"synopsis" : null,
"menuTitle" : "Getting Started (part 2)",
"url" : "http://dev.localhost.localdomain/getting_started/getting-started-part2",
"title" : "Getting Started (part 2)",
"dateCreated" : "2006-05-14 16:35:15"
}
],
"className" : "WebGUI::Asset::Wobject::Article",
"pageNumber" : 1
}
If it is 'xml' it will look like:
<opt>
<assets>
<dateCreated>2006-05-14 16:35:15</dateCreated>
<lastUpdated>2006-05-14 16:35:15</lastUpdated>
<menuTitle>Getting Started (part 2)</menuTitle>
<synopsis></synopsis>
<title>Getting Started (part 2)</title>
<url>http://dev.localhost.localdomain/getting_started/getting-started-part2</url>
</assets>
<className>WebGUI::Asset::Wobject::Article</className>
<pageNumber>1</pageNumber>
</opt>
=head2 pn
Defaults to 1. pn stands for Page Number. The result set from this service returns up to 100 assets at a time. If you need more than that you can set pn to the next page number and so on. B<Caveat:> Due to the calculations based upon branch and user privileges this service does not know the maximum number of pages of data there will be.
=head1 SUBROUTINES
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 handler ( session )
The content handler for this package.
=cut
sub handler {
my ($session) = @_;
my $form = $session->form;
if ($form->get('op') eq 'findAssets') {
my @assets;
my $as = $form->get('as') || 'json';
my $pageNumber = $form->get('pn') || 1;
my $class = $form->get('className');
if ($class ne '') {
my $start = WebGUI::Asset->newByUrl($session);
my $limit = ($pageNumber * 100 - 100).','.($pageNumber * 100 - 1);
my $siteUrl = $session->url->getSiteURL;
my $date = $session->datetime;
my $matchingAssets = $session->db->read("select assetId from asset where lineage like ? and className=? limit ".$limit, [$start->get('lineage').'%', $class]);
while (my ($id) = $matchingAssets->array) {
my $asset = WebGUI::Asset->new($session, $id, $class);
if (defined $asset) {
if ($asset->canView && $asset->get('state') eq 'published' && isIn($asset->get('status'), 'approved', 'archived')) {
push @assets, {
title => $asset->getTitle,
menuTitle => $asset->get('menuTitle'),
synopsis => $asset->get('synopsis'),
url => $siteUrl.$asset->getUrl,
dateCreated => $date->epochToHuman($asset->get('creationDate'), '%y-%m-%d %j:%n:%s'),
lastUpdated => $date->epochToHuman($asset->get('revisionDate'), '%y-%m-%d %j:%n:%s'),
};
}
}
}
}
my $document = {
pageNumber => $pageNumber,
className => $class,
assets => \@assets
};
if ($as eq "xml") {
$session->http->setMimeType('text/xml');
return XML::Simple::XMLout($document, NoAttr => 1);
}
$session->http->setMimeType('application/json');
return JSON->new->encode($document);
}
return undef;
}
1;
#vim:ft=perl

View file

@ -0,0 +1,167 @@
package WebGUI::Content::AssetHistory;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
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;
=head1 NAME
Package WebGUI::Content::AssetHistory
=head1 DESCRIPTION
Give the admins an interface to view the history of assets on their site.
=head1 SYNOPSIS
use WebGUI::Content::AssetHistory;
my $output = WebGUI::Content::AssetHistory::handler($session);
=head1 SUBROUTINES
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 handler ( session )
The content handler for this package.
=cut
sub handler {
my ($session) = @_;
return undef unless ($session->form->get('op') eq 'assetHistory');
my $method = $session->form->get( 'method' )
? 'www_' . $session->form->get( 'method' )
: 'www_view'
;
# Validate the method name
if ( !__PACKAGE__->can( $method ) ) {
return "Invalid method";
}
else {
return __PACKAGE__->can( $method )->( $session );
}
my $output = "";
# ...
return $output;
}
#-------------------------------------------------------------------
=head2 www_getHistoryAsJson ( )
Servers side pagination for asset history data displayed in a YUI DataTable.
=cut
sub www_getHistoryAsJson {
my ($session) = @_;
return $session->privilege->insufficient
unless $session->user->isInGroup(12);
my ($db, $form) = $session->quick(qw(db form));
my $startIndex = $form->get('startIndex') || 0;
my $numberOfResults = $form->get('results') || 25;
my %goodKeys = qw/assetId 1 url 1 username 1 dateStamp 1/;
my $sortKey = $form->get('sortKey');
$sortKey = $goodKeys{$sortKey} == 1 ? $sortKey : 'dateStamp';
my $sortDir = $form->get('sortDir');
$sortDir = lc($sortDir) eq 'desc' ? 'desc' : 'asc';
my @placeholders = ();
my $sql = <<EOSQL;
select SQL_CALC_FOUND_ROWS assetHistory.*,users.username from assetHistory join users on assetHistory.userId=users.userId
EOSQL
my $keywords = $form->get("keywords");
if ($keywords ne "") {
$db->buildSearchQuery(\$sql, \@placeholders, $keywords, [qw{url assetId username}])
}
push(@placeholders, $startIndex, $numberOfResults);
$sql .= sprintf (" order by %s limit ?,?","$sortKey $sortDir");
my %results = ();
my @records = ();
my $sth = $db->read($sql, \@placeholders);
while (my $record = $sth->hashRef) {
push(@records,$record);
}
$results{'recordsReturned'} = $sth->rows()+0;
$sth->finish;
$results{'records'} = \@records;
$results{'totalRecords'} = $db->quickScalar('select found_rows()')+0; ##Convert to numeric
$results{'startIndex'} = $startIndex;
$results{'sort'} = undef;
$results{'dir'} = $sortDir;
$session->http->setMimeType('application/json');
my $json = JSON::to_json(\%results);
return $json;
}
#-------------------------------------------------------------------
=head2 www_view
YUI DataTable for browsing asset history.
=cut
sub www_view {
my $session = shift;
return $session->privilege->insufficient
unless $session->user->isInGroup(12);
##YUI specific datatable CSS
my $ac = WebGUI::AdminConsole->new( $session, "assetHistory", {
showAdminBar => 1
} );
my ($style, $url) = $session->quick(qw(style url));
$style->setLink($url->extras('/yui/build/fonts/fonts-min.css'), {rel=>'stylesheet', type=>'text/css'});
$style->setLink($url->extras('yui/build/datatable/assets/skins/sam/datatable.css'), {rel=>'stylesheet', type => 'text/CSS'});
$style->setLink($url->extras('yui/build/paginator/assets/skins/sam/paginator.css'), {rel=>'stylesheet', type => 'text/CSS'});
$style->setScript($url->extras('/yui/build/utilities/utilities.js'), {type=>'text/javascript'});
$style->setScript($url->extras('yui/build/json/json-min.js'), {type => 'text/javascript'});
$style->setScript($url->extras('yui/build/paginator/paginator-min.js'), {type => 'text/javascript'});
$style->setScript($url->extras('yui/build/datasource/datasource-min.js'), {type => 'text/javascript'});
##YUI Datatable
$style->setScript($url->extras('yui/build/datatable/datatable-min.js'), {type => 'text/javascript'});
##WebGUI YUI AssetHistory
$style->setScript( $url->extras( 'yui-webgui/build/i18n/i18n.js' ), {type => 'text/javascript'} );
$style->setScript( $url->extras('yui-webgui/build/assetHistory/assetHistory.js'), {type => 'text/javascript'});
##Default CSS
$style->setRawHeadTags('<style type="text/css"> #paging a { color: #0000de; } #search form { display: inline; } </style>');
my $i18n=WebGUI::International->new($session);
my $output;
$output .= q|
<div class="yui-skin-sam">
<div id="search"><form id="keywordSearchForm"><input type="text" name="keywords" id="keywordsField" /><input type="submit" value="|.$i18n->get(364, 'WebGUI').q|" /><input type="submit" value="|.$i18n->get('Clear', 'WebGUI').q|" onclick="this.form.keywords.value='';"/></form></div>
<div id="paginationTop"></div>
<div id="historyData"></div>
<div id="paginationBot"></div>
</div>
<script type="text/javascript">
YAHOO.util.Event.onDOMReady( WebGUI.AssetHistory.initManager );
</script>
|;
return $ac->render( $output );
}
1;
#vim:ft=perl

View file

@ -0,0 +1,752 @@
package WebGUI::Content::AssetManager;
use strict;
use JSON qw( from_json to_json );
use URI;
use WebGUI::Form;
use WebGUI::Paginator;
use WebGUI::Utility;
use WebGUI::Macro::AdminBar;
#----------------------------------------------------------------------------
=head2 getClassSelectBox ( session )
Gets a select box to choose a class name.
=cut
sub getClassSelectBox {
my $session = shift;
my $i18n = WebGUI::International->new($session, 'Asset');
tie my %classes, "Tie::IxHash", (
"" => $i18n->get("Any Class"),
$session->db->buildHash("select distinct(className) from asset"),
);
delete $classes{"WebGUI::Asset"}; # don't want to search for the root asset
#my $className = $session->form->process("class","className") || $session->scratch->get('assetManagerSearchClassName');
my $className = $session->form->get('action') ? $session->form->process('class', "className")
: $session->scratch->get('assetManagerSearchPageNumber')
;
$session->scratch->set('assetManagerSearchClassName', $className);
return WebGUI::Form::selectBox( $session, {
name => "class",
value => $className,
defaultValue => "",
options => \%classes,
});
}
#----------------------------------------------------------------------------
=head2 getCurrentAsset ( session )
Returns the asset we would be looking at if we weren't looking at the Asset
Manager.
=cut
sub getCurrentAsset {
my $session = shift;
return WebGUI::Asset->newByUrl( $session );
}
#----------------------------------------------------------------------------
=head2 getHeader ( session )
Get a header to pick "Manage" or "Search". Add other things later maybe?
=cut
sub getHeader {
my $session = shift;
my $output = '';
my $i18n = WebGUI::International->new( $session, "Asset" );
if ( $session->form->get( 'method' ) eq "search" ) {
$output .= '<div style="float: right">'
. join( " | ",
q{<a href="?op=assetManager;method=manage">} . $i18n->get( 'manage' ) . q{</a>},
q{<strong>} . $i18n->get( "search" ) . q{</strong>},
)
. q{</div>}
;
}
else {
$output .= '<div style="float: right">'
. join( " | ",
q{<strong>} . $i18n->get( "manage" ) . q{</strong>},
q{<a href="?op=assetManager;method=search">} . $i18n->get( "search" ) . q{</a>},
)
. q{</div>}
;
}
return $output;
}
#----------------------------------------------------------------------------
=head2 getManagerPaginator ( session )
Get a page for the Asset Manager view. Returns a WebGUI::Paginator object
filled with asset IDs.
=cut
sub getManagerPaginator {
my $session = shift;
my $user = $session->user;
my $asset = getCurrentAsset( $session );
my %update;
my $orderByColumn = $session->form->get( 'orderByColumn' );
if ($orderByColumn) {
$update{assetManagerSortColumn} = $orderByColumn;
}
else {
$orderByColumn = $user->get( 'assetManagerSortColumn' ) || 'lineage';
}
my $orderByDirection = lc $session->form->get( 'orderByDirection' );
if ($orderByDirection) {
$update{assetManagerSortDirection} = $orderByDirection;
}
else {
$orderByDirection = $user->get( 'assetManagerSortDirection' );
}
$orderByDirection = $orderByDirection eq 'desc' ? 'DESC' : 'ASC';
$user->update( \%update ) if ( keys %update );
my $recordOffset = $session->form->get( 'recordOffset' ) || 1;
my $rowsPerPage = $session->form->get( 'rowsPerPage' ) || 100;
my $currentPage = int ( $recordOffset / $rowsPerPage ) + 1;
my $p = WebGUI::Paginator->new( $session, '', $rowsPerPage, 'pn', $currentPage );
my $orderBy = $session->db->dbh->quote_identifier( $orderByColumn ) . ' ' . $orderByDirection;
$p->setDataByArrayRef( $asset->getLineage( ['children'], { orderByClause => $orderBy } ) );
return {
paginator => $p,
sortColumn => $orderByColumn,
sortDirection => lc $orderByDirection,
};
}
#----------------------------------------------------------------------------
=head2 getSearchPaginator ( session, query )
Get a page for the Asset Search view. Returns a WebGUI::Paginator object
filled with asset IDs.
=cut
sub getSearchPaginator {
my $session = shift;
my $query = shift;
my %parms;
my $s = WebGUI::Search->new( $session, 0 );
$s->search( {
assetIds => $query->{ assetIds },
keywords => $query->{ keywords },
classes => $query->{ classes },
} );
my $queryString = 'op=assetManager;method=search;keywords=' . $query->{ keywords };
for my $class ( @{ $query->{ classes } } ) {
$queryString .= ';class=' . $class;
}
##If the form was submitted, we always use page #1. Otherwise, take the page # from the
##form or from the scratch variable.
my $pageNumber = $session->form->get('action') ? 1
: $session->form->get('pn') ? $session->form->get('pn')
: $session->scratch->get('assetManagerSearchPageNumber')
;
my $p = $s->getPaginatorResultSet( $session->url->page( $queryString ), undef, $pageNumber );
$session->scratch->set('assetManagerSearchPageNumber', $pageNumber);
return $p;
}
#----------------------------------------------------------------------------
=head2 getMoreMenu ( session, label )
Gets the "More" menu with the specified label.
=cut
sub getMoreMenu {
my $session = shift;
my $label = shift || "More";
my $userUiLevel = $session->user->profileField("uiLevel");
my $toolbarUiLevel = $session->config->get("assetToolbarUiLevel");
my $i18n = WebGUI::International->new( $session, "Asset" );
### The More menu
my @more_fields = ();
# FIXME: Add a show callback with the record as first argument. If it
# returns true, the URL will be shown.
# These links are shown based on UI level
if ( $userUiLevel >= $toolbarUiLevel->{ "changeUrl" } ) {
push @more_fields, {
url => 'func=changeUrl;proceed=manageAssets',
label => $i18n->get( 'change url' ),
};
}
if ( $userUiLevel >= $toolbarUiLevel->{ "editBranch" } ) {
push @more_fields, {
url => 'func=editBranch',
label => $i18n->get( 'edit branch' ),
};
}
if ( $userUiLevel >= $toolbarUiLevel->{ "shortcut" } ) {
push @more_fields, {
url => 'func=createShortcut;proceed=manageAssets',
label => $i18n->get( 'create shortcut' ),
};
}
if ( $userUiLevel >= $toolbarUiLevel->{ "revisions" } ) {
push @more_fields, {
url => 'func=manageRevisions',
label => $i18n->get( 'revisions' ),
};
}
if ( $userUiLevel >= $toolbarUiLevel->{ "view" } ) {
push @more_fields, {
url => '',
label => $i18n->get( 'view' ),
};
}
if ( $userUiLevel >= $toolbarUiLevel->{ "edit" } ) {
push @more_fields, {
url => 'func=edit;proceed=manageAssets',
label => $i18n->get( 'edit' ),
};
}
if ( $userUiLevel >= $toolbarUiLevel->{ "lock" } ) {
push @more_fields, {
url => 'func=lock;proceed=manageAssets',
label => $i18n->get( 'lock' ),
};
}
if ( $session->config->get("exportPath") && $userUiLevel >= $toolbarUiLevel->{"export"} ) {
push @more_fields, {
url => 'func=export',
label => $i18n->get( 'Export Page' ),
};
}
return to_json \@more_fields;
}
#----------------------------------------------------------------------------
=head2 handler ( session )
Handle the session, if we can. Otherwise pass it on.
Check permissions
=cut
sub handler {
my ( $session ) = @_;
if ( $session->form->get( 'op' ) eq 'assetManager' && getCurrentAsset( $session ) ) {
$session->asset(getCurrentAsset($session));
return $session->privilege->noAccess unless getCurrentAsset( $session )->canEdit;
my $method = $session->form->get( 'method' )
? 'www_' . $session->form->get( 'method' )
: 'www_manage'
;
# Validate the method name
if ( !__PACKAGE__->can( $method ) ) {
return "Invalid method";
}
else {
return __PACKAGE__->can( $method )->( $session );
}
}
else {
return;
}
}
#----------------------------------------------------------------------------
=head2 www_ajaxGetManagerPage ( session )
Get a page of Asset Manager data, ajax style. Returns a JSON array to be
formatted in a WebGUI.AssetManager data table.
=cut
sub www_ajaxGetManagerPage {
my $session = shift;
my $i18n = WebGUI::International->new( $session, "Asset" );
my $assetInfo = { assets => [] };
my $pageInfo = getManagerPaginator( $session );
my $p = $pageInfo->{paginator};
for my $assetId ( @{ $p->getPageData } ) {
my $asset = WebGUI::Asset->newByDynamicClass( $session, $assetId );
unless( $asset ) {
$session->log->error('www_ajaxGetManagerPage: assetId="'.$assetId.'" failed in newByDynamicClass');
next;
}
# Populate the required fields to fill in
my %fields = (
assetId => $asset->getId,
url => $asset->getUrl,
lineage => $asset->get( "lineage" ),
title => $asset->get( "menuTitle" ),
revisionDate => $asset->get( "revisionDate" ),
childCount => $asset->getChildCount,
assetSize => $asset->get( 'assetSize' ),
lockedBy => ($asset->get( 'isLockedBy' ) ? $asset->lockedBy->username : ''),
actions => $asset->canEdit && $asset->canEditIfLocked,
);
$fields{ className } = {};
# The asset icon
my $icon = [ grep { $_->{ icon } } @{ $asset->definition( $session ) } ]->[ 0 ]->{ icon };
$fields{ icon } = $session->url->extras( '/assets/small/' . $icon );
# The asset type (i18n name)
my $type = [ grep { $_->{ assetName } } @{ $asset->definition( $session ) } ]->[ 0 ]->{ assetName };
$fields{ className } = $type;
push @{ $assetInfo->{ assets } }, \%fields;
}
$assetInfo->{ totalAssets } = $p->getRowCount;
$assetInfo->{ sort } = $pageInfo->{sortColumn};
$assetInfo->{ dir } = $pageInfo->{sortDirection};
$session->http->setMimeType( 'application/json' );
return to_json( $assetInfo );
}
#----------------------------------------------------------------------------
=head2 www_manage ( session )
Show the main screen of the asset manager, paginated. Also load the
JavaScript that will take over if the browser has the cojones.
=cut
sub www_manage {
my ( $session ) = @_;
my $ac = WebGUI::AdminConsole->new( $session, "assets", {
showAdminBar => 1
} );
my $currentAsset = getCurrentAsset( $session );
my $i18n = WebGUI::International->new( $session, "Asset" );
### Do Action
my @assetIds = $session->form->get( 'assetId' );
# Handle autocommit workflows
if (WebGUI::VersionTag->autoCommitWorkingIfEnabled($session, {
allowComments => 1,
returnUrl => $currentAsset->getUrl,
}) eq 'redirect' ) {
return undef;
};
# Show the page
# i18n we'll need later
# TODO: Add all i18n to this hash so we can better format our JS code
my %i18n = (
"select all" => $i18n->get( "select all" ),
);
# Add script and stylesheets
$session->style->setLink( $session->url->extras('yui/build/paginator/assets/skins/sam/paginator.css'), {rel=>'stylesheet', type=>'text/css'});
$session->style->setLink( $session->url->extras('yui/build/datatable/assets/skins/sam/datatable.css'), {rel=>'stylesheet', type=>'text/css'});
$session->style->setLink( $session->url->extras('yui/build/menu/assets/skins/sam/menu.css'), {rel=>'stylesheet', type=>'text/css'});
$session->style->setLink( $session->url->extras('yui-webgui/build/assetManager/assetManager.css' ), { rel => "stylesheet", type => 'text/css' } );
$session->style->setScript( $session->url->extras( 'yui/build/utilities/utilities.js' ) );
$session->style->setScript( $session->url->extras( 'yui/build/paginator/paginator-min.js ' ) );
$session->style->setScript( $session->url->extras( 'yui/build/datasource/datasource-min.js ' ) );
$session->style->setScript( $session->url->extras( 'yui/build/datatable/datatable-min.js ' ) );
$session->style->setScript( $session->url->extras( 'yui/build/container/container-min.js' ) );
$session->style->setScript( $session->url->extras( 'yui/build/menu/menu-min.js' ) );
$session->style->setScript( $session->url->extras( 'yui/build/json/json-min.js' ) );
$session->style->setScript( $session->url->extras( 'yui-webgui/build/i18n/i18n.js' ) );
$session->style->setScript( $session->url->extras( 'yui-webgui/build/assetManager/assetManager.js' ) );
$session->style->setScript( $session->url->extras( 'yui-webgui/build/form/form.js' ) );
$session->style->setRawHeadTags( <<ENDHTML );
<script type="text/javascript">
YAHOO.util.Event.onDOMReady( WebGUI.AssetManager.initManager );
</script>
ENDHTML
my $output = '<div class="yui-skin-sam" id="assetManager">' . getHeader( $session );
### Crumbtrail
my $crumb_markup = '<li><a href="%s">%s</a> &gt;</li>';
my $ancestorIter = $currentAsset->getLineageIterator( ['ancestors'] );
$output .= '<ol id="crumbtrail">';
while ( 1 ) {
my $ancestor;
eval { $ancestor = $ancestorIter->() };
if ( my $x = WebGUI::Error->caught('WebGUI::Error::ObjectNotFound') ) {
$session->log->error($x->full_message);
next;
}
last unless $ancestor;
$output .= sprintf $crumb_markup,
$ancestor->getUrl( 'op=assetManager;method=manage' ),
$ancestor->get( "menuTitle" ),
;
}
# And ourself
$output .= sprintf q{<li><a href="#" onclick="WebGUI.AssetManager.showMoreMenu('%s','crumbMoreMenuLink', %s); return false;"><span id="crumbMoreMenuLink">%s</span></a></li>},
$currentAsset->getUrl,
($currentAsset->canEdit && $currentAsset->canEditIfLocked ? 1 : 0),
$currentAsset->get( "menuTitle" ),
;
$output .= '</ol>';
### The page of assets
$output .= sprintf <<EOHTML, $session->asset->getUrl, WebGUI::Form::CsrfToken->new($session)->toHtml, $i18n->get( 'with selected' ), $i18n->get( "update" ), $i18n->get( "delete" ), $i18n->get( '43' ), $i18n->get( 'cut' ), $i18n->get( "Copy" ), $i18n->get( "duplicate" );
<div>
<form method="post" enctype="multipart/form-data" action="%s">
%s
<input type="hidden" name="func" value="manageAssets" />
<input type="hidden" name="proceed" value="manageAssets" />
<div id="dataTableContainer">
</div>
<p class="actions"> %s
<input type="submit" name="action_update" value="%s" onclick="this.form.func.value='setRanks'; this.form.submit(); return false;" />
<input type="submit" name="action_delete" value="%s" onclick="if( confirm('%s')){ this.form.func.value='deleteList'; this.form.submit(); return false;}{ return false; }" />
<input type="submit" name="action_cut" value="%s" onclick="this.form.func.value='cutList'; this.form.submit(); return false;"/>
<input type="submit" name="action_copy" value="%s" onclick="this.form.func.value='copyList'; this.form.submit(); return false;"/>
<input type="submit" name="action_duplicate" value="%s" onclick="this.form.func.value='duplicateList'; this.form.submit(); return false;"/>
</p>
</form>
<div id="pagination">
</div>
</div>
EOHTML
### Clearing div
$output .= q{<div style="clear: both;">&nbsp;</div>};
tie my %options, 'Tie::IxHash';
my $hasClips = 0;
my $clipNum = 0;
foreach my $asset (@{$currentAsset->getAssetsInClipboard(1)}) {
$options{$asset->getId} = '<img src="'.$asset->getIcon(1).'" alt="'.$asset->getName.'" style="border: 0px;" /> '.$asset->getTitle;
$hasClips = 1;
$clipNum++;
}
if ($hasClips) {
$output .= '<div class="functionPane"><fieldset><legend>'.$i18n->get(1082).'</legend>'
.WebGUI::Form::formHeader($session, {action=>$currentAsset->getUrl})
.WebGUI::Form::hidden($session,{name=>"func",value=>"pasteList"})
.WebGUI::Form::hidden($session,{name=>"proceed",value=>"manageAssets"})
.( $clipNum > 1
? WebGUI::Form::checkbox($session,{extras=>'onclick="toggleClipboardSelectAll(this.form);"'}).' '.$i18n->get("select all").'<br />'
: ''
)
.WebGUI::Form::checkList($session,{name=>"assetId",vertical=>1,options=>\%options})
.'<br />'
.WebGUI::Form::submit($session,{value=>$i18n->get('Paste')})
.WebGUI::Form::formFooter($session)
.' </fieldset></div> '
.'<script type="text/javascript">
//<![CDATA[
var clipboardItemSelectAllToggle = false;
function toggleClipboardSelectAll(form){
clipboardItemSelectAllToggle = clipboardItemSelectAllToggle ? false : true;
for(var i = 0; i < form.assetId.length; i++)
form.assetId[i].checked = clipboardItemSelectAllToggle;
}
//]]>
</script>';
}
## Packages
$output .= '<div class="functionPane"><fieldset> <legend>'.$i18n->get("packages").'</legend>';
foreach my $asset (@{$currentAsset->getPackageList}) {
$output .= '<p style="display:inline;vertical-align:middle;"><img src="'.$asset->getIcon(1).'" alt="'.$asset->getName.'" style="vertical-align:middle;border: 0px;" /></p>
<a href="'.$currentAsset->getUrl("func=deployPackage;assetId=".$asset->getId.";proceed=manageAssets").'">'.$asset->getTitle.'</a> '
.$session->icon->edit("func=edit;proceed=manageAssets",$asset->get("url"))
.$session->icon->export("func=exportPackage",$asset->get("url"))
.'<br />';
}
$output .= '<br />'
. WebGUI::Form::formHeader($session, {action=>$currentAsset->getUrl})
. WebGUI::Form::hidden($session, {name=>"func", value=>"importPackage"})
. '<div><input type="file" name="packageFile" size="30" style="font-size: 10px;" /></div>'
. '<div style="font-size: 10px">'
. WebGUI::Form::checkbox($session, { label => $i18n->get('clear package flag'), checked => 0, name => 'clearPackageFlag', value => 1 })
. '<br />'
. WebGUI::Form::checkbox($session, { label => $i18n->get('inherit parent permissions'), checked => 1, name => 'inheritPermissions', value => 1 })
. ' &nbsp; ' . WebGUI::Form::submit($session, { value=>$i18n->get("import"), 'extras' => ' ' })
. '</div>'
. WebGUI::Form::formFooter($session)
;
$output .= ' </fieldset></div>';
### Clearing div
$output .= q{<div style="clear: both;">&nbsp;</div>};
$output .= q{</div>};
### Write the JavaScript that will take over
$output .= '<script type="text/javascript">'
. 'WebGUI.AssetManager.MoreMenuItems = ' . getMoreMenu( $session ) . ';'
;
$output .= <<"ENDJS";
var selectAllButton = "<input type=\\"checkbox\\" title=\\"$i18n{"select all"}\\" onclick=\\"WebGUI.Form.toggleAllCheckboxesInForm( document.forms[0], 'assetId' );\\" />";
ENDJS
# Column defs have i18n, so be careful
# Can't be Perl datastructure because formatter must be a function ref not a string
$output .= q(
WebGUI.AssetManager.ColumnDefs
= [
{ key: 'assetId', label: selectAllButton, formatter: WebGUI.AssetManager.formatAssetIdCheckbox },
{ key: 'lineage', label: ") . $i18n->get( 'rank' ) . q(", sortable: true, formatter: WebGUI.AssetManager.formatRank },
{ key: 'actions', label: "", formatter: WebGUI.AssetManager.formatActions },
{ key: 'title', label: ") . $i18n->get( 99 ) . q(", formatter: WebGUI.AssetManager.formatTitle, sortable: true },
{ key: 'className', label: ") . $i18n->get( 'type' ) . q(", sortable: true, formatter: WebGUI.AssetManager.formatClassName },
{ key: 'revisionDate', label: ") . $i18n->get( 'revision date' ) . q(", formatter: WebGUI.AssetManager.formatRevisionDate, sortable: true },
{ key: 'assetSize', label: ") . $i18n->get( 'size' ) . q(", formatter: WebGUI.AssetManager.formatAssetSize, sortable: true },
{ key: 'lockedBy', label: ") . $i18n->get( 'locked' ) . q(", formatter: WebGUI.AssetManager.formatLockedBy }
];
);
$output .= <<'ENDJS';
</script>
ENDJS
return $ac->render( $output );
}
#----------------------------------------------------------------------------
=head2 www_search ( session )
Search assets underneath this asset.
=cut
sub www_search {
my $session = shift;
my $ac = WebGUI::AdminConsole->new( $session, "assets" );
my $i18n = WebGUI::International->new( $session, "Asset" );
my $currentAsset = getCurrentAsset($session);
my $output = '<div id="assetSearch">' . getHeader( $session );
$session->style->setLink( $session->url->extras( 'yui-webgui/build/assetManager/assetManager.css' ), { rel => "stylesheet", type => 'text/css' } );
$session->style->setScript( $session->url->extras( 'yui/build/yahoo-dom-event/yahoo-dom-event.js' ) );
$session->style->setScript( $session->url->extras( 'yui-webgui/build/assetManager/assetManager.js' ) );
$session->style->setScript( $session->url->extras( 'yui-webgui/build/form/form.js' ) );
my $keywords = $session->form->get('keywords') || $session->scratch->get('assetManagerSearchKeywords');
### Show the form
$output .= q{<form method="post" enctype="multipart/form-data" action="} . $currentAsset->getUrl . q{"><p>}
. q{<input type="hidden" name="op" value="assetManager" />}
. q{<input type="hidden" name="method" value="search" />}
. q{<input type="text" size="45" name="keywords" value="} . $keywords . q{" />}
. getClassSelectBox( $session )
. q{<input type="submit" name="action" value="}.$i18n->get( "search" ).q{" />}
. q{</p></form>}
;
### Run the search
if ( $keywords || $session->form->get( 'class' ) ) {
my @classes = $session->form->get( 'class' );
my $keywordsScrubbed = $keywords;
# Detect a helper word key
my @assetIds = ($keywords =~ /assetid:\s*([^\s]+)/gi);
# purge helper word keys
if (@assetIds) {
$keywordsScrubbed =~ s/\bassetid:\s*[^\s]+//gi;
}
$keywordsScrubbed =~ s/^\s+//g;
$keywordsScrubbed =~ s/\s+$//g;
my $p = getSearchPaginator( $session, {
assetIds => \@assetIds,
keywords => $keywordsScrubbed,
classes => \@classes,
orderByColumn => $session->form->get( 'orderByColumn' ),
orderByDirection => $session->form->get( 'orderByDirection' ),
} );
if ( $p->getRowCount == 0 ) {
$output .= q{<p class="error">} . $i18n->get( 'no results' ) . q{</p>};
}
else {
### Display the search results
$output .= q{<form method="post" enctype="multipart/form-data" action="}.$currentAsset->getUrl.q{">}
. q{<input type="hidden" name="func" value="searchAssets" />}
. q{<input type="hidden" name="proceed" value="searchAssets" />}
. WebGUI::Form::CsrfToken->new($session)->toHtml
. q{<input type="hidden" name="pn" value="} . $session->form->get('pn') . q{" />}
. q{<input type="hidden" name="keywords" value="} . $keywords . q{" />}
;
# Add classes to the form
for my $class ( @classes ) {
$output .= q{<input type="hidden" name="class" value="} . $class . q{" />};
}
$output .= q{<table class="assetSearch" border="0">}
. q{<thead>}
. q{<tr>}
. q{<th class="center"><input type="checkbox" onclick="WebGUI.Form.toggleAllCheckboxesInForm( this.form, 'assetId' )" /></th>} # Checkbox column
. q{<th class="center">&nbsp;</th>} # Edit
. q{<th>} . $i18n->get( '99' ) . q{</th>} # Title
. q{<th>} . $i18n->get( "type" ) . q{</th>} # Type
. q{<th class="center">} . $i18n->get( "last updated" ) . q{</th>} # Revision Date
. q{<th class="center">} . $i18n->get( "size" ) . q{</th>} # Size
. q{<th class="center">} . $i18n->get( "locked" ) . q{</th>} # Lock
. q{</tr>}
. q{</thead}
. q{<tbody>}
;
# The markup for a single asset
my $row_markup = q{<tr %s ondblclick="WebGUI.AssetManager.toggleRow( this )">}
. q{<td class="center"><input type="checkbox" name="assetId" value="%s" onchange="WebGUI.AssetManager.toggleHighlightForRow( this )" /></td>}
. q{<td class="center">%s</td>} #Edit
. q{<td><a href="%s">%s</a></td>} #URL/Title as link
. q{<td><img src="%s" /> %s</td>} #Type
. q{<td class="center">%s</td>} #Revision Date
. q{<td class="right">%s</td>} #Lock
. q{<td class="center"><a href="%s?func=manageRevisions">%s</a></td>}
. q{</tr>}
;
# The field keys to fill in the placeholders
my @row_fields = qw(
alt
assetId
editLink
url
title
iconUrl type
revisionDate
size
url lockIcon
);
my $count = 0;
for my $assetInfo ( @{ $p->getPageData } ) {
$count++;
my $asset = WebGUI::Asset->newByDynamicClass( $session, $assetInfo->{ assetId } );
# Populate the required fields to fill in
my %fields = (
alt => ( $count % 2 == 0 ? 'class="alt"' : '' ),
assetId => $asset->getId,
url => $asset->getUrl,
title => $asset->get( "menuTitle" ),
revisionDate => $session->datetime->epochToHuman( $asset->get( "revisionDate" ) ),
hasChildren => ( $asset->hasChildren ? "+&nbsp;" : "&nbsp;&nbsp;" ),
rank => $asset->getRank,
size => formatBytes( $asset->get( 'assetSize' ) ),
);
# The asset icon
my $icon = [ grep { $_->{ icon } } @{ $asset->definition( $session ) } ]->[ 0 ]->{ icon };
$fields{ iconUrl } = $session->url->extras( '/assets/small/' . $icon );
# The asset type (i18n name)
my $type = [ grep { $_->{ assetName } } @{ $asset->definition( $session ) } ]->[ 0 ]->{ assetName };
$fields{ type } = $type;
# The lock
if ( $asset->lockedBy ) { # lockedBy in case someone overrides isLocked (like the Collab System Thread )
$fields{ lockIcon }
= sprintf '<img src="%s" alt="locked by %s" title="locked by %s" style="border: 0px;" />',
$session->url->extras( 'assetManager/locked.gif' ),
WebGUI::HTML::format( $asset->lockedBy->username, "text" ),
WebGUI::HTML::format( $asset->lockedBy->username, "text" ),
;
}
else {
$fields{ lockIcon }
= sprintf '<img src="%s" alt="unlocked" title="unlocked" style="border: 0px;" />',
$session->url->extras( 'assetManager/unlocked.gif' ),
;
}
# The edit link
if ( !$asset->lockedBy || $asset->canEditIfLocked ) {
$fields{ editLink }
= sprintf '<a href="%s">' . $i18n->get( "edit" ) . '</a>',
$asset->getUrl( 'func=edit;proceed=manageAssets' )
;
}
$output .= sprintf $row_markup, @fields{ @row_fields };
}
$output .= q{</tbody>}
. q{</table>}
. q{<p class="actions">} . $i18n->get( 'with selected' )
. q{<input type="submit" name="action" value="}.$i18n->get( 'delete' ) . q[" onclick="if(confirm('].$i18n->get('43').q[')){this.form.func.value='deleteList'; this.form.submit();}{ return false; }" />]
. q{<input type="submit" name="action" value="}.$i18n->get( "cut" ) . q{" onclick="this.form.func.value='cutList'; this.form.submit();" />}
. q{<input type="submit" name="action" value="}.$i18n->get( "Copy" ) .q{" onclick="this.form.func.value='copyList'; this.form.submit();" />}
. q{</p>}
. q{</form>}
;
### Page links
$output .= q{<div id="pageLinks">} . $p->getBarAdvanced . q{</div>};
### Page description
$output .= sprintf q{<div id="pageStats">} . $i18n->get( 'page indicator' ) . q{</div>},
$p->getPageNumber,
$p->getNumberOfPages,
;
### Clearing div
$output .= q{<div style="clear: both;">&nbsp;</div>};
}
}
$output .= '</div>';
$session->scratch->set('assetManagerSearchKeywords', $keywords);
return $ac->render( $output );
}
1;

View file

@ -0,0 +1,52 @@
package WebGUI::Content::FilePump;
use strict;
use WebGUI::AdminConsole;
use WebGUI::Exception;
use WebGUI::FilePump::Admin;
=head1 NAME
Package WebGUI::Content::FilePump
=head1 DESCRIPTION
Handle all requests for building and editing FilePump bundles
=head1 SYNOPSIS
use WebGUI::Content::FilePump;
my $output = WebGUI::Content::FilePump::handler($session);
=head1 SUBROUTINES
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 handler ( session )
The content handler for this package.
=cut
sub handler {
my ($session) = @_;
my $output = undef;
return undef unless $session->form->get('op') eq 'filePump';
my $func = $session->form->get( 'func' )
? 'www_' . $session->form->get( 'func' )
: 'www_manage'
;
if ($func ne "www_" && (my $sub = WebGUI::FilePump::Admin->can($func))) {
$output = $sub->($session);
}
else {
WebGUI::Error::MethodNotFound->throw(error=>"Couldn't call non-existant function $func inside FilePump", method=>$func);
}
return $output;
}
1;

View file

@ -0,0 +1,64 @@
package WebGUI::Content::Maintenance;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
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;
=head1 NAME
Package WebGUI::Content::Maintenance;
=head1 DESCRIPTION
A content handler that displays a maintenance page while upgrading.
=head1 SYNOPSIS
use WebGUI::Content::Maintenance;
my $output = WebGUI::Content::Maintenance::handler($session);
=head1 SUBROUTINES
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 handler ( session )
The content handler for this package.
=cut
sub handler {
my $session = shift;
if ($session->setting->get("specialState") eq "upgrading") {
$session->http->sendHeader;
my $output = "";
open(my $FILE,"<",$session->config->getWebguiRoot."/docs/maintenance.html");
while (<$FILE>) {
$output .= $_;
}
close($FILE);
return $output;
}
return undef;
}
1;

View file

@ -0,0 +1,65 @@
package WebGUI::Content::NotFound;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
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::Asset;
=head1 NAME
Package WebGUI::Content::NotFound
=head1 DESCRIPTION
A content handler that displays a default page when no other content is produced.
=head1 SYNOPSIS
use WebGUI::Content::NotFound;
my $output = WebGUI::Content::NotFound::handler($session);
=head1 SUBROUTINES
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 handler ( session )
The content handler for this package.
=cut
sub handler {
my ($session) = @_;
$session->http->setStatus("404","Page Not Found");
my $output = "";
my $notFound = WebGUI::Asset->getNotFound($session);
if (defined $notFound) {
$session->asset($notFound);
$output = eval { $notFound->www_view };
}
else {
$session->errorHandler->error("The notFound page could not be instanciated!");
$output = "An error was encountered while processing your request.";
}
$output = "An error was encountered while processing your request." if $output eq '';
return $output;
}
1;

View file

@ -0,0 +1,58 @@
package WebGUI::Content::Operation;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
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::Operation;
=head1 NAME
Package WebGUI::Content::Operation
=head1 DESCRIPTION
A content handler that handles operations.
=head1 SYNOPSIS
use WebGUI::Content::Operation;
my $output = WebGUI::Content::Operation::handler($session);
=head1 SUBROUTINES
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 handler ( session )
The content handler for this package.
=cut
sub handler {
my ($session) = @_;
my $output = "";
my $op = $session->form->process("op");
if ($op) {
$output = WebGUI::Operation::execute($session,$op);
}
return $output;
}
1;

View file

@ -0,0 +1,148 @@
package WebGUI::Content::PDFGenerator;
use warnings;
use strict;
use List::Util qw(first);
use Scope::Guard qw(guard);
use WebGUI::Session;
use WebGUI::Content::Asset;
use WebGUI::Cache;
=head1 NAME
WebGUI::Content::PDFGenerator
=head1 DESCRIPTION
Generates a PDF of the requested URL when op=generatePdf.
=head1 PREREQUISITES
This handler depends on wkpdftohtml, which does not ship with WebGUI and is,
as of this writing, still in active development. This handler was written for
version 0.9.9. It is available from http://code.google.com/p/wkhtmltopdf/.
Compiling is rather difficult, but static binaries are available for the most
popular platforms.
=head1 INSTALLATION
Enable this content handler in your WebGUI config file, placing it somewhere
before WebGUI::Content::Operation, and add a pdfGen section to your config
file at the top level. This must contain the path to your wkhtmltopdf
executable, a cache timeout (how many seconds to cache the pdf), and
optionally the userId of a user to view the page as (defaults to Visitor). It
can also contain additional command line arguments to pass to wkhtmltopdf.
"pdfGen" : {
"exe" : "/usr/local/bin/wkhtmltopdf",
"args" : "--orientation Landscape",
"userId" : "_f7d61hs6djh0fjnxqw21",
"cacheTimeout" : 3600 # 1 hour cache timeout
},
"contentHandlers" : [
#...
"WebGUI::Content::PDFGenerator",
#...
"WebGUI::Content::Operation",
#...
"WebGUI::Content::NotFound"
],
=cut
#-------------------------------------------------------------------
# Return the cached pdf, generating if necessary.
=head2 cache ($asset)
Returns the cached PDF for an asset, if necessary
=cut
sub cache {
my $asset = shift;
my $session = $asset->session;
my $key = [
'PDFGen', $session->url->getRequestedUrl, $asset->get('revisionDate'),
];
my $cache = WebGUI::Cache->new($session, $key);
my $content = $cache->get;
unless ($content) {
$content = generate($asset);
$cache->set($content, $session->config->get('pdfGen/cacheTimeout'));
}
return $content;
}
#-------------------------------------------------------------------
# Generate the pdf unconditionally and return it as a string.
=head2 generate ($asset)
Generate the pdf unconditionally and return it as a string.
=cut
sub generate {
my $asset = shift;
my $session = $asset->session;
my $url = $session->url;
my $c = $session->config;
my $o = $c->get('pdfGen');
my $login = WebGUI::Session->open($c->getWebguiRoot, $c->getFilename);
my $guard = guard { $login->var->end; $login->close };
$login->user({ userId => $o->{userId} || 1 });
my @args = (
$o->{exe}, @{$o->{args} || []},
'--cookie', $c->get('cookieName'), $login->getId,
$url->getSiteURL . $url->gateway($url->getRequestedUrl),
'-'
);
# We're using backticks because trying to run external programs from a
# mod_perl process is extremely tricky any other way, but TODO: figure out
# use a real call and pass an array of args, as that would be safer.
my $cmd = join ' ', @args;
`$cmd`;
}
#-------------------------------------------------------------------
=head2 cache ($asset)
Figure out which asset we need to check permissions for
=cut
sub getRequestedAsset {
my $session = shift;
my $assetUrl = $session->url->getRequestedUrl;
my $perms = WebGUI::Content::Asset::getUrlPermutations($assetUrl);
foreach my $url (@$perms) {
if (my $asset = WebGUI::Content::Asset::getAsset($session, $url)) {
return $asset;
}
}
}
#-------------------------------------------------------------------
# Top-level handler.
=head2 handler ($session)
Top-level handler
=cut
sub handler {
my $session = shift;
my $op = $session->form->get('op');
return undef unless $op && $op eq 'generatePdf';
my $asset = getRequestedAsset($session);
return $session->privilege->noAccess unless $asset->canView;
$session->http->setMimeType('application/pdf');
return cache($asset);
}
1;

View file

@ -0,0 +1,49 @@
package WebGUI::Content::PassiveAnalytics;
use strict;
use WebGUI::AdminConsole;
use WebGUI::Exception;
use WebGUI::PassiveAnalytics::Flow;
=head1 NAME
Package WebGUI::Content::PassiveAnalytics
=head1 DESCRIPTION
Handle all requests for building and editing Passive Analytic flows.
=head1 SYNOPSIS
use WebGUI::Content::PassiveAnalytics;
my $output = WebGUI::Content::PassiveAnalytics::handler($session);
=head1 SUBROUTINES
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 handler ( session )
The content handler for this package.
=cut
sub handler {
my ($session) = @_;
my $output = undef;
return undef unless $session->form->get('op') eq 'passiveAnalytics';
my $function = "www_".$session->form->get('func');
if ($function ne "www_" && (my $sub = WebGUI::PassiveAnalytics::Flow->can($function))) {
$output = $sub->($session);
}
else {
WebGUI::Error::MethodNotFound->throw(error=>"Couldn't call non-existant method $function inside PassiveAnalytics", method=>$function);
}
return $output;
}
1;

View file

@ -0,0 +1,56 @@
package WebGUI::Content::Prefetch;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
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;
=head1 NAME
Package WebGUI::Content::Prefetch
=head1 DESCRIPTION
A content handler that prevents prefetching browsers.
=head1 SYNOPSIS
use WebGUI::Content::Prefetch;
my $output = WebGUI::Content::Prefetch::handler($session);
=head1 SUBROUTINES
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 handler ( session )
The content handler for this package.
=cut
sub handler {
my ($session) = @_;
if ($session->env->get("HTTP_X_MOZ") eq "prefetch") { # browser prefetch is a bad thing
$session->http->setStatus("403","We don't allow prefetch, because it increases bandwidth, hurts stats, and can break web sites.");
}
return undef;
}
1;

View file

@ -0,0 +1,55 @@
package WebGUI::Content::Referral;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
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::Affiliate;
=head1 NAME
Package WebGUI::Content::Referral
=head1 DESCRIPTION
Processes referrals from other sites.
=head1 SYNOPSIS
use WebGUI::Content::Referral;
my $output = WebGUI::Content::Referral::handler($session);
=head1 SUBROUTINES
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 handler ( session )
The content handler for this package.
=cut
sub handler {
my ($session) = @_;
WebGUI::Affiliate::grabReferral($session); # process affiliate tracking request
return undef;
}
1;

View file

@ -0,0 +1,83 @@
package WebGUI::Content::SetLanguage;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
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::International;
=head1 NAME
Package WebGUI::Content::SetLanguage
=head1 DESCRIPTION
Sets or delete an scratch variable that overrides the profile field language
=head1 SYNOPSIS
use WebGUI::Content::SetLanguage;
WebGUI::Content::SetLanguage::handler();
=head1 SUBROUTINES
These subroutines are available from this package:
handler
=cut
#-------------------------------------------------------------
=head2 handler ( session, op, setLanguage )
sets or delete scratch variable in a session and returns undef
=head3 session
The current WebGUI::Session object.
=head3 op
op should be setLanguage to call the handler
=head3 language
language should be an installed language or delete
=cut
sub handler {
my ($session) = @_;
return undef unless $session->form->get('op') eq 'setLanguage';
my $language = $session->form->get('language');
#check whether a language has been given in the url
if (!$language) {
$session->log->error('There is no language given to this method');
return undef;
}
#make it possible to delete the language scratch variable from the session
if ($language eq 'delete' ) {
$session->scratch->removeLanguageOverride;
return undef;
}
#set a scratch variable language or throw error if language is not installed
else {
return $session->scratch->setLanguageOverride($language);
}
}
1;

View file

@ -0,0 +1,64 @@
package WebGUI::Content::Setup;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
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::Wizard::Setup;
=head1 NAME
Package WebGUI::Setup
=head1 DESCRIPTION
Initializes a new WebGUI install.
=head1 SYNOPSIS
use WebGUI::Setup;
WebGUI::Content::Setup::handler();
=head1 SUBROUTINES
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 handler ( session )
Handles a specialState: "init"
=head3 session
The current WebGUI::Session object.
=cut
sub handler {
my $session = shift;
my $form = $session->form;
unless ( $session->setting->get("specialState") eq "init" ) {
return undef;
}
# Dispatch to the setup wizard
my $wiz = WebGUI::Wizard::Setup->new( $session );
return $wiz->dispatch;
}
1;

279
lib/WebGUI/Content/Shop.pm Normal file
View file

@ -0,0 +1,279 @@
package WebGUI::Content::Shop;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
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::AdminConsole;
use WebGUI::Exception::Shop;
use WebGUI::Shop::AddressBook;
use WebGUI::Shop::Cart;
use WebGUI::Shop::Credit;
use WebGUI::Shop::Pay;
use WebGUI::Shop::Ship;
use WebGUI::Shop::Tax;
use WebGUI::Shop::Transaction;
use WebGUI::Shop::Vendor;
=head1 NAME
Package WebGUI::Content::Shop
=head1 DESCRIPTION
A content handler that opens up all the commerce functionality. The shop modules are accessed via the url like this:
/pagename?shop=modulehandler;method=www_method
For example:
/home?shop=transaction;method=manage
In the above we're accessing the WebGUI::Shop::Transaction module, which is configured with the www_transaction() sub in this package. And we're calling www_manage() on that object.
=head1 SYNOPSIS
use WebGUI::Content::Shop;
my $output = WebGUI::Content::Shop::handler($session);
=head1 SUBROUTINES
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 handler ( session )
The content handler for this package.
=cut
sub handler {
my ($session) = @_;
my $output = undef;
my $shop = $session->form->get("shop");
return $output unless ($shop);
my $function = "www_".$shop;
if ($function ne "www_" && (my $sub = __PACKAGE__->can($function))) {
$output = $sub->($session);
}
else {
WebGUI::Error::MethodNotFound->throw(error=>"Couldn't call non-existant method $function", method=>$function);
}
return $output;
}
#-------------------------------------------------------------------
=head2 www_address ()
Hand off to the address book.
=cut
sub www_address {
my $session = shift;
my $output = undef;
my $method = "www_". ( $session->form->get("method") || "view");
my $cart = WebGUI::Shop::AddressBook->newByUserId($session);
if ($cart->can($method)) {
$output = $cart->$method();
}
else {
WebGUI::Error::MethodNotFound->throw(error=>"Couldn't call non-existant method $method", method=>$method);
}
return $output;
}
#-------------------------------------------------------------------
=head2 www_admin ()
Hand off to admin processor.
=cut
sub www_admin {
my $session = shift;
my $output = undef;
my $method = "www_". ( $session->form->get("method") || "editSettings");
my $admin = WebGUI::Shop::Admin->new($session);
if ($admin->can($method)) {
$output = $admin->$method();
}
else {
WebGUI::Error::MethodNotFound->throw(error=>"Couldn't call non-existant method $method", method=>$method);
}
return $output;
}
#-------------------------------------------------------------------
=head2 www_cart ()
Hand off to the cart.
=cut
sub www_cart {
my $session = shift;
my $output = undef;
my $method = "www_". ( $session->form->get("method") || "view");
my $cart = WebGUI::Shop::Cart->newBySession($session);
if ($cart->can($method)) {
$output = $cart->$method();
}
else {
WebGUI::Error::MethodNotFound->throw(error=>"Couldn't call non-existant method $method", method=>$method);
}
return $output;
}
#-------------------------------------------------------------------
=head2 www_credit ()
Hand off to the credit system.
=cut
sub www_credit {
my $session = shift;
my $output = undef;
my $method = "www_".$session->form->get("method");
if ($method ne "www_" && WebGUI::Shop::Credit->can($method)) {
$output = WebGUI::Shop::Credit->$method($session);
}
else {
WebGUI::Error::MethodNotFound->throw(error=>"Couldn't call non-existant method $method", method=>$method);
}
return $output;
}
#-------------------------------------------------------------------
=head2 www_pay ()
Hand off to the payment gateway.
=cut
sub www_pay {
my $session = shift;
my $output = undef;
my $method = "www_".$session->form->get("method");
my $pay = WebGUI::Shop::Pay->new($session);
if ($method ne "www_" && $pay->can($method)) {
$output = $pay->$method();
}
else {
WebGUI::Error::MethodNotFound->throw(error=>"Couldn't call non-existant method $method", method=>$method);
}
return $output;
}
#-------------------------------------------------------------------
=head2 www_ship ()
Hand off to the shipper.
=cut
sub www_ship {
my $session = shift;
my $output = undef;
my $method = "www_".$session->form->get("method");
my $ship = WebGUI::Shop::Ship->new($session);
if ($method ne "www_" && $ship->can($method)) {
$output = $ship->$method($session);
}
else {
WebGUI::Error::MethodNotFound->throw(error=>"Couldn't call non-existant method $method", method=>$method);
}
return $output;
}
#-------------------------------------------------------------------
=head2 www_tax ()
Hand off to the tax system.
=cut
sub www_tax {
my $session = shift;
my $output = undef;
my $method = "www_".$session->form->get("method");
my $tax = WebGUI::Shop::Tax->new($session);
if ($method ne "www_" && $tax->can($method)) {
$output = $tax->$method();
}
else {
WebGUI::Error::MethodNotFound->throw(error=>"Couldn't call non-existant method $method", method=>$method);
}
return $output;
}
#-------------------------------------------------------------------
=head2 www_transaction ()
Hand off to the transaction system.
=cut
sub www_transaction {
my $session = shift;
my $output = undef;
my $method = "www_".$session->form->get("method");
if ($method ne "www_" && WebGUI::Shop::Transaction->can($method)) {
$output = WebGUI::Shop::Transaction->$method($session);
}
else {
WebGUI::Error::MethodNotFound->throw(error=>"Couldn't call non-existant method $method", method=>$method);
}
return $output;
}
#-------------------------------------------------------------------
=head2 www_vendor ()
Hand off to the vendor system.
=cut
sub www_vendor {
my $session = shift;
my $output = undef;
my $method = "www_".$session->form->get("method");
if ($method ne "www_" && WebGUI::Shop::Vendor->can($method)) {
$output = WebGUI::Shop::Vendor->$method($session);
}
else {
WebGUI::Error::MethodNotFound->throw(error=>"Couldn't call non-existant method $method", method=>$method);
}
return $output;
}
1;

View file

@ -0,0 +1,125 @@
package WebGUI::Content::SiteIndex;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
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::Asset;
use WebGUI::Exception;
use XML::Simple;
=head1 NAME
Package WebGUI::Content::SiteIndex
=head1 DESCRIPTION
A content handler that displays a google site index making it easier and faster
for search engines to index a website.
=head1 SYNOPSIS
use WebGUI::Content::SiteIndex;
my $output = WebGUI::Content::SiteIndex::handler($session);
=head1 SUBROUTINES
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 handler ( session )
The content handler for this package.
=cut
sub handler {
my $session = shift;
my $p = $session->url->page();
unless ($p =~ m/sitemap\.xml$/i) {
return undef;
}
my $whereClause = "assetData.groupIdView = 7";
if (! $session->config->get("siteIndex")->{showHiddenPages}) {
$whereClause .= ' AND assetData.isHidden=0';
}
my $pages = WebGUI::Asset->getRoot($session)->getLineageIterator(["self","descendants"],{
includeOnlyClasses => ["WebGUI::Asset::Wobject::Layout"],
whereClause => $whereClause,
limit => 20000
});
my $url = [];
ASSET: while (1) {
my $page = eval { $pages->() };
if (my $e = Exception::Class->caught()) {
$session->log->error($@);
next ASSET;
}
last ASSET unless $page;
push(@{$url},{
loc => $session->url->getSiteURL().formatXML($page->getUrl),
lastmod => $session->datetime->epochToSet($page->get("revisionDate")),
});
}
my $xmlStructure = { url => $url };
my $xml =
'<?xml version="1.0" encoding="UTF-8"?>'
.'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'
. XMLout( $xmlStructure,
NoAttr => 1,
KeepRoot => 1,
KeyAttr => ["url"],
)
.'</urlset>';
$session->http->setMimeType('text/xml');
return $xml;
}
#-------------------------------------------------------------------
=head2 formatXML ( content )
Escape XML entities, &, <, >, ' and ".
=head3 content
The content that will have XML entities escaped.
=cut
sub formatXML {
my $content = shift;
$content =~ s/&/&amp;/g;
$content =~ s/\</&lt;/g;
$content =~ s/\>/&gt;/g;
$content =~ s/'/&apos;/g;
$content =~ s/"/&quot;/g;
return $content;
}
1;

View file

@ -0,0 +1,45 @@
package WebGUI::Content::Wizard;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
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
-------------------------------------------------------------------
=head1 NAME
Package WebGUI::Content::Wizard
=head1 DESCRIPTION
A content handler for WebGUI::Wizard modules. Dispatches to WebGUI::Wizard after process form variables.
=head2 handler ( session )
The content handler for this package.
=cut
sub handler {
my ( $session ) = @_;
if ( $session->form->get('op') eq 'wizard' && $session->form->get('wizard_class') ) {
my $class = $session->form->get('wizard_class');
WebGUI::Pluggable->load($class);
if ( $class->isa( 'WebGUI::Wizard' ) ) {
my $wizard = $class->new( $session );
return $wizard->dispatch;
}
else {
return "Sminternal Smerver Smerror";
}
}
}
1;

View file

@ -0,0 +1,55 @@
package WebGUI::Content::MyHandler;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2009 Plain Black Corporation.
-------------------------------------------------------------------
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;
=head1 NAME
Package WebGUI::Content::MyHandler
=head1 DESCRIPTION
A content handler that does whatever I tell it to do.
=head1 SYNOPSIS
use WebGUI::Content::MyHandler;
my $output = WebGUI::Content::MyHandler::handler($session);
=head1 SUBROUTINES
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 handler ( session )
The content handler for this package.
=cut
sub handler {
my ($session) = @_;
my $output = "";
# ...
return $output;
}
1;
#vim:ft=perl