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;