webgui/lib/WebGUI/Account.pm
2011-05-25 15:44:46 -05:00

560 lines
14 KiB
Perl

package WebGUI::Account;
use strict;
use Class::InsideOut qw{ :std };
use WebGUI::Exception;
use Carp qw(croak);
use WebGUI::International;
use WebGUI::Pluggable;
use WebGUI::Utility;
=head1 NAME
Package WebGUI::Account::Profile
=head1 DESCRIPTION
This is the class which is used to display a users's profile information
=head1 SYNOPSIS
use base 'WebGUI::Account';
currentState("edit");
=head1 METHODS
These subroutines are available from this package:
=cut
#-------------------------------------------------------------------
=head2 session ()
Returns a reference to the current WebGUI::Session object.
=cut
readonly session => my %session;
#-------------------------------------------------------------------
=head2 module ()
Returns the string representation of the name of the last Account module called.
=cut
readonly module => my %module;
#-------------------------------------------------------------------
=head2 method ()
Returns the string representation of the name of the last method called on the module().
=cut
public method => my %method;
#-------------------------------------------------------------------
=head2 uid ( [ userId ] )
Returns the userId of the WebGUI::User who's account is being interacted with.
=head3 userId
Optionally set the userId. Normally this is never needed, but is provided for completeness.
=cut
public uid => my %uid;
#-------------------------------------------------------------------
=head2 bare ( [ flag ] )
Returns whether or not the Account system should return a method's content
without the layout and style templates. This would normally be used for
returning JSON or XML data out of the account system.
=head3 flag
Optionally set bare to be true, or false.
=cut
#-------------------------------------------------------------------
=head2 store ( [ hashRef ] )
Returns a hash reference attached to this account object that contains arbitrary data.
=head2 hashRef
A hash reference of data to store.
=cut
public store => my %store; #This is an all purpose hash to store stuff in: $self->store->{something} = "something"
public bare => my %bare; #This flag indicates that neither the layout nor style template should be applied
#to the output of the method. Think JSON/XML, etc.
#-------------------------------------------------------------------
=head2 appendCommonVars ( var )
Appends common template variables that all most templates will use
=head3 var
The hash reference to append template variables to
=cut
sub appendCommonVars {
my $self = shift;
my $var = shift;
my $session = $self->session;
my $user = $self->getUser;
$var->{'profile_user_id' } = $user->userId;
$var->{'user_full_name' } = $user->getWholeName;
$var->{'user_member_since'} = $user->dateCreated;
$var->{'view_profile_url' } = $user->getProfileUrl;
$var->{'root_url' } = $session->url->page("op=account");
$var->{'back_url' } = $session->url->getBackToSiteURL;
}
#-------------------------------------------------------------------
=head2 callMethod ( [ method, args, uid ] )
Calls the method passed in
=head3 method
Method to call. If no method is passed in, the view method is called
=head3 args
array reference of arguments to pass to the method being called.
=head3 uid
uid to set in the object.
=cut
sub callMethod {
my $self = shift;
my $method = shift || "view";
my $args = shift;
my $uid = shift;
my $module = $self->module;
#Set the method in the object
$self->method($method);
#Set the uid in the object
$self->uid($uid);
$method = "www_".$method;
unless ($self->can($method)) {
WebGUI::Error::MethodNotFound->throw(
error => qq{Could not locate method $method in the $module module of the account system},
method => $method
);
return undef;
}
unless ($self->canView) {
my $session = $self->session;
$session->output->print($session->privilege->insufficient);
return undef;
}
#Try to call the method
my $output = eval { $self->$method(@{$args}) };
#Croak on error
if($@) {
croak "Unable to run $method on $module: $@";
return undef;
}
#Return the output from the method call
return $output;
}
#-------------------------------------------------------------------
=head2 displayContent ( content[, withoutStyle] )
Wraps the content in the style and layout of the account pluggin
=head3 content
Content to wrap in the pluggin style and layout
=head3 withoutStyle
Return the layout without the style wrapper
=cut
sub displayContent {
my $self = shift;
my $content = shift;
my $noStyle = shift;
my $session = $self->session;
##Don't do any templating if we're sending back data like JSON or XML.
return $content if $self->bare;
##Don't do any templating if we're sending back data like JSON or XML.
return $content if $self->bare;
#Wrap content into the layout
my $var = {};
$var->{content} = $content;
my $configs = $session->config->get("account");
my $method = $self->method || "view";
# Get fieldsets for avaiable account methods in the order they exist in the config file and append them to the template
my @pluggins = ();
foreach my $account (@{$configs}) {
#Instantiate the pluggin
my $instance = undef;
my $identifier = $account->{identifier};
#Use the currently instantiated pluggin if we are checking this pluggin
if($account->{identifier} eq $self->module) {
$instance = $self;
}
else {
#Eval it as we don't want to fail if there's a problem with another method in the config file
$instance = eval { WebGUI::Content::Account->createInstance($session,$identifier) };
if (my $e = WebGUI::Error->caught) {
$session->log->warn("Couldn't instantiate Account Pluggin ".$account->{className}." ... skipping");
next;
}
elsif(!$instance->isa('WebGUI::Account')) {
$session->log->warn((ref $instance)." is not a subclass of WebGUI::Account ... skipping");
next;
}
#Set the current uid state in the instance
$instance->uid($self->uid);
}
#Skip this module if the user can't view it
next unless ($instance->canView);
#Push the tab variables onto the template
my %hash = %{$account};
$hash{'is_'.$identifier } = "true";
$hash{'is_method_'.$self->method } = "true";
$hash{'url' } = $instance->getUrl("module=$identifier",1);
$hash{'isActive' } = "true" if($identifier eq $self->module);
WebGUI::Macro::process($session,\$hash{'title'});
push(@pluggins,\%hash);
}
$var->{'account_loop'} = \@pluggins;
#Append common display variables to the layout template
$self->appendCommonVars($var);
#Process the layout template
my $output = $self->processTemplate($var,$self->getLayoutTemplateId);
return $output if($noStyle);
#Wrap the layout in the user style
$session->http->setCacheControl("none");
return $session->style->process($output,$self->getStyleTemplateId);
}
#-------------------------------------------------------------------
=head2 canView ( )
Override this method to create permission levels for your Account Pluggin
=cut
sub canView {
my $self = shift;
return 1;
}
#-------------------------------------------------------------------
=head2 editSettingsForm ( )
Override this method to create settings for your Account Pluggin
=cut
sub editSettingsForm {
my $self = shift;
return "";
}
#-------------------------------------------------------------------
=head2 editSettingsFormSave ( )
Override this method to create settings for your Account Pluggin
=cut
sub editSettingsFormSave {
my $self = shift;
return "";
}
#-------------------------------------------------------------------
=head2 getLayoutTemplateId ( )
Override this method to return the template Id for the account layout. The default
account layout draws a tabbed interface to the different account plugins, and displays
the content from a particular screen from the account plugin.
=cut
sub getLayoutTemplateId {
my $self = shift;
return "N716tpSna0iIQTKxS4gTWA";
}
#-------------------------------------------------------------------
=head2 getStyleTemplateId ( )
Override this method to return the template for the main style. The style would
be for the page that the account layout template is embedded in.
=cut
sub getStyleTemplateId {
my $self = shift;
return $self->session->setting->get("userFunctionStyleId");
}
#-------------------------------------------------------------------
=head2 getUrl ( [pairs,appendUID] )
Builds the url for the current page.
=head3 pairs
name value pairs to append to the page url. If pairs is not passed in
the current module and do values will be used.
=head3 appendUID
If this flag is set and uid is passed as a URL param, that uid will be
appended to the end of the url.
=cut
sub getUrl {
my $self = shift;
my $pairs = shift;
my $appendUID = shift;
my $session = $self->session;
my $uid = $self->uid;
if($pairs) {
#Append op=account to the url if it doesn't already exist
unless ($pairs =~ m/op=account/){
$pairs = "op=account;".$pairs;
}
}
else {
$pairs = q{op=account;module=}.$self->module.q{;do=}.$self->method;
}
$pairs .= ";uid=".$uid if($appendUID && $uid);
return $session->url->page($pairs);
}
#-------------------------------------------------------------------
=head2 getUser
Gets the user, either specified by the uid URL parameter, or the
session user.
=cut
sub getUser {
my $self = shift;
if ($self->uid) {
return WebGUI::User->new($self->session, $self->uid);
}
else {
return $self->session->user;
}
}
#-------------------------------------------------------------------
=head2 new ( session, module [,method ,uid] )
Constructor.
=head3 $session
A WebGUI::Session object.
=head3 module
The module being called
=cut
sub new {
my $class = shift;
my $session = shift;
my $module = shift;
unless (ref $session eq 'WebGUI::Session') {
WebGUI::Error::InvalidObject->throw(
expected =>"WebGUI::Session",
got =>(ref $session),
error => q{Must provide a session variable}
);
}
my $self = register $class;
my $id = id $self;
$session { $id } = $session;
$module { $id } = $module;
$store { $id } = {};
$method { $id } = "view";
$uid { $id } = undef;
$bare { $id } = 0;
return $self;
}
#-------------------------------------------------------------------
=head2 processTemplate ( vars, templateId, template )
Returns the content generated from this template. It adds the Asset control
bar to the template variables, as well as all Asset properties and metadata.
=head3 vars
A hash reference containing variables and loops to pass to the template engine.
=head3 templateId
An id referring to a particular template in the templates table.
=head3 template
Instead of passing in a templateId, you may pass in a template object.
=cut
sub processTemplate {
my $self = shift;
my $session = $self->session;
my $var = shift;
my $templateId = shift;
my $template = shift;
my $className = ref $self;
# Sanity checks
if (ref $var ne "HASH") {
$session->log->error("First argument to processTemplate() should be a hash reference.");
my $i18n = WebGUI::International->new($session, 'Account');
return sprintf($i18n->get('Error: Cannot instantiate template'),$templateId,$className);
}
$template = WebGUI::Asset->new($session, $templateId,"WebGUI::Asset::Template") unless (defined $template);
unless (defined $template) {
$session->log->error("Can't instantiate template $templateId for class ".$className);
my $i18n = WebGUI::International->new($session, 'Account');
return sprintf($i18n->get('Error: Cannot instantiate template'),$templateId,$className);
}
return $template->process($var);
}
#-------------------------------------------------------------------
=head2 showError ( vars )
Returns a general error screen with the message passed in.
=head3 vars
Variable hash ref to append errors to
=head3 error
Error message to display
=head3 url
URL to display to the user to go back to a safe place
=head3 templateId
temlateId to use to display error
=cut
sub showError {
my $self = shift;
my $var = shift || {};
$var->{'error_message'} = shift;
$var->{'back_url' } = shift;
my $templateId = shift;
return $self->processTemplate($var,$templateId)
}
#-------------------------------------------------------------------
=head2 store ( )
This method returns an internal hash where you can store things for your Account Plugin.
The store is private to your plugin, to each user's copy of the plugin, and only lasts as
long as the session does.
=cut
#-------------------------------------------------------------------
=head2 store ( )
This method returns an internal hash where you can store things for your Account Plugin.
The store is private to your plugin, to each user's copy of the plugin, and only lasts as
long as the session does.
=cut
1;