From d754931286cdd935b6e374b3a344c579ed7dc114 Mon Sep 17 00:00:00 2001 From: Frank Dillon Date: Mon, 3 Nov 2008 16:19:48 +0000 Subject: [PATCH 1/8] WebGUI branch for frank to develop WebGUI features to be added to WebGUI once they've been tested From 7b260de791f9adaf2227b375d14376eefb71cb73 Mon Sep 17 00:00:00 2001 From: Frank Dillon Date: Mon, 3 Nov 2008 17:03:00 +0000 Subject: [PATCH 2/8] initial commit --- lib/WebGUI/Account.pm | 163 +++++++++++++++++++++ lib/WebGUI/Account/Friends.pm | 153 +++++++++++++++++++ lib/WebGUI/Account/Inbox.pm | 124 ++++++++++++++++ lib/WebGUI/Account/Profile.pm | 146 ++++++++++++++++++ lib/WebGUI/Account/User.pm | 124 ++++++++++++++++ lib/WebGUI/Content/Account.pm | 124 ++++++++++++++++ lib/WebGUI/Exception/Account.pm | 63 ++++++++ lib/WebGUI/Operation/Settings.pm | 31 ++++ lib/WebGUI/i18n/English/Account.pm | 14 ++ lib/WebGUI/i18n/English/Account_Friends.pm | 15 ++ lib/WebGUI/i18n/English/Account_Inbox.pm | 15 ++ lib/WebGUI/i18n/English/Account_Profile.pm | 53 +++++++ lib/WebGUI/i18n/English/Account_User.pm | 15 ++ lib/WebGUI/i18n/English/WebGUI.pm | 6 + 14 files changed, 1046 insertions(+) create mode 100644 lib/WebGUI/Account.pm create mode 100644 lib/WebGUI/Account/Friends.pm create mode 100644 lib/WebGUI/Account/Inbox.pm create mode 100644 lib/WebGUI/Account/Profile.pm create mode 100644 lib/WebGUI/Account/User.pm create mode 100644 lib/WebGUI/Content/Account.pm create mode 100644 lib/WebGUI/Exception/Account.pm create mode 100644 lib/WebGUI/i18n/English/Account.pm create mode 100644 lib/WebGUI/i18n/English/Account_Friends.pm create mode 100644 lib/WebGUI/i18n/English/Account_Inbox.pm create mode 100644 lib/WebGUI/i18n/English/Account_Profile.pm create mode 100644 lib/WebGUI/i18n/English/Account_User.pm diff --git a/lib/WebGUI/Account.pm b/lib/WebGUI/Account.pm new file mode 100644 index 000000000..de38f603e --- /dev/null +++ b/lib/WebGUI/Account.pm @@ -0,0 +1,163 @@ +package WebGUI::Account; + +use strict; + +use Class::InsideOut qw{ :std }; +use WebGUI::Exception; +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 WebGUI::Account::Profile; + +=head1 METHODS + +These subroutines are available from this package: + +=cut + +readonly session => my %session; + +#------------------------------------------------------------------- + +=head2 editSettingsForm ( ) + + Override this method to create settings for your Account Pluggin + +=cut + +sub editUserSettingsForm { + my $self = shift; + return ""; +} + +#------------------------------------------------------------------- + +=head2 editSettingsFormSave ( ) + + Override this method to create settings for your Account Pluggin + +=cut + +sub editUserSettingsFormSave { + my $self = shift; + return ""; +} + + +#------------------------------------------------------------------- + +=head2 getLayoutTemplateId ( ) + + Override this method to return the template Id for the account layout. + +=cut + +sub getLayoutTemplateId { + my $self = shift; + return "FJbUTvZ2nUTn65LpW6gjsA"; +} + +#------------------------------------------------------------------- + +=head2 getStyleTemplate ( ) + + Override this method to return the template for the main style. + +=cut + +sub getStyleTemplateId { + my $self = shift; + return $self->session->setting->get("userFunctionStyleId"); +} + +#------------------------------------------------------------------- + +=head2 new ( $session ) + +Constructor. + +=head3 $session + +A WebGUI::Session object. + +=cut + +sub new { + my $class = shift; + my $session = 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; + 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($self->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($self->session, 'Account'); + return sprintf($i18n->get('Error: Cannot instantiate template'),$templateId,$className); + } + + return $template->process($var); +} + + +1; diff --git a/lib/WebGUI/Account/Friends.pm b/lib/WebGUI/Account/Friends.pm new file mode 100644 index 000000000..10e219eab --- /dev/null +++ b/lib/WebGUI/Account/Friends.pm @@ -0,0 +1,153 @@ +package WebGUI::Account::Friends; + +use strict; + +use WebGUI::Exception; +use WebGUI::International; +use WebGUI::Pluggable; +use WebGUI::Utility; +use base qw/WebGUI::Account/; + +=head1 NAME + +Package WebGUI::Account::Friends + +=head1 DESCRIPTION + +This is the class which is used to display a users's friends + +=head1 SYNOPSIS + + use WebGUI::Account::Friends; + +=head1 METHODS + +These subroutines are available from this package: + +=cut + + +#------------------------------------------------------------------- + +=head2 editSettingsForm ( ) + + Creates form elements for user settings page custom to this account module + +=cut + +sub editUserSettingsForm { + my $self = shift; + my $session = $self->session; + my $setting = $session->setting; + my $i18n = WebGUI::International->new($session,'Account_Friends'); + my $f = WebGUI::HTMLForm->new($session); + +# $f->template( +# name => "profileStyleTemplateId", +# value => $self->getStyleTemplateId, +# namespace => "style", +# label => $i18n->get("profile style template label"), +# hoverHelp => $i18n->get("profile style template hoverHelp") +# ); + + return $f->printRowsOnly; +} + +#------------------------------------------------------------------- + +=head2 editSettingsFormSave ( ) + + Creates form elements for user settings page custom to this account module + +=cut + +sub editUserSettingsFormSave { +} + +#------------------------------------------------------------------- + +=head2 getDisplayTemplateId ( ) + +This method returns the template ID for the account layout. + +=cut + +sub getDisplayTemplateId { + my $self = shift; + return $self->session->setting->get("friendsDisplayTempalteId") || "defaultAssetId"; +} + +#------------------------------------------------------------------- + +=head2 getLayoutTemplateId ( ) + +This method returns the template ID for the account layout. + +=cut + +sub getLayoutTemplateId { + my $self = shift; + return $self->session->setting->get("friendsLayoutTempalteId") || $self->SUPER::getLayoutTemplateId; +} + + +#------------------------------------------------------------------- + +=head2 getStyleTemplateId ( ) + +This method returns the template ID for the main style. + +=cut + +sub getStyleTemplateId { + my $self = shift; + return $self->session->setting->get("friendsStyleTemplateId") || $self->SUPER::getStyleTemplateId; +} + +#------------------------------------------------------------------- + +=head2 getViewTemplateId ( ) + +This method returns the template ID for the main view. + +=cut + +sub getViewTemplateId { + my $self = shift; + return $self->session->setting->get("friendsViewTemplateId") || "defaultAssetId"; +} + +#------------------------------------------------------------------- + +=head2 www_display ( ) + +The main view page for displaying the user's profile. + +=cut + +sub www_display { + my $self = shift; + my $session = $self->session; + my $var = {}; + + return $self->processTemplate($var,$self->getDisplayTemplateId); +} + +#------------------------------------------------------------------- + +=head2 www_view ( ) + +The main view page for editing the user's profile. + +=cut + +sub www_view { + my $self = shift; + my $session = $self->session; + my $var = {}; + + return $self->processTemplate($var,$self->getViewTemplateId); +} + + +1; diff --git a/lib/WebGUI/Account/Inbox.pm b/lib/WebGUI/Account/Inbox.pm new file mode 100644 index 000000000..3ec4ea23f --- /dev/null +++ b/lib/WebGUI/Account/Inbox.pm @@ -0,0 +1,124 @@ +package WebGUI::Account::Inbox; + +use strict; + +use WebGUI::Exception; +use WebGUI::International; +use WebGUI::Pluggable; +use WebGUI::Utility; +use base qw/WebGUI::Account/; + +=head1 NAME + +Package WebGUI::Account::Inbox + +=head1 DESCRIPTION + +This is the class which is used to display a users's inbox + +=head1 SYNOPSIS + + use WebGUI::Account::Inbox; + +=head1 METHODS + +These subroutines are available from this package: + +=cut + + +#------------------------------------------------------------------- + +=head2 editSettingsForm ( ) + + Creates form elements for user settings page custom to this account module + +=cut + +sub editUserSettingsForm { + my $self = shift; + my $session = $self->session; + my $setting = $session->setting; + my $i18n = WebGUI::International->new($session,'Account_Inbox'); + my $f = WebGUI::HTMLForm->new($session); + +# $f->template( +# name => "profileStyleTemplateId", +# value => $self->getStyleTemplateId, +# namespace => "style", +# label => $i18n->get("profile style template label"), +# hoverHelp => $i18n->get("profile style template hoverHelp") +# ); + + return $f->printRowsOnly; +} + +#------------------------------------------------------------------- + +=head2 editSettingsFormSave ( ) + + Creates form elements for user settings page custom to this account module + +=cut + +sub editUserSettingsFormSave { +} + +#------------------------------------------------------------------- + +=head2 getLayoutTemplateId ( ) + +This method returns the template ID for the account layout. + +=cut + +sub getLayoutTemplateId { + my $self = shift; + return $self->session->setting->get("inboxLayoutTempalteId") || $self->SUPER::getLayoutTemplateId; +} + + +#------------------------------------------------------------------- + +=head2 getStyleTemplateId ( ) + +This method returns the template ID for the main style. + +=cut + +sub getStyleTemplateId { + my $self = shift; + return $self->session->setting->get("inboxStyleTemplateId") || $self->SUPER::getStyleTemplateId; +} + +#------------------------------------------------------------------- + +=head2 getViewTemplateId ( ) + +This method returns the template ID for the main view. + +=cut + +sub getViewTemplateId { + my $self = shift; + return $self->session->setting->get("inboxViewTemplateId") || "defaultAssetId"; +} + +#------------------------------------------------------------------- + +=head2 www_view ( ) + +The main view page for editing the user's profile. + +=cut + +sub www_view { + my $self = shift; + my $session = $self->session; + my $var = {}; + + return $self->processTemplate($var,$self->getViewTemplateId); +} + + +1; diff --git a/lib/WebGUI/Account/Profile.pm b/lib/WebGUI/Account/Profile.pm new file mode 100644 index 000000000..410167616 --- /dev/null +++ b/lib/WebGUI/Account/Profile.pm @@ -0,0 +1,146 @@ +package WebGUI::Account::Profile; + +use strict; + +use WebGUI::Exception; +use WebGUI::International; +use WebGUI::Pluggable; +use WebGUI::Utility; +use base qw/WebGUI::Account/; + +=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 WebGUI::Account::Profile; + +=head1 METHODS + +These subroutines are available from this package: + +=cut + + +#------------------------------------------------------------------- + +=head2 editSettingsForm ( ) + + Creates form elements for user settings page custom to this account module + +=cut + +sub editUserSettingsForm { + my $self = shift; + my $session = $self->session; + my $setting = $session->setting; + my $i18n = WebGUI::International->new($session,'Account_Profile'); + my $f = WebGUI::HTMLForm->new($session); + + $f->template( + name => "profileStyleTemplateId", + value => $self->getStyleTemplateId, + namespace => "style", + label => $i18n->get("profile style template label"), + hoverHelp => $i18n->get("profile style template hoverHelp") + ); + $f->template( + name => "profileLayoutTempalteId", + value => $self->getLayoutTemplateId, + namespace => "Account/Layout", + label => $i18n->get("profile layout template label"), + hoverHelp => $i18n->get("profile layout template hoverHelp") + ); + $f->template( + name => "profileViewTemplateId", + value => $self->getViewTemplateId, + namespace => "Account/Profile/View", + label => $i18n->get("profile view template label"), + hoverHelp => $i18n->get("profile view template hoverHelp") + ); + $f->template( + name => "profileEditTemplateId", + value => $setting->get("profileEditTemplateId"), + namespace => "Account/Profile/Edit", + label => $i18n->get("profile edit template label"), + hoverHelp => $i18n->get("profile edit template hoverHelp") + ); + + return $f->printRowsOnly; +} + +#------------------------------------------------------------------- + +=head2 getDisplayTemplateId ( ) + +This method returns the template ID for the account layout. + +=cut + +sub getDisplayTemplateId { + my $self = shift; + return $self->session->setting->get("profileDisplayTempalteId") || "defaultAssetId"; +} + +#------------------------------------------------------------------- + +=head2 getLayoutTemplateId ( ) + +This method returns the template ID for the account layout. + +=cut + +sub getLayoutTemplateId { + my $self = shift; + return $self->session->setting->get("profileLayoutTempalteId") || $self->SUPER::getLayoutTemplateId; +} + +#------------------------------------------------------------------- + +=head2 getStyleTemplateId ( ) + +This method returns the template ID for the main style. + +=cut + +sub getStyleTemplateId { + my $self = shift; + return $self->session->setting->get("profileStyleTemplateId") || $self->SUPER::getStyleTemplateId; +} + +#------------------------------------------------------------------- + +=head2 getViewTemplateId ( ) + +This method returns the template ID for the main view. + +=cut + +sub getViewTemplateId { + my $self = shift; + return $self->session->setting->get("profileViewTemplateId") || "75CmQgpcCSkdsL-oawdn3Q"; +} + +#------------------------------------------------------------------- + +=head2 www_view ( ) + +The main view page for the user's profile. + +=cut + +sub www_view { + my $self = shift; + my $session = $self->session; + my $var = {}; + + return $self->processTemplate($var,$session->setting->get("profileViewTemplateId")); +} + + +1; diff --git a/lib/WebGUI/Account/User.pm b/lib/WebGUI/Account/User.pm new file mode 100644 index 000000000..ffeebc415 --- /dev/null +++ b/lib/WebGUI/Account/User.pm @@ -0,0 +1,124 @@ +package WebGUI::Account::User; + +use strict; + +use WebGUI::Exception; +use WebGUI::International; +use WebGUI::Pluggable; +use WebGUI::Utility; +use base qw/WebGUI::Account/; + +=head1 NAME + +Package WebGUI::Account::User + +=head1 DESCRIPTION + +This is the class which is used to display a users's account details + +=head1 SYNOPSIS + + use WebGUI::Account::User; + +=head1 METHODS + +These subroutines are available from this package: + +=cut + + +#------------------------------------------------------------------- + +=head2 editSettingsForm ( ) + + Creates form elements for user settings page custom to this account module + +=cut + +sub editUserSettingsForm { + my $self = shift; + my $session = $self->session; + my $setting = $session->setting; + my $i18n = WebGUI::International->new($session,'Account_User'); + my $f = WebGUI::HTMLForm->new($session); + +# $f->template( +# name => "profileStyleTemplateId", +# value => $self->getStyleTemplateId, +# namespace => "style", +# label => $i18n->get("profile style template label"), +# hoverHelp => $i18n->get("profile style template hoverHelp") +# ); + + return $f->printRowsOnly; +} + +#------------------------------------------------------------------- + +=head2 editSettingsFormSave ( ) + + Creates form elements for user settings page custom to this account module + +=cut + +sub editUserSettingsFormSave { +} + +#------------------------------------------------------------------- + +=head2 getLayoutTemplateId ( ) + +This method returns the template ID for the account layout. + +=cut + +sub getLayoutTemplateId { + my $self = shift; + return $self->session->setting->get("userLayoutTempalteId") || $self->SUPER::getLayoutTemplateId; +} + + +#------------------------------------------------------------------- + +=head2 getStyleTemplateId ( ) + +This method returns the template ID for the main style. + +=cut + +sub getStyleTemplateId { + my $self = shift; + return $self->session->setting->get("userStyleTemplateId") || $self->SUPER::getStyleTemplateId; +} + +#------------------------------------------------------------------- + +=head2 getViewTemplateId ( ) + +This method returns the template ID for the main view. + +=cut + +sub getViewTemplateId { + my $self = shift; + return $self->session->setting->get("userViewTemplateId") || "defaultAssetId"; +} + +#------------------------------------------------------------------- + +=head2 www_view ( ) + +The main view page for editing the user's profile. + +=cut + +sub www_view { + my $self = shift; + my $session = $self->session; + my $var = {}; + + return $self->processTemplate($var,$self->getViewTemplateId); +} + + +1; diff --git a/lib/WebGUI/Content/Account.pm b/lib/WebGUI/Content/Account.pm new file mode 100644 index 000000000..c41b9e69a --- /dev/null +++ b/lib/WebGUI/Content/Account.pm @@ -0,0 +1,124 @@ +package WebGUI::Content::Account; + +=head1 LEGAL + + ------------------------------------------------------------------- + WebGUI is Copyright 2001-2008 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::Account; +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 handler ( session ) + +The content handler for this package. + +=cut + +sub handler { + my $session = shift; + my $form = $session->form; + + my $output = undef; + + my $op = $session->form->get("op"); + my $configs = $session->config->get("account"); + + if ($configs->{$op}) { + return $session->privilege->insufficient if($session->user->isVisitor); + #$session->errorHandler->warn("Loading module : ".$configs->{$op}->{className}); + + #Create Pluggin Object + #Don't eval this as pluggable will croak and we want WebGUI::URL::Content to handle the exception + my $pluggin = WebGUI::Pluggable::instanciate($configs->{$op}->{className}, "new", [ $session ] ); + + #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' + ); + } + + #Process the method call + my $method = $session->form->get("do") || "view"; + $method = "www_".$method; + + if($pluggin->can($method)) { + $output = eval { $pluggin->$method($session) }; + } + else { + WebGUI::Error::MethodNotFound->throw( + error => "Couldn't call non-existant method $method", + method => $method + ); + } + + #Wrap content returned from method call into the layout + my $var = {}; + $var->{content} = $output; + my $layoutId = $pluggin->getLayoutTemplateId; + $output = $pluggin->processTemplate($var,$layoutId); + + #Wrap the layout in the user style + $session->http->setCacheControl("none"); + $output = $session->style->process($output,$session->setting->get("userFunctionStyleId")); + } + + return $output; +} + + +1; + diff --git a/lib/WebGUI/Exception/Account.pm b/lib/WebGUI/Exception/Account.pm new file mode 100644 index 000000000..e5ad7e37a --- /dev/null +++ b/lib/WebGUI/Exception/Account.pm @@ -0,0 +1,63 @@ +package WebGUI::Exception::Account; + +=head1 LEGAL + + ------------------------------------------------------------------- + WebGUI is Copyright 2001-2008 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::Exception; +use Exception::Class ( + + 'WebGUI::Error::Account::NoAccountInfo' => { + description => "Some items restrict how many you can put into your cart.", + }, +); + + +=head1 NAME + +Package WebGUI::Exception::Account + +=head1 DESCRIPTION + +Exceptions which apply only to the WebGUI account system. + +=head1 SYNOPSIS + + use WebGUI::Exception::Account; + + # throw + WebGUI::Error::Account::MaxOfItemInCartReached->throw(error=>"Too many in cart."); + + # try + eval { $cart->addItem($ku) }; + + # catch + if (my $e = WebGUI::Error->caught("WebGUI::Error::Shop::MaxOfItemInCartReached")) { + # do something + } + +=head1 EXCEPTION TYPES + +These exception classes are defined in this class: + + +=head2 WebGUI::Error::Shop::MaxOfItemInCartReached + +Throw this when there are too many items of a given type added to the cart so that the user can be notified. ISA WebGUI::Error. + +=cut + + +1; + diff --git a/lib/WebGUI/Operation/Settings.pm b/lib/WebGUI/Operation/Settings.pm index cd03374e6..c980492d7 100644 --- a/lib/WebGUI/Operation/Settings.pm +++ b/lib/WebGUI/Operation/Settings.pm @@ -15,6 +15,7 @@ use Tie::IxHash; use WebGUI::AdminConsole; use WebGUI::TabForm; use WebGUI::International; +use WebGUI::Macro; use WebGUI::SQL; =head1 NAME @@ -603,6 +604,7 @@ sub www_editSettings { ui => { label => $i18n->get("ui") }, messaging => { label => $i18n->get("messaging") }, misc => { label => $i18n->get("misc") }, + account => { label => $i18n->get("account settings tab")}, user => { label => $i18n->get("user") }, auth => { label => $i18n->get("authentication") }, perms => { label => $i18n->get("permissions") }, @@ -628,6 +630,35 @@ sub www_editSettings { $tabform->getTab("auth")->fieldSetEnd; } + # Get fieldsets for avaiable account methods + my $accountConfigs = $session->config->get("account"); + foreach my $accountKey (keys %{$accountConfigs}) { + my $account = $accountConfigs->{$accountKey}; + + #Create the instance + my $className = $account->{className}; + my $instance = eval { WebGUI::Pluggable::instanciate($className,"new",[ $session ]) }; + + if ( my $e = WebGUI::Error->caught ) { + $session->log->warn("Could not instantiate account pluggin $className...skipping"); + next; + } + + #Get the content of the settings form from the instance + my $settingsForm = $instance->editUserSettingsForm; + #If editUserSettingsForm is empty, skip it + next if $settingsForm eq ""; + + #Set the title of the fieldset + my $title = $account->{title}; + WebGUI::Macro::process($title); + + #Print the settings form for this account pluggin + $tabform->getTab("account")->fieldSetStart($title); + $tabform->getTab("account")->raw($settingsForm); + $tabform->getTab("account")->fieldSetEnd; + } + $tabform->submit(); $output .= $tabform->print; diff --git a/lib/WebGUI/i18n/English/Account.pm b/lib/WebGUI/i18n/English/Account.pm new file mode 100644 index 000000000..d43c2c618 --- /dev/null +++ b/lib/WebGUI/i18n/English/Account.pm @@ -0,0 +1,14 @@ +package WebGUI::i18n::English::Account_Profile; +use strict; + +our $I18N = { + + 'Error: Cannot instantiate template' => { + message => q{Error: Cannot instantiate template %s for class %s}, + lastUpdated => 1225724810, + context => q{Error message in Account.pm}, + }, + +}; + +1; diff --git a/lib/WebGUI/i18n/English/Account_Friends.pm b/lib/WebGUI/i18n/English/Account_Friends.pm new file mode 100644 index 000000000..83a41ffba --- /dev/null +++ b/lib/WebGUI/i18n/English/Account_Friends.pm @@ -0,0 +1,15 @@ +package WebGUI::i18n::English::Account_Friends; +use strict; + +our $I18N = { + + 'title' => { + message => q{Friends}, + lastUpdated => 1225724810, + context => q{Tab label for Friends Account pluggin}, + }, + + +}; + +1; diff --git a/lib/WebGUI/i18n/English/Account_Inbox.pm b/lib/WebGUI/i18n/English/Account_Inbox.pm new file mode 100644 index 000000000..ad27f61e0 --- /dev/null +++ b/lib/WebGUI/i18n/English/Account_Inbox.pm @@ -0,0 +1,15 @@ +package WebGUI::i18n::English::Account_Inbox; +use strict; + +our $I18N = { + + 'title' => { + message => q{Inbox}, + lastUpdated => 1225724810, + context => q{Tab label for Inbox Account pluggin}, + }, + + +}; + +1; diff --git a/lib/WebGUI/i18n/English/Account_Profile.pm b/lib/WebGUI/i18n/English/Account_Profile.pm new file mode 100644 index 000000000..621e24fde --- /dev/null +++ b/lib/WebGUI/i18n/English/Account_Profile.pm @@ -0,0 +1,53 @@ +package WebGUI::i18n::English::Account_Profile; +use strict; + +our $I18N = { + + 'title' => { + message => q{Profile}, + lastUpdated => 1225724810, + context => q{Tab label for Profile Account pluggin}, + }, + + 'profile style template label' => { + message => q|Style Template|, + lastUpdated => 1119068809 + }, + + 'profile style template hoverHelp' => { + message => q|Select a style template from the list to enclose your Wobject if it is viewed directly. If the Wobject is displayed as part of a Layout Asset, the Layout Asset's Style Template is used instead.|, + lastUpdated => 1119068809 + }, + + 'profile layout template label' => { + message => q|Layout Template|, + lastUpdated => 1119068809 + }, + + 'profile layout template hoverHelp' => { + message => q|Choose a layout from the list to display the various account pluggins and the contents of the one currently chosen|, + lastUpdated => 1119068809 + }, + + 'profile view template label' => { + message => q|View Template|, + lastUpdated => 1119068809 + }, + + 'profile view template hoverHelp' => { + message => q|Choose the main template for viewing a profile|, + lastUpdated => 1119068809 + }, + + 'profile edit template label' => { + message => q|Edit Template|, + lastUpdated => 1119068809 + }, + + 'profile edit template hoverHelp' => { + message => q|Choose the main template for editing a profile|, + lastUpdated => 1119068809 + }, +}; + +1; diff --git a/lib/WebGUI/i18n/English/Account_User.pm b/lib/WebGUI/i18n/English/Account_User.pm new file mode 100644 index 000000000..c18edc6ea --- /dev/null +++ b/lib/WebGUI/i18n/English/Account_User.pm @@ -0,0 +1,15 @@ +package WebGUI::i18n::English::Account_User; +use strict; + +our $I18N = { + + 'title' => { + message => q{User}, + lastUpdated => 1225724810, + context => q{Tab label for User Account pluggin}, + }, + + +}; + +1; diff --git a/lib/WebGUI/i18n/English/WebGUI.pm b/lib/WebGUI/i18n/English/WebGUI.pm index 81cc4c7e5..f58144ee1 100644 --- a/lib/WebGUI/i18n/English/WebGUI.pm +++ b/lib/WebGUI/i18n/English/WebGUI.pm @@ -3229,6 +3229,12 @@ a user.|, lastUpdated => 1118941685, }, + 'account settings tab' => { + message => q|Account|, + lastUpdated => 1098327046, + context => q|Tab label for the account settings in WebGUI Settings.| + }, + 'account' => { message => q|Account|, lastUpdated => 1098327046, From 93df39d6f6dc049c352c61d78cfceeef6b4eb838 Mon Sep 17 00:00:00 2001 From: Frank Dillon Date: Mon, 3 Nov 2008 18:34:26 +0000 Subject: [PATCH 3/8] resetdev installs account system --- docs/upgrades/upgrade_7.6.1-7.6.2.pl | 51 ++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/docs/upgrades/upgrade_7.6.1-7.6.2.pl b/docs/upgrades/upgrade_7.6.1-7.6.2.pl index c0fa36e5a..05f298be1 100644 --- a/docs/upgrades/upgrade_7.6.1-7.6.2.pl +++ b/docs/upgrades/upgrade_7.6.1-7.6.2.pl @@ -20,6 +20,7 @@ use Getopt::Long; use WebGUI::Session; use WebGUI::Storage; use WebGUI::Asset; +use WebGUI::Utility; my $toVersion = '7.6.2'; @@ -39,8 +40,58 @@ addProfileExtrasField($session); addWorkflowToDataform( $session ); installDataTableAsset( $session ); installAjaxI18N( $session ); +upgradeAccount( $session ); finish($session); # this line required +#---------------------------------------------------------------------------- +sub upgradeAccount { + my $session = shift; + my $config = $session->config; + my $setting = $session->setting; + + print "\tUpgrading WebGUI Account System... " unless $quiet; + #Add account properties to config file + $session->config->delete("account"); #Delete account if it exists + $session->config->set("account",{ + profile => { + title => "^International(title,Account_Profile);", + className => "WebGUI::Account::Profile", + }, + friends => { + title => "^International(title,Account_Friends);", + className => "WebGUI::Account::Friends", + }, + user => { + title => "^International(title,Account_User);", + className => "WebGUI::Account::User", + }, + inbox => { + title => "^International(title,Account_Inbox);", + className => "WebGUI::Account::Inbox", + } + }); + + #Add the content handler to the config file if it's not there + my $oldHandlers = $session->config->get( "contentHandlers" ); + unless (isIn("WebGUI::Content::Account",@{$oldHandlers})) { + my @newHandlers; + for my $handler ( @{ $oldHandlers } ) { + if ( $handler eq "WebGUI::Content::Operation" ) { + push @newHandlers, "WebGUI::Content::Account"; + } + push @newHandlers, $handler; + } + $session->config->set( "contentHandlers", \@newHandlers ); + } + + #Add the settings + $setting->add("profileStyleTemplateId",""); #Use the userStyle by default + $session->setting->add("profileLayoutTempalteId","FJbUTvZ2nUTn65LpW6gjsA"); + $session->setting->add("profileViewTemplateId","75CmQgpcCSkdsL-oawdn3Q"); + + print "DONE!\n" unless $quiet; +} + #---------------------------------------------------------------------------- # installDataTableAsset # Install the asset by creating the DB table and adding it to the config file From 615e0e37461fa80dda89bc005b01bc5c45ea7d91 Mon Sep 17 00:00:00 2001 From: Frank Dillon Date: Wed, 12 Nov 2008 23:03:42 +0000 Subject: [PATCH 4/8] lots of changes --- docs/upgrades/upgrade_7.6.1-7.6.2.pl | 132 +++- etc/WebGUI.conf.original | 2 + lib/WebGUI/Account.pm | 116 +++- lib/WebGUI/Account/Friends.pm | 4 +- lib/WebGUI/Account/Inbox.pm | 763 ++++++++++++++++++++- lib/WebGUI/Account/Profile.pm | 466 ++++++++++++- lib/WebGUI/Account/User.pm | 4 +- lib/WebGUI/Content/Account.pm | 97 ++- lib/WebGUI/Form/File.pm | 8 + lib/WebGUI/Form/Image.pm | 5 +- lib/WebGUI/Group.pm | 42 +- lib/WebGUI/Inbox.pm | 430 ++++++++++-- lib/WebGUI/Inbox/Message.pm | 320 ++++++++- lib/WebGUI/Macro/FileUrl.pm | 40 +- lib/WebGUI/Operation/Inbox.pm | 48 +- lib/WebGUI/Operation/Profile.pm | 22 +- lib/WebGUI/Operation/ProfileSettings.pm | 15 +- lib/WebGUI/Operation/Settings.pm | 22 +- lib/WebGUI/Paginator.pm | 1 + lib/WebGUI/ProfileCategory.pm | 19 + lib/WebGUI/ProfileField.pm | 69 +- lib/WebGUI/Storage.pm | 5 +- lib/WebGUI/User.pm | 73 +- lib/WebGUI/i18n/English/Account_Inbox.pm | 269 ++++++++ lib/WebGUI/i18n/English/Account_Profile.pm | 71 +- lib/WebGUI/i18n/English/WebGUI.pm | 40 ++ lib/WebGUI/i18n/English/WebGUIProfile.pm | 10 + www/extras/FileUploadControl.js | 2 +- 28 files changed, 2883 insertions(+), 212 deletions(-) diff --git a/docs/upgrades/upgrade_7.6.1-7.6.2.pl b/docs/upgrades/upgrade_7.6.1-7.6.2.pl index 05f298be1..7cae6ebd9 100644 --- a/docs/upgrades/upgrade_7.6.1-7.6.2.pl +++ b/docs/upgrades/upgrade_7.6.1-7.6.2.pl @@ -21,6 +21,7 @@ use WebGUI::Session; use WebGUI::Storage; use WebGUI::Asset; use WebGUI::Utility; +use Tie::IxHash; my $toVersion = '7.6.2'; @@ -40,9 +41,20 @@ addProfileExtrasField($session); addWorkflowToDataform( $session ); installDataTableAsset( $session ); installAjaxI18N( $session ); +fixFriendsGroups( $session ); upgradeAccount( $session ); finish($session); # this line required +#---------------------------------------------------------------------------- +sub fixFriendsGroups { + my $session = shift; + my $users = $session->db->buildArrayRef("select userId from users where friendsGroup is not null && friendsGroup != ''"); + foreach my $userId (@{$users}) { + #purge the admin group + WebGUI::User->new($session,$userId)->friends->deleteGroups([3]); + } +} + #---------------------------------------------------------------------------- sub upgradeAccount { my $session = shift; @@ -52,25 +64,29 @@ sub upgradeAccount { print "\tUpgrading WebGUI Account System... " unless $quiet; #Add account properties to config file $session->config->delete("account"); #Delete account if it exists - $session->config->set("account",{ - profile => { - title => "^International(title,Account_Profile);", - className => "WebGUI::Account::Profile", - }, - friends => { - title => "^International(title,Account_Friends);", - className => "WebGUI::Account::Friends", - }, - user => { - title => "^International(title,Account_User);", - className => "WebGUI::Account::User", + $session->config->set("account",[ + { + identifier => "profile", + title => "^International(title,Account_Profile);", + className => "WebGUI::Account::Profile" }, - inbox => { - title => "^International(title,Account_Inbox);", - className => "WebGUI::Account::Inbox", - } - }); - + { + identifier => "inbox", + title => "^International(title,Account_Inbox);", + className => "WebGUI::Account::Inbox" + }, + { + identifier => "friends", + title => "^International(title,Account_Friends);", + className => "WebGUI::Account::Friends" + }, + { + identifier => "user", + title => "^International(title,Account_User);", + className => "WebGUI::Account::User" + }, + ]); + $session->config->set("profileModuleIdentifier","profile"); #Add the content handler to the config file if it's not there my $oldHandlers = $session->config->get( "contentHandlers" ); unless (isIn("WebGUI::Content::Account",@{$oldHandlers})) { @@ -84,10 +100,84 @@ sub upgradeAccount { $session->config->set( "contentHandlers", \@newHandlers ); } - #Add the settings + #Add the settings for the profile $setting->add("profileStyleTemplateId",""); #Use the userStyle by default - $session->setting->add("profileLayoutTempalteId","FJbUTvZ2nUTn65LpW6gjsA"); - $session->setting->add("profileViewTemplateId","75CmQgpcCSkdsL-oawdn3Q"); + $setting->add("profileLayoutTemplateId","N716tpSna0iIQTKxS4gTWA"); + $setting->add("profileEditLayoutTemplateId","FJbUTvZ2nUTn65LpW6gjsA"); + $setting->add("profileEditTemplateId","75CmQgpcCSkdsL-oawdn3Q"); + $setting->add("profileViewTempalteId","2CS-BErrjMmESOtGT90qOg"); + + #Add the settings for the inbox + $setting->add("inboxStyleTemplateId",""); #Use the userStyle by default + $setting->add("inboxLayoutTempalteId","N716tpSna0iIQTKxS4gTWA"); + $setting->add("inboxViewTemplateId","c8xrwVuu5QE0XtF9DiVzLw"); + $setting->add("inboxViewMessageTemplateId","0n4HtbXaWa_XJHkFjetnLQ"); + $setting->add("inboxSendMessageTemplateId","6uQEULvXFgCYlRWnYzZsuA"); + $setting->add("inboxErrorTemplateId","ErEzulFiEKDkaCDVmxUavw"); + $setting->add("inboxInvitationErrorTemplateId","5A8Hd9zXvByTDy4x-H28qw"); + $setting->add("inboxMessageConfirmationTemplateId","DUoxlTBXhVS-Zl3CFDpt9g"); + $setting->add("inboxManageInvitationsTemplateId","1Q4Je3hKCJzeo0ZBB5YB8g"); + + #Add inbox changes + $session->db->write(q{ + create table inbox_messageState ( + messageId char(22) binary not null, + userId char(22) binary not null, + isRead tinyint(4) not null default 0, + repliedTo tinyint(4) not null default 0, + deleted tinyint(4) not null default 0, + primary key (messageId, userId) + ) + }); + + #Update the inbox + my $sth = $session->db->read("select messageId, groupId, userId, status from inbox"); + while(my ($messageId,$groupId,$userId,$status) = $sth->array) { + my $repliedTo = $status eq "replied"; + my $isRead = ($status ne "unread" && $status ne "pending")?1:0; + my $deleted = 0; + + if($status eq "deleted") { + #Purge deleted messages + $session->db->write("delete from inbox where messageId=?",[$messageId]); + next; + } + + if($groupId) { + my $g = WebGUI::Group->new($session,$groupId); + my $users = $g->getAllUsers; + foreach my $userId (@{$users}) { + $session->db->write( + q{ REPLACE INTO inbox_messageState (messageId,userId,isRead,repliedTo,deleted) VALUES (?,?,?,?,?) }, + [$messageId,$userId,$isRead,$repliedTo,$deleted] + ); + } + } + + if($userId) { + $session->db->write( + q{ REPLACE INTO inbox_messageState (messageId,userId,isRead,repliedTo,deleted) VALUES (?,?,?,?,?) }, + [$messageId,$userId,$isRead,$repliedTo,$deleted] + ); + } + + if($status ne "completed" && $status ne "pending") { + $session->db->write( + q{ UPDATE inbox SET status='active' WHERE messageId=? }, + [$messageId] + ); + } + } + + #Add the profile field changes + $session->db->write(q{alter table userProfileCategory add column shortLabel char(255) default NULL after label}); + $session->db->write(q{update userProfileCategory set shortLabel='WebGUI::International::get("misc info short","WebGUI");' where profileCategoryId='1'}); + $session->db->write(q{update userProfileCategory set shortLabel='WebGUI::International::get("contact info short","WebGUI");' where profileCategoryId='2'}); + $session->db->write(q{update userProfileCategory set shortLabel='WebGUI::International::get("personal info short","WebGUI");' where profileCategoryId='3'}); + $session->db->write(q{update userProfileCategory set shortLabel='WebGUI::International::get("preferences short","WebGUI");' where profileCategoryId='4'}); + $session->db->write(q{update userProfileCategory set shortLabel='WebGUI::International::get("home info short","WebGUI");' where profileCategoryId='5'}); + $session->db->write(q{update userProfileCategory set shortLabel='WebGUI::International::get("work info short","WebGUI");' where profileCategoryId='6'}); + $session->db->write(q{update userProfileCategory set shortLabel='WebGUI::International::get("demographic info short","WebGUI");' where profileCategoryId='7'}); print "DONE!\n" unless $quiet; } diff --git a/etc/WebGUI.conf.original b/etc/WebGUI.conf.original index e1163d4bb..e4ef49be4 100644 --- a/etc/WebGUI.conf.original +++ b/etc/WebGUI.conf.original @@ -831,9 +831,11 @@ "WebGUI::Content::Referral", "WebGUI::Content::AssetManager", "WebGUI::Content::AssetDiscovery", + "WebGUI::Content::AjaxI18N", "WebGUI::Content::Operation", "WebGUI::Content::Setup", "WebGUI::Content::Shop", + "WebGUI::Content::SiteIndex", "WebGUI::Content::Asset", "WebGUI::Content::NotFound" ], diff --git a/lib/WebGUI/Account.pm b/lib/WebGUI/Account.pm index de38f603e..82cc50d6a 100644 --- a/lib/WebGUI/Account.pm +++ b/lib/WebGUI/Account.pm @@ -18,7 +18,9 @@ This is the class which is used to display a users's profile information =head1 SYNOPSIS - use WebGUI::Account::Profile; + use base 'WebGUI::Account'; + + currentState("edit"); =head1 METHODS @@ -27,6 +29,20 @@ These subroutines are available from this package: =cut readonly session => my %session; +public store => my %store; #This is an all purpose hash to store stuff in: $store{id $self}->{something} = "something" + +#------------------------------------------------------------------- + +=head2 canView ( ) + + Override this method to create permission levels for your Account Pluggin + +=cut + +sub canView { + my $self = shift; + return 1; +} #------------------------------------------------------------------- @@ -36,7 +52,7 @@ readonly session => my %session; =cut -sub editUserSettingsForm { +sub editSettingsForm { my $self = shift; return ""; } @@ -49,12 +65,11 @@ sub editUserSettingsForm { =cut -sub editUserSettingsFormSave { +sub editSettingsFormSave { my $self = shift; return ""; } - #------------------------------------------------------------------- =head2 getLayoutTemplateId ( ) @@ -65,7 +80,7 @@ sub editUserSettingsFormSave { sub getLayoutTemplateId { my $self = shift; - return "FJbUTvZ2nUTn65LpW6gjsA"; + return "N716tpSna0iIQTKxS4gTWA"; } #------------------------------------------------------------------- @@ -81,6 +96,49 @@ sub getStyleTemplateId { 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 along the url, the uid passed in will be + appended to the end of it to the end of the url + +=cut + +sub getUrl { + my $self = shift; + my $pairs = shift; + my $appendUID = shift; + + my $session = $self->session; + my $form = $session->form; + + 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=}.$form->get("module").q{;do=}.$form->get("do"); + } + + my $uid = $form->get("uid"); + $pairs .= ";uid=".$uid if($appendUID && $uid); + + return $session->url->page($pairs); +} + #------------------------------------------------------------------- =head2 new ( $session ) @@ -105,9 +163,10 @@ sub new { ); } - my $self = register $class; - my $id = id $self; - $session { $id } = $session; + my $self = register $class; + my $id = id $self; + $session { $id } = $session; + $store { $id } = {}; return $self; } @@ -144,7 +203,7 @@ sub processTemplate { # Sanity checks if (ref $var ne "HASH") { $session->log->error("First argument to processTemplate() should be a hash reference."); - my $i18n = WebGUI::International->new($self->session, 'Account'); + my $i18n = WebGUI::International->new($session, 'Account'); return sprintf($i18n->get('Error: Cannot instantiate template'),$templateId,$className); } @@ -152,7 +211,7 @@ sub processTemplate { unless (defined $template) { $session->log->error("Can't instantiate template $templateId for class ".$className); - my $i18n = WebGUI::International->new($self->session, 'Account'); + my $i18n = WebGUI::International->new($session, 'Account'); return sprintf($i18n->get('Error: Cannot instantiate template'),$templateId,$className); } @@ -160,4 +219,41 @@ sub processTemplate { } +#------------------------------------------------------------------- + +=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) +} + + 1; diff --git a/lib/WebGUI/Account/Friends.pm b/lib/WebGUI/Account/Friends.pm index 10e219eab..77e4fe034 100644 --- a/lib/WebGUI/Account/Friends.pm +++ b/lib/WebGUI/Account/Friends.pm @@ -35,7 +35,7 @@ These subroutines are available from this package: =cut -sub editUserSettingsForm { +sub editSettingsForm { my $self = shift; my $session = $self->session; my $setting = $session->setting; @@ -61,7 +61,7 @@ sub editUserSettingsForm { =cut -sub editUserSettingsFormSave { +sub editSettingsFormSave { } #------------------------------------------------------------------- diff --git a/lib/WebGUI/Account/Inbox.pm b/lib/WebGUI/Account/Inbox.pm index 3ec4ea23f..7f36efd1f 100644 --- a/lib/WebGUI/Account/Inbox.pm +++ b/lib/WebGUI/Account/Inbox.pm @@ -2,6 +2,7 @@ package WebGUI::Account::Inbox; use strict; +use WebGUI::Form; use WebGUI::Exception; use WebGUI::International; use WebGUI::Pluggable; @@ -27,6 +28,51 @@ These subroutines are available from this package: =cut +#------------------------------------------------------------------- + +=head2 appendCommonVars ( var, inbox ) + + Appends common template variables that all inbox templates use + +=head3 var + + The hash reference to append template variables to + +=head3 inbox + + The instance of the inbox currently being worked with. + +=cut + +sub appendCommonVars { + my $self = shift; + my $var = shift; + my $inbox = shift; + my $session = $self->session; + my $user = $session->user; + + $var->{'user_full_name' } = $user->getWholeName; + $var->{'user_member_since' } = $user->dateCreated; + $var->{'view_profile_url' } = $user->getProfileUrl; + $var->{'view_inbox_url' } = $self->getUrl("module=inbox;do=view"); + $var->{'view_invitations_url'} = $self->getUrl("module=inbox;do=manageInvitations"); + $var->{'unread_message_count'} = $inbox->getUnreadMessageCount; + +} + +#------------------------------------------------------------------- + +=head2 canView ( ) + + Returns whether or not the user can view the inbox tab + +=cut + +sub canView { + my $self = shift; + return ($self->session->form->get("uid") eq ""); +} + #------------------------------------------------------------------- =head2 editSettingsForm ( ) @@ -35,20 +81,76 @@ These subroutines are available from this package: =cut -sub editUserSettingsForm { +sub editSettingsForm { my $self = shift; my $session = $self->session; my $setting = $session->setting; my $i18n = WebGUI::International->new($session,'Account_Inbox'); my $f = WebGUI::HTMLForm->new($session); -# $f->template( -# name => "profileStyleTemplateId", -# value => $self->getStyleTemplateId, -# namespace => "style", -# label => $i18n->get("profile style template label"), -# hoverHelp => $i18n->get("profile style template hoverHelp") -# ); + $f->template( + name => "inboxStyleTemplateId", + value => $self->getStyleTemplateId, + namespace => "style", + label => $i18n->get("inbox style template label"), + hoverHelp => $i18n->get("inbox style template hoverHelp") + ); + $f->template( + name => "inboxLayoutTempalteId", + value => $self->getLayoutTemplateId, + namespace => "Account/Layout", + label => $i18n->get("inbox layout template label"), + hoverHelp => $i18n->get("inbox layout template hoverHelp") + ); + $f->template( + name => "inboxViewTemplateId", + value => $self->getViewTemplateId, + namespace => "Account/Inbox/View", + label => $i18n->get("inbox view template label"), + hoverHelp => $i18n->get("inbox view template hoverHelp") + ); + $f->template( + name => "inboxViewMessageTemplateId", + value => $self->getViewMessageTemplateId, + namespace => "Account/Inbox/ViewMessage", + label => $i18n->get("inbox view message template label"), + hoverHelp => $i18n->get("inbox view message template hoverHelp") + ); + $f->template( + name => "inboxSendMessageTemplateId", + value => $self->getSendMessageTemplateId, + namespace => "Account/Inbox/SendMessage", + label => $i18n->get("inbox send message template label"), + hoverHelp => $i18n->get("inbox send message template hoverHelp") + ); + $f->template( + name => "inboxMessageConfirmationTemplateId", + value => $self->getMessageConfirmTemplateId, + namespace => "Account/Inbox/Confirm", + label => $i18n->get("inbox message confirm template label"), + hoverHelp => $i18n->get("inbox message confirm template hoverHelp") + ); + $f->template( + name => "inboxErrorTemplateId", + value => $self->getInboxErrorTemplateId, + namespace => "Account/Inbox/Error", + label => $i18n->get("inbox error message template label"), + hoverHelp => $i18n->get("inbox error message template hoverHelp") + ); + $f->template( + name => "inboxManageInvitationsTemplateId", + value => $self->getManageInvitationsTemplateId, + namespace => "Account/Inbox/ManageInvitations", + label => $i18n->get("inbox manage invitations template label"), + hoverHelp => $i18n->get("inbox manage invitations template hoverHelp") + ); + $f->template( + name => "inboxInvitationErrorTemplateId", + value => $self->getInvitationErrorTemplateId, + namespace => "Account/Inbox/Error", + label => $i18n->get("invitation error message template label"), + hoverHelp => $i18n->get("invitation error message template hoverHelp") + ); return $f->printRowsOnly; } @@ -61,7 +163,50 @@ sub editUserSettingsForm { =cut -sub editUserSettingsFormSave { +sub editSettingsFormSave { + my $self = shift; + my $session = $self->session; + my $setting = $session->setting; + my $form = $session->form; + + #Messages Settings + $setting->set("inboxStyleTemplateId", $form->process("inboxStyleTemplateId","template")); + $setting->set("inboxLayoutTempalteId", $form->process("inboxLayoutTempalteId","template")); + $setting->set("inboxViewTemplateId", $form->process("inboxViewTemplateId","template")); + $session->set("inboxViewMessageTemplateId",$form->process("inboxViewMessageTemplateId","template")); + $session->set("inboxSendMessageTemplateId",$form->process("inboxSendMessageTemplateId","template")); + $session->set("inboxMessageConfirmationTemplateId",$form->process("inboxMessageConfirmationTemplateId","template")); + $session->set("inboxErrorTemplateId",$form->process("inboxErrorTemplateId","template")); + #Invitations Settings + $session->set("inboxManageInvitationsTemplateId",$form->process("inboxManageInvitationsTemplateId","template")); + $session->set("inboxInvitationErrorTemplateId",$form->process("inboxInvitationErrorTemplateId","template")); +} + +#------------------------------------------------------------------- + +=head2 getInboxErrorTemplateId ( ) + +This method returns the template ID for inbox errors. + +=cut + +sub getInboxErrorTemplateId { + my $self = shift; + return $self->session->setting->get("inboxErrorTemplateId") || "ErEzulFiEKDkaCDVmxUavw"; +} + + +#------------------------------------------------------------------- + +=head2 getInvitationErrorTemplateId ( ) + +This method returns the template ID for invitation errors. + +=cut + +sub getInvitationErrorTemplateId { + my $self = shift; + return $self->session->setting->get("inboxInvitationErrorTemplateId") || "5A8Hd9zXvByTDy4x-H28qw"; } #------------------------------------------------------------------- @@ -77,6 +222,45 @@ sub getLayoutTemplateId { return $self->session->setting->get("inboxLayoutTempalteId") || $self->SUPER::getLayoutTemplateId; } +#------------------------------------------------------------------- + +=head2 getManageInvitationsTemplateId ( ) + +This method returns the template ID for the invitations manage screen. + +=cut + +sub getManageInvitationsTemplateId { + my $self = shift; + return $self->session->setting->get("inboxManageInvitationsTemplateId") || "1Q4Je3hKCJzeo0ZBB5YB8g"; +} + +#------------------------------------------------------------------- + +=head2 getMessageConfirmTemplateId ( ) + +This method returns the template ID for message confirmations. + +=cut + +sub getMessageConfirmTemplateId { + my $self = shift; + return $self->session->setting->get("inboxMessageConfirmationTemplateId") || "DUoxlTBXhVS-Zl3CFDpt9g"; +} + + +#------------------------------------------------------------------- + +=head2 getSendMessageTemplateId ( ) + +This method returns the template ID for the send message view. + +=cut + +sub getSendMessageTemplateId { + my $self = shift; + return $self->session->setting->get("inboxSendMessageTemplateId") || "6uQEULvXFgCYlRWnYzZsuA"; +} #------------------------------------------------------------------- @@ -93,6 +277,39 @@ sub getStyleTemplateId { #------------------------------------------------------------------- +=head2 getUserProfileUrl ( userId ) + +This method stores a reference of user profile URLs to prevent us from having to instantiate +the same users over and over as the nature of an inbox is to have multiple messages from the same user. + +=cut + +sub getUserProfileUrl { + my $self = shift; + my $userId = shift; + + + unless ($self->store->{$userId}) { + $self->store->{$userId} = WebGUI::User->new($self->session,$userId)->getProfileUrl; + } + return $self->store->{$userId}; +} + +#------------------------------------------------------------------- + +=head2 getViewMessageTemplateId ( ) + +This method returns the id for the view message template. + +=cut + +sub getViewMessageTemplateId { + my $self = shift; + return $self->session->setting->get("inboxViewMessageTemplateId") || "0n4HtbXaWa_XJHkFjetnLQs"; +} + +#------------------------------------------------------------------- + =head2 getViewTemplateId ( ) This method returns the template ID for the main view. @@ -101,9 +318,356 @@ This method returns the template ID for the main view. sub getViewTemplateId { my $self = shift; - return $self->session->setting->get("inboxViewTemplateId") || "defaultAssetId"; + return $self->session->setting->get("inboxViewTemplateId") || "c8xrwVuu5QE0XtF9DiVzLw"; } +#------------------------------------------------------------------- + +=head2 www_deleteMessage ( ) + +Deletes a single messages passed in + +=cut + +sub www_deleteMessage { + my $self = shift; + my $session = $self->session; + + my $messageId = $session->form->get("messageId"); + my $inbox = WebGUI::Inbox->new($session); + my $message = $inbox->getMessage($messageId); + + if (!(defined $message) || !$inbox->canRead($message)) { + #View will handle displaying these errors + return $self->www_viewMessage; + } + + #Get the next message to display + my $displayMessage = $inbox->getNextMessage($message); + unless (defined $displayMessage) { + #No more messages - try to get the previous message + $displayMessage = $inbox->getPreviousMessage($message); + unless (defined $displayMessage) { + #This is the last message in the inbox - delete it and return to inbox + $message->delete; + return $self->www_view(); + } + } + $message->delete; + + return $self->www_viewMessage($displayMessage->getId); +} + +#------------------------------------------------------------------- + +=head2 www_deleteMessages ( ) + +Deletes a list of messages selected for the current user + +=cut + +sub www_deleteMessages { + my $self = shift; + my $session = $self->session; + + my @messages = $session->form->process("message","checkList"); + + foreach my $messageId (@messages) { + my $message = WebGUI::Inbox::Message->new($session, $messageId); + $message->delete; + } + + return $self->www_view(); +} + +#------------------------------------------------------------------- + +=head2 www_manageInvitations ( ) + +The page on which users can manage their friends requests + +=cut + +sub www_manageInvitations { + my $self = shift; + my $session = $self->session; + my $user = $session->user; + + my $var = {}; + + #Add common template variable for displaying the inbox + my $inbox = WebGUI::Inbox->new($session); + $self->appendCommonVars($var,$inbox); + + return $self->processTemplate($var,$self->getManageInvitationsTemplateId); +} + +#------------------------------------------------------------------- + +=head2 www_sendMessage ( ) + +The page on which users send or reply to messages + +=cut + +sub www_sendMessage { + my $self = shift; + my $session = $self->session; + my $form = $session->form; + my $fromUser = $session->user; + my $displayError = shift; + my $toUser = undef; + my $var = {}; + + #Add any error passed in to be displayed if the form reloads + $var->{'message_display_error'} = $displayError; + + #Add common template variable for displaying the inbox + my $inbox = WebGUI::Inbox->new($session); + $self->appendCommonVars($var,$inbox); + + my $messageId = $form->get("messageId"); + my $userId = $form->get("userId"); + my $pageUrl = $session->url->page; + my $backUrl = $session->env->get("HTTP_REFERER") || $var->{'view_inbox_url'}; + my $errorMsg = ""; + + if($messageId) { + #This is a reply to a message - automate who the user is + my $message = $inbox->getMessage($messageId); + + #Handle Errors + if (!(defined $message)) { + #Message doesn't exist + my $i18n = WebGUI::International->new($session,'Account_Inbox'); + $errorMsg = $i18n->get("message does not exist"); + } + elsif (!$inbox->canRead($message)) { + #User trying to reply to message that they have not been sent. + my $i18n = WebGUI::International->new($session,'Account_Inbox'); + $errorMsg = $i18n->get("no reply error"); + } + elsif($message->get("status") eq "completed" || $message->get("status") eq "pending") { + #User trying to reply to system message + my $i18n = WebGUI::International->new($session,'Account_Inbox'); + $errorMsg = $i18n->get("system message error"); + } + if($errorMsg) { + return $self->showError($var,$errorMsg,$backUrl,$self->getInboxErrorTemplateId); + } + + #Otherwise you should be able to reply to anyone who sent you a message + $toUser = WebGUI::User->new($session,$message->get("sentBy")); + $var->{'isReply' } = "true"; + $var->{'message_to' } = $toUser->getWholeName; + $var->{'message_subject'} = $message->get("subject"); + } + elsif($userId) { + #This is a private message to a user - check user private message settings + + #Handle Errors + $toUser = WebGUI::User->new($session,$userId); + if($toUser->isVisitor || !$toUser->acceptsPrivateMessages($fromUser->userId)) { + #Trying to send messages to the visitor or a user that doesn't exist + my $i18n = WebGUI::International->new($session,'Account_Inbox'); + $errorMsg = $i18n->get("blocked error"); + } + elsif($toUser->userId eq $fromUser->userId) { + #Trying to send a message to yourself + my $i18n = WebGUI::International->new($session,'Account_Inbox'); + $errorMsg = $i18n->get("no self error"); + } + if($errorMsg) { + return $self->showError($var,$errorMsg,$backUrl,$self->getInboxErrorTemplateId); + } + + $var->{'isPrivateMessage'} = "true"; + $var->{'message_to' } = $toUser->getWholeName; + } + else { + #This is a new message + $var->{'isNew' } = "true"; + + my $friends = $fromUser->friends->getUserList; + my @checkedFriends = (); + my @friendsChecked = $form->process("friend","checkList"); + my $activeFriendCount = 0; + #Append this users friends to the template + my @friendsLoop = (); + foreach my $friendId (keys %{$friends}) { + my $friend = WebGUI::User->new($session,$friendId); + #This friend has private messages turned off + my $disabled = "disabled"; + if($friend->acceptsPrivateMessages($fromUser->userId)) { + $disabled = ""; + $activeFriendCount++; + } + my $fname = $friend->profileField("firstName"); + my $lname = $friend->profileField("lastName"); + my $wholeName = ""; + $wholeName = $fname." ".$lname if($fname && $lname); + + my $isChecked = WebGUI::Utility::isIn($friendId,@friendsChecked); + my $friendHash = { + 'friend_id' => $friendId, + 'friend_name' => $friends->{$friendId}, + 'friend_wholeName' => $wholeName, + }; + + push(@checkedFriends,$friendHash) if($isChecked); + + $friendHash->{'friend_checkbox'} = WebGUI::Form::checkbox($session,{ + name => "friend", + value => $friendId, + checked => $isChecked, + extras => q{id="friend_}.$friendId.qq{_id" $disabled}, + }); + + push (@friendsLoop, $friendHash); + } + + #You can't send new messages if you don't have any friends to send to + unless($activeFriendCount) { + my $i18n = WebGUI::International->new($session,'Account_Inbox'); + $errorMsg = $i18n->get("no friends error"); + return $self->showError($var,$errorMsg,$backUrl,$self->getInboxErrorTemplateId); + } + + $var->{'friends_loop' } = \@friendsLoop; + $var->{'checked_fiends_loop'} = \@checkedFriends; + } + + $var->{'message_from' } = $fromUser->getWholeName; + + my $subject = $form->get("subject"); + if($subject eq "" && $messageId) { + $subject = "Re: ".$var->{'message_subject'}; + } + + $var->{'form_subject' } = WebGUI::Form::text($session, { + name => "subject", + value => $subject, + extras => q{ class="inbox_subject" } + }); + + $var->{'message_body' } = $form->get('message'); + + $var->{'form_message_text'} = WebGUI::Form::textarea($session, { + name =>"message", + value =>$var->{'message_body'} || "", + }); + + $var->{'form_message_rich'} = WebGUI::Form::HTMLArea($session, { + name => "message", + value => $var->{'message_body'} || "", + width => "600", + }); + + $var->{'form_header' } = WebGUI::Form::formHeader($session,{ + action => $self->getUrl("module=inbox;do=sendMessageSave;messageId=$messageId;userId=$userId"), + extras => q{name="messageForm"} + }); + + $var->{'submit_button' } = WebGUI::Form::submit($session,{}); + $var->{'form_footer' } = WebGUI::Form::formFooter($session, {}); + $var->{'back_url' } = $backUrl; + + return $self->processTemplate($var,$self->getSendMessageTemplateId); +} + +#------------------------------------------------------------------- + +=head2 www_sendMessageSave ( ) + +Sends the message created by the user + +=cut + +sub www_sendMessageSave { + my $self = shift; + my $session = $self->session; + my $form = $session->form; + my $fromUser = $session->user; + my $var = {}; + my $errorMsg = ""; + my @toUsers = (); + + #Add common template variable for displaying the inbox + my $inbox = WebGUI::Inbox->new($session); + + my $messageId = $form->get("messageId"); + my $userId = $form->get("userId"); + my @friends = $form->get("friend","checkList"); + push (@friends, $userId) if ($userId); + + my $hasError = 0; + + my $subject = $form->get("subject"); + my $message = $form->get("message"); + + #Check for hacker errors / set who the message is going to + if($messageId) { + #This is a reply to a message - automate who the user is + my $message = $inbox->getMessage($messageId); + #Handle Errors + if (!(defined $message) + || !$inbox->canRead($message) + || $message->get("status") eq "completed" + || $message->get("status") eq "pending") { + $hasError = 1; + } + push(@toUsers,$message->get("sentBy")); + $message->setStatus("replied"); + } + elsif(scalar(@friends)) { + #This is a private message to a user - check user private message settings + foreach my $userId (@friends) { + my $toUser = WebGUI::User->new($session,$userId); + if($toUser->isVisitor + || !$toUser->acceptsPrivateMessages($fromUser->userId) + || $toUser->userId eq $fromUser->userId) { + $hasError = 1; + } + push(@toUsers,$userId); + } + } + + #Check for client errors + if($subject eq "") { + my $i18n = WebGUI::International->new($session,'Account_Inbox'); + $errorMsg = $i18n->get("no subject error"); + $hasError = 1; + } + elsif($message eq "") { + my $i18n = WebGUI::International->new($session,'Account_Inbox'); + $errorMsg = $i18n->get("no message error"); + $hasError = 1; + } + elsif(scalar(@toUsers) == 0) { + my $i18n = WebGUI::International->new($session,'Account_Inbox'); + $errorMsg = $i18n->get("no user error"); + $hasError = 1; + } + + #Let sendMessage deal with displaying errors + return $self->www_sendMessage($errorMsg) if $hasError; + + foreach my $uid (@toUsers) { + $inbox->addMessage({ + message => $message, + subject => $subject, + userId => $uid, + status => 'unread', + sentBy => $fromUser->userId + }); + } + + $self->appendCommonVars($var,$inbox); + + return $self->processTemplate($var,$self->getMessageConfirmTemplateId); +} + + #------------------------------------------------------------------- =head2 www_view ( ) @@ -115,10 +679,189 @@ The main view page for editing the user's profile. sub www_view { my $self = shift; my $session = $self->session; + my $user = $session->user; my $var = {}; + + #Deal with sort order + my $sortBy = $session->form->get("sortBy") || undef; + my $sort_url = ($sortBy)?";sortBy=$sortBy":""; + + #Deal with sort direction + my $sortDir = $session->form->get("sortDir") || "desc"; + my $sortDir_url = ";sortDir=".(($sortDir eq "desc")?"asc":"desc"); + #Deal with rows per page + my $rpp = $session->form->get("rpp") || 25; + my $rpp_url = ";rpp=$rpp"; + + #Cache the base url + my $inboxUrl = $self->getUrl; + + #Create sortBy headers + $var->{'subject_url' } = $inboxUrl.";sortBy=subject".$sortDir_url.$rpp_url; + $var->{'status_url' } = $inboxUrl.";sortBy=status".$sortDir_url.$rpp_url; + $var->{'from_url' } = $inboxUrl.";sortBy=sentBy".$sortDir_url.$rpp_url; + $var->{'dateStamp_url' } = $inboxUrl.";sortBy=dateStamp".$sortDir_url.$rpp_url; + $var->{'rpp_url' } = $inboxUrl.$sort_url.";sortDir=".$sortDir; + + #Create the paginator + my $inbox = WebGUI::Inbox->new($session); + my $p = $inbox->getMessagesPaginator($session->user,{ + sortBy => $sortBy, + sortDir => $sortDir, + baseUrl => $inboxUrl.$sort_url.";sortDir=".$sortDir.$rpp_url, + paginateAfter => $rpp + }); + + #Export page to template + my @msg = (); + foreach my $row ( @{$p->getPageData} ) { + my $message = $inbox->getMessage( $row->{messageId} ); + #next if($message->get('status') eq 'deleted'); + + my $hash = {}; + $hash->{'message_id' } = $message->getId; + $hash->{'message_url' } = $self->getUrl("module=inbox;do=viewMessage;messageId=".$message->getId); + $hash->{'subject' } = $message->get("subject"); + $hash->{'status_class' } = $message->get("status"); + $hash->{'status' } = $message->getStatus; + $hash->{'isRead' } = $message->isRead; + $hash->{'isReplied' } = $hash->{'status_class'} eq "replied"; + $hash->{'isPending' } = $hash->{'status_class'} eq "pending"; + $hash->{'isCompleted' } = $hash->{'status_class'} eq "completed"; + $hash->{'from_id' } = $message->get("sentBy"); + $hash->{'from_url' } = $self->getUserProfileUrl($hash->{'from_id'}); #Get the profile url of this user which may be cached. + $hash->{'from' } = $row->{'fullName'}; + $hash->{'dateStamp' } = $message->get("dateStamp"); + $hash->{'dateStamp_formatted'} = $session->datetime->epochToHuman($hash->{'dateStamp'}); + $hash->{'inbox_form_delete' } = WebGUI::Form::checkbox($session,{ + name => "message", + value => $message->getId + }); + push(@msg,$hash); + } + my $msgCount = $p->getRowCount; + + $var->{'message_loop' } = \@msg; + $var->{'has_messages' } = $msgCount > 0; + $var->{'message_total' } = $msgCount; + $var->{'new_message_url' } = $self->getUrl("module=inbox;do=sendMessage"); + $var->{'canSendMessages' } = $user->hasFriends; + + $var->{'inbox_form_start' } = WebGUI::Form::formHeader($session,{ + action => $self->getUrl("module=inbox;do=deleteMessages") + }); + $var->{'inbox_form_end' } = WebGUI::Form::formFooter($session); + + tie my %rpps, "Tie::IxHash"; + %rpps = (25 => "25", 50 => "50", 100=>"100"); + $var->{'message_rpp' } = WebGUI::Form::selectBox($session,{ + name =>"rpp", + options => \%rpps, + value => $session->form->get("rpp") || 25, + extras => q{onchange="location.href='}.$var->{'rpp_url'}.q{;rpp='+this.options[this.selectedIndex].value"} + }); + + #Append common vars + $self->appendCommonVars($var,$inbox); + #Append pagination vars + $p->appendTemplateVars($var); return $self->processTemplate($var,$self->getViewTemplateId); } +#------------------------------------------------------------------- + +=head2 www_viewMessage ( ) + +The page on which users view their messages + +=cut + +sub www_viewMessage { + my $self = shift; + my $session = $self->session; + my $user = $session->user; + + my $var = {}; + my $messageId = shift || $session->form->get("messageId"); + my $errorMsg = shift; + + my $inbox = WebGUI::Inbox->new($session); + my $message = $inbox->getMessage($messageId); + + #Add common template variable for displaying the inbox + $self->appendCommonVars($var,$inbox); + + #Handler Errors + if (!(defined $message)) { + my $i18n = WebGUI::International->new($session,'Account_Inbox'); + $errorMsg = $i18n->get("message does not exist"); + } + elsif (!$inbox->canRead($message)) { + my $i18n = WebGUI::International->new($session,'Account_Inbox'); + $errorMsg = $i18n->get("no access"); + } + + if($errorMsg) { + my $backUrl = $var->{'view_inbox_url'}; + return $self->showError($var,$errorMsg,$backUrl,$self->getInboxErrorTemplateId); + } + + $message->setStatus("read") unless ($message->isRead); + + $var->{'message_id' } = $messageId; + $var->{'message_subject' } = $message->get("subject"); + $var->{'message_dateStamp' } = $message->get("dateStamp"); + $var->{'message_dateStemp_human'} = $session->datetime->epochToHuman($var->{'message_dateStamp'}); + $var->{'message_status' } = $message->getStatus; + $var->{'message_body' } = $message->get("message"); + + unless ($var->{'message_body'} =~ /\{'message_body'} =~ s/(http\S*)/\$1\<\/a\>/g; + } + unless ($var->{'message_body'} =~ /\
{'message_body'} =~ /\
{'message_body'} =~ /\

{'message_body'} =~ s/\n/\
\n/g; + } + + #Get the user the message was sent by + my $sentBy = $message->get("sentBy"); + my $from = WebGUI::User->new($session,$sentBy); + my $sentByVisitor = 0; + if ($from->isVisitor) { + $sentByVisitor = 1; + $from = WebGUI::User->new($session,3); + } + $var->{'message_from_id' } = $from->userId; + $var->{'message_from' } = $from->getWholeName; + + #Build the action URLs + $var->{'delete_url' } = $self->getUrl("module=inbox;do=deleteMessage;messageId=".$messageId); + + my $status = $message->get("status"); + if($sentBy ne $user->userId + && !$sentByVisitor + && $status ne "pending" + && $status ne "completed" ) { + $var->{'canReply' } = "true"; + $var->{'reply_url'} = $self->getUrl("module=inbox;do=sendMessage;messageId=".$messageId); + } + + my $nextMessage = $inbox->getNextMessage($message); + if( defined $nextMessage ) { + $var->{'hasNext' } = "true"; + $var->{'next_message_url'} = $self->getUrl("module=inbox;do=viewMessage;messageId=".$nextMessage->getId); + } + + my $prevMessage = $inbox->getPreviousMessage($message); + if(defined $prevMessage) { + $var->{'hasPrevious' } = "true"; + $var->{'prev_message_url'} = $self->getUrl("module=inbox;do=viewMessage;messageId=".$prevMessage->getId); + } + + return $self->processTemplate($var,$self->getViewMessageTemplateId); +} + 1; diff --git a/lib/WebGUI/Account/Profile.pm b/lib/WebGUI/Account/Profile.pm index 410167616..6adbe4854 100644 --- a/lib/WebGUI/Account/Profile.pm +++ b/lib/WebGUI/Account/Profile.pm @@ -5,6 +5,8 @@ use strict; use WebGUI::Exception; use WebGUI::International; use WebGUI::Pluggable; +use WebGUI::ProfileCategory; +use WebGUI::ProfileField; use WebGUI::Utility; use base qw/WebGUI::Account/; @@ -26,6 +28,31 @@ These subroutines are available from this package: =cut +#------------------------------------------------------------------- + +=head2 appendCommonVars ( var ) + + Appends common template variables that all inbox templates 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 = $session->user; + my $pageUrl = $session->url->page; + + $var->{'user_full_name' } = $user->getWholeName; + $var->{'user_member_since' } = $user->dateCreated; + $var->{'view_profile_url' } = $user->getProfileUrl($pageUrl); + $var->{'edit_profile_url' } = $self->getUrl("module=profile;do=edit"); + $var->{'back_url' } = $session->env->get("HTTP_REFERER") || $var->{'view_profile_url'} +} #------------------------------------------------------------------- @@ -35,7 +62,7 @@ These subroutines are available from this package: =cut -sub editUserSettingsForm { +sub editSettingsForm { my $self = shift; my $session = $self->session; my $setting = $session->setting; @@ -50,41 +77,121 @@ sub editUserSettingsForm { hoverHelp => $i18n->get("profile style template hoverHelp") ); $f->template( - name => "profileLayoutTempalteId", + name => "profileLayoutTemplateId", value => $self->getLayoutTemplateId, namespace => "Account/Layout", label => $i18n->get("profile layout template label"), hoverHelp => $i18n->get("profile layout template hoverHelp") ); + $f->template( + name => "profileEditLayoutTemplateId", + value => $self->getEditLayoutTemplateId, + namespace => "Account/Layout", + label => $i18n->get("profile edit layout template label"), + hoverHelp => $i18n->get("profile edit layout template hoverHelp") + ); $f->template( + name => "profileEditTemplateId", + value => $self->getEditTemplateId, + namespace => "Account/Profile/Edit", + label => $i18n->get("profile edit template label"), + hoverHelp => $i18n->get("profile edit template hoverHelp") + ); + $f->template( name => "profileViewTemplateId", value => $self->getViewTemplateId, namespace => "Account/Profile/View", label => $i18n->get("profile view template label"), hoverHelp => $i18n->get("profile view template hoverHelp") ); - $f->template( - name => "profileEditTemplateId", - value => $setting->get("profileEditTemplateId"), - namespace => "Account/Profile/Edit", - label => $i18n->get("profile edit template label"), - hoverHelp => $i18n->get("profile edit template hoverHelp") - ); return $f->printRowsOnly; } + #------------------------------------------------------------------- -=head2 getDisplayTemplateId ( ) +=head2 editSettingsFormSave ( ) + + Creates form elements for user settings page custom to this account module + +=cut + +sub editSettingsFormSave { + my $self = shift; + my $session = $self->session; + my $setting = $session->setting; + my $form = $session->form; + + $setting->set("profileStyleTemplateId", $form->process("profileStyleTemplateId","template")); + $setting->set("profileLayoutTemplateId", $form->process("profileLayoutTemplateId","template")); + $setting->set("profileDisplayLayoutTemplateId", $form->process("profileDisplayLayoutTemplateId","template")); + $setting->set("profileEditTemplateId", $form->process("profileEditTemplateId","template")); + $setting->set("profileViewTempalteId", $form->process("profileViewTemplateId","template")); + +} + +#------------------------------------------------------------------- + +=head2 getExtrasStyle ( field, fieldErrors, fieldValue ) + +This method returns the proper field to display for required fields. + +=head3 field + +field to check + +=head3 fieldErrors + +errors returned as a result of validation (see $self->validateProfileFields) + +=head3 fieldValue + +Value of the field to use when returning the style + +=cut + +sub getExtrasStyle { + my $self = shift; + my $field = shift; + my $fieldErrors = shift; + my $fieldValue = shift; + + my $requiredStyleOff = q{class="profilefield_required_off"}; + my $requiredStyle = q{class="profilefield_required"}; + my $errorStyle = q{class="profilefield_error"}; #Required Field Not Filled In and Error Returend + + return $errorStyle if(WebGUI::Utility::isIn($field->getId,@{$fieldErrors})); + return "" unless ($field->isRequired); + return $requiredStyle unless($self->session->user->profileField($field->getId) || $fieldValue); + return $requiredStyleOff; +} + + +#------------------------------------------------------------------- + +=head2 getDisplayLayoutTemplateId ( ) This method returns the template ID for the account layout. =cut -sub getDisplayTemplateId { +sub getEditLayoutTemplateId { + my $self = shift; + return $self->session->setting->get("profileEditLayoutTemplateId") || "FJbUTvZ2nUTn65LpW6gjsA"; +} + +#------------------------------------------------------------------- + +=head2 getEditTemplateId ( ) + +This method returns the template ID for the edit profile page. + +=cut + +sub getEditTemplateId { my $self = shift; - return $self->session->setting->get("profileDisplayTempalteId") || "defaultAssetId"; + return $self->session->setting->get("profileEditTemplateId") || "75CmQgpcCSkdsL-oawdn3Q"; } #------------------------------------------------------------------- @@ -96,8 +203,13 @@ This method returns the template ID for the account layout. =cut sub getLayoutTemplateId { - my $self = shift; - return $self->session->setting->get("profileLayoutTempalteId") || $self->SUPER::getLayoutTemplateId; + my $self = shift; + my $session = $self->session; + my $method = $session->form->get("do"); + my $uid = $session->form->get("uid"); + + return $self->getEditLayoutTemplateId if($method eq "edit" || $uid eq ""); + return $session->setting->get("profileLayoutTemplateId") || $self->SUPER::getLayoutTemplateId; } #------------------------------------------------------------------- @@ -117,30 +229,342 @@ sub getStyleTemplateId { =head2 getViewTemplateId ( ) -This method returns the template ID for the main view. +This method returns the template ID for the view profile page. =cut sub getViewTemplateId { my $self = shift; - return $self->session->setting->get("profileViewTemplateId") || "75CmQgpcCSkdsL-oawdn3Q"; + return $self->session->setting->get("profileViewTemplateId") || "2CS-BErrjMmESOtGT90qOg"; +} + +#------------------------------------------------------------------- + +=head2 saveProfileFields ( session, user, profile ) + +Saves profile data to a user's profile. Does not validate any of the data. + +=head3 session + +WebGUI session object + +=head3 user + +User object. Profile data will be placed in this user's profile. + +=head3 profile + +Hash ref of profile data to save. + +=cut + +sub saveProfileFields { + my $class = shift; + my $session = shift; + my $u = shift; + my $profile = shift; + + foreach my $fieldName (keys %{$profile}) { + $u->profileField($fieldName,${$profile}{$fieldName}); + } +} + +#------------------------------------------------------------------- + +=head2 validateProfileFields ( session, fields ) + +Class method which validates profile data from the session form variables. Returns an data structure which contains the following + +{ + profile => Hash reference containing all of the profile fields and their values + errors => Array reference of error messages to be displayed + errorCategory => Category in which the first error was thrown + warnings => Array reference of warnings to be displayed + errorFields => Array reference of the fieldIds that threw an error + warningFields => Array reference of the fieldIds that threw a warning +} + +=head3 session + +WebGUI session object + +=head3 fields + +An array reference of profile fields to validate. + +=cut + +sub validateProfileFields { + my $class = shift; + my $session = shift; + my $fields = shift; + + my $i18n = WebGUI::International->new($session, 'Account_Profile'); + + my $data = {}; + my $errors = []; + my $warnings = []; + my $errorCat = undef; + my $errorFields = []; + my $warnFields = []; + + foreach my $field (@{$fields}) { + my $fieldId = $field->getId; + my $fieldLabel = $field->getLabel; + my $fieldValue = $field->formProcess; + my $isValid = $field->isValid($fieldValue); + + $data->{$fieldId} = (ref $fieldValue eq "ARRAY") ? $fieldValue->[0] : $fieldValue; + + if(!$isValid) { + $errorCat = $field->get("profileCategoryId") unless (defined $errorCat); + push (@{$errors}, sprintf($i18n->get("required error"),$fieldLabel)); + push(@{$errorFields},$fieldId); + } + #The language field is special and must be always be valid or WebGUI will croak + elsif($fieldId eq "language" && !(exists $i18n->getLanguages()->{$data->{$fieldId}})) { + $errorCat = $field->get("profileCategoryId") unless (defined $errorCat); + $session->log->warn("language $fieldValue does not exist"); + push (@{$errors}, sprintf($i18n->get("language not installed error"),$data->{$fieldId})); + push(@{$errorFields},$fieldId); + } + #Duplicate emails throw warnings + elsif($fieldId eq "email" && $field->isDuplicate($fieldValue)) { + $errorCat = $field->get("profileCategoryId") unless (defined $errorCat); + push (@{$warnings},$i18n->get("email already in use error")); + push(@{$warnFields},$fieldId); + } + } + + return { + profile => $data, + errors => $errors, + warnings => $warnings, + errorCategory => $errorCat, + errorFields => $errorFields, + warningFields => $warnFields, + }; +} + +#------------------------------------------------------------------- + +=head2 www_edit ( ) + +The edit page for the user's profile. + +=cut + +sub www_edit { + my $self = shift; + my $errors = shift || {}; + my $session = $self->session; + my $user = $session->user; + my $selected = $errors->{errorCategory} || $session->form->get("selected"); #Allow users to template tabs or other category dividers + my $var = {}; + + my $active = 0; #Whether or not a category is selected + my $counter = 1; #Count the number of categories being displayed + my $hasErrors = scalar(keys %{$errors}); + + my @errorFields = (); + @errorFields = (@{$errors->{errorFields}},@{$errors->{warningFields}}) if($hasErrors); + + my @categories = (); + foreach my $category (@{WebGUI::ProfileCategory->getCategories($session)}) { + next unless $category->isEditable; + my @fields = (); + foreach my $field (@{$category->getFields}) { + next unless ($field->isEditable); + next if $field->getId =~ m/contentPositions/; #This protects the contentPosition fields + my $fieldId = $field->getId; + my $fieldLabel = $field->getLabel; + my $fieldForm = $field->formField({ extras=>$self->getExtrasStyle($field,\@errorFields,$user->profileField($fieldId)) }); + my $fieldSubtext = $field->isRequired ? "*" : undef; + my $fieldExtras = $field->getExtras; + #Create a seperate template var for each field + $var->{'profile_field_'.$fieldId.'_form' } = $fieldForm; + $var->{'profile_field_'.$fieldId.'_label' } = $fieldLabel; + $var->{'profile_field_'.$fieldId.'_subtext'} = $fieldSubtext; + $var->{'profile_field_'.$fieldId.'_extras' } = $fieldExtras; + + push(@fields, { + 'profile_field_id' => $fieldId, + 'profile_field_form' => $fieldForm, + 'profile_field_label' => $fieldLabel, + 'profile_field_subtext' => $field->isRequired ? "*" : undef, + 'profile_field_extras' => $field->getExtras, + }); + } + my $categoryId = $category->getId; + my $categoryLabel = $category->getLabel; + my $shortCategoryLabel = $category->getShortLabel; + my $isActive = $categoryId eq $selected; + my $categoryIndex = $counter++; + + $var->{'profile_category_'.$categoryId."_isActive" } = $isActive; + $var->{'profile_category_'.$categoryId."_label" } = $categoryLabel; + $var->{'profile_category_'.$categoryId."_shortLabel"} = $shortCategoryLabel; + $var->{'profile_category_'.$categoryId."_fields" } = \@fields; + $var->{'profile_category_'.$categoryId."_index" } = $categoryIndex; + + push(@categories, { + 'profile_category_id' => $categoryId, + 'profile_category_isActive' => $isActive, + 'profile_category_is_'.$categoryId => "true", #Test so users can tell what category they are at in the loop + 'profile_category_label' => $categoryLabel, + 'profile_category_shortLabel' => $shortCategoryLabel, + 'profile_category_index' => $categoryIndex, + 'profile_fields_loop' => \@fields, + }); + #This value will determine whether or not a valid category is active or not + $active ||= $isActive; + } + + #If not category is selected, set the first category as the active one + $categories[0]->{profile_category_isActive} = 1 unless($active); + + $var->{'profile_category_loop'} = \@categories; + + $var->{'profile_form_submit' } = WebGUI::Form::submit($session,{}); + $var->{'profile_form_header' } = WebGUI::Form::formHeader($session,{ + action => $self->getUrl("module=profile;do=editSave") + }); + $var->{'profile_form_footer' } = WebGUI::Form::formFooter($session); + + $var->{'profile_errors' } = []; + map{ push(@{$var->{'profile_errors'}},{ error_message => $_ }) } @{$errors->{errors}} if($hasErrors); + + $self->appendCommonVars($var); + + return $self->processTemplate($var,$self->getEditTemplateId); +} + + +#------------------------------------------------------------------- + +=head2 www_editSave ( ) + +The page which saves the user's profile and returns them to their profile view. + +=cut + +sub www_editSave { + my $self = shift; + my $session = $self->session; + + my $fields = WebGUI::ProfileField->getEditableFields($session); + my $retHash = $self->validateProfileFields($session,$fields); + push (@{$retHash->{errors}},@{$retHash->{warnings}}); + + unless(scalar(@{$retHash->{errors}})) { + foreach my $fieldName (keys %{$retHash->{profile}}) { + $session->user->profileField($fieldName,$retHash->{profile}->{$fieldName}); + } + } + + return $self->www_edit($retHash); } #------------------------------------------------------------------- =head2 www_view ( ) -The main view page for the user's profile. +The display page of the . =cut sub www_view { - my $self = shift; - my $session = $self->session; - my $var = {}; + my $self = shift; + my $session = $self->session; + my $i18n = WebGUI::International->new($session, 'Account_Profile'); + my $var = {}; + my $uid = $session->form->get("uid"); + my $selected = $session->form->get("selected"); #Allow users to template tabs or other category dividers - return $self->processTemplate($var,$session->setting->get("profileViewTemplateId")); + my $active = 0; #Whether or not a category is selected + my $counter = 1; #Count the number of categories being displayed + + #Ensure uid is passed in if they want to view a profile. This controls the tab state. + return $self->www_edit unless ($uid); + + my $user = WebGUI::User->new($session,$uid); + + #Check user privileges + #return $session->style->userStyle($vars->{displayTitle}.'. '.$i18n->get(862)) if($u->profileField("publicProfile") < 1 && ($session->user->userId ne $session->form->process("uid") || $session->user->isAdmin)); + #return $session->privilege->insufficient() if(!$session->user->isRegistered); + + if($user->isVisitor) { + $var->{'restricted' } = "true"; + $var->{'error_message'} = $i18n->get("visitor profile restricted"); + } + + my @categories = (); + foreach my $category (@{WebGUI::ProfileCategory->getCategories($session)}) { + next unless $category->isViewable; + my @fields = (); + foreach my $field (@{$category->getFields}) { + next unless ($field->isViewable); + next if $field->getId =~ m/contentPositions/; #This protects the contentPosition fields + my $fieldId = $field->getId; + my $fieldLabel = $field->getLabel; + my $fieldValue = $field->formField(undef,2,$user); + my $fieldRaw = $user->profileField($fieldId);; + #Create a seperate template var for each field + $var->{'profile_field_'.$fieldId.'_label' } = $fieldLabel; + $var->{'profile_field_'.$fieldId.'_value' } = $fieldValue; + $var->{'profile_field_'.$fieldId.'_raw' } = $fieldRaw; + + push(@fields, { + 'profile_field_id' => $fieldId, + 'profile_field_is_'.$fieldId => "true", + 'profile_field_label' => $fieldLabel, + 'profile_field_value' => $fieldValue, + 'profile_field_raw' => $fieldRaw + }); + } + my $categoryId = $category->getId; + my $categoryLabel = $category->getLabel; + my $shortCategoryLabel = $category->getShortLabel; + my $isActive = $categoryId eq $selected; + my $categoryIndex = $counter++; + + $var->{'profile_category_'.$categoryId."_isActive" } = $isActive; + $var->{'profile_category_'.$categoryId."_label" } = $categoryLabel; + $var->{'profile_category_'.$categoryId."_shortLabel"} = $shortCategoryLabel; + $var->{'profile_category_'.$categoryId."_fields" } = \@fields; + $var->{'profile_category_'.$categoryId."_index" } = $categoryIndex; + + push(@categories, { + 'profile_category_id' => $categoryId, + 'profile_category_isActive' => $isActive, + 'profile_category_is_'.$categoryId => "true", + 'profile_category_label' => $categoryLabel, + 'profile_category_shortLabel' => $shortCategoryLabel, + 'profile_category_index' => $categoryIndex, + 'profile_fields_loop' => \@fields, + }); + #This value will determine whether or not a valid category is active or not + $active ||= $isActive; + } + + #If not category is selected, set the first category as the active one + $categories[0]->{profile_category_isActive} = 1 unless($active); + + $var->{'profile_category_loop' } = \@categories; + $var->{'profile_user_id' } = $user->userId; + $var->{'can_edit_profile' } = $uid eq $session->user->userId; + $var->{'acceptsPrivateMessages'} = $user->acceptsPrivateMessages($session->user->userId); + $var->{'acceptsFriendsRequests'} = $user->acceptsFriendsRequests($session->user); + + $self->appendCommonVars($var); + + #Overwrite these + $var->{'user_full_name' } = $user->getWholeName; + $var->{'user_member_since' } = $user->dateCreated; + + return $self->processTemplate($var,$self->getViewTemplateId); } + 1; diff --git a/lib/WebGUI/Account/User.pm b/lib/WebGUI/Account/User.pm index ffeebc415..46f3b4d42 100644 --- a/lib/WebGUI/Account/User.pm +++ b/lib/WebGUI/Account/User.pm @@ -35,7 +35,7 @@ These subroutines are available from this package: =cut -sub editUserSettingsForm { +sub editSettingsForm { my $self = shift; my $session = $self->session; my $setting = $session->setting; @@ -61,7 +61,7 @@ sub editUserSettingsForm { =cut -sub editUserSettingsFormSave { +sub editSettingsFormSave { } #------------------------------------------------------------------- diff --git a/lib/WebGUI/Content/Account.pm b/lib/WebGUI/Content/Account.pm index c41b9e69a..619687ca7 100644 --- a/lib/WebGUI/Content/Account.pm +++ b/lib/WebGUI/Content/Account.pm @@ -58,6 +58,36 @@ These subroutines are available from this package: #------------------------------------------------------------------- +=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. @@ -67,19 +97,25 @@ The content handler for this package. sub handler { my $session = shift; my $form = $session->form; + my $setting = $session->setting; + + my $op = $form->get("op"); + return undef unless ($op eq "account"); my $output = undef; - my $op = $session->form->get("op"); - my $configs = $session->config->get("account"); + my $module = $form->get("module") || $session->config->get("profileModuleIdentifier"); - if ($configs->{$op}) { + my $configs = $session->config->get("account"); + my $config = __PACKAGE__->getAccountConfig($session,$module,$configs); + + if (defined $config) { + #Visitor cannot do anything to the profile. return $session->privilege->insufficient if($session->user->isVisitor); - #$session->errorHandler->warn("Loading module : ".$configs->{$op}->{className}); #Create Pluggin Object #Don't eval this as pluggable will croak and we want WebGUI::URL::Content to handle the exception - my $pluggin = WebGUI::Pluggable::instanciate($configs->{$op}->{className}, "new", [ $session ] ); + my $pluggin = WebGUI::Pluggable::instanciate($config->{className}, "new", [ $session ] ); #Check to make sure pluggin is a subclass of WebGUI::Account unless($pluggin->isa('WebGUI::Account')) { @@ -91,12 +127,15 @@ sub handler { ); } + #Check to see if the user has permission to see what they are calling + return $session->privilege->insufficient unless ($pluggin->canView); + #Process the method call - my $method = $session->form->get("do") || "view"; + my $method = $form->get("do") || "view"; $method = "www_".$method; - + if($pluggin->can($method)) { - $output = eval { $pluggin->$method($session) }; + $output = $pluggin->$method; } else { WebGUI::Error::MethodNotFound->throw( @@ -108,12 +147,46 @@ sub handler { #Wrap content returned from method call into the layout my $var = {}; $var->{content} = $output; - my $layoutId = $pluggin->getLayoutTemplateId; - $output = $pluggin->processTemplate($var,$layoutId); + # Get fieldsets for avaiable account methods in the order they exist in the config file + my @pluggins = (); + foreach my $account (@{$configs}) { + #Instantiate the pluggin + #Use the currently instantiated pluggin if we are checking this pluggin + my $instance = undef; + if($account->{identifier} eq $module) { + $instance = $pluggin; + } + else { + $instance = eval { WebGUI::Pluggable::instanciate($account->{className}, "new", [ $session ] ) }; + if (my $e = WebGUI::Error->caught) { + $session->log->warn("Couldn't instantiate Account Pluggin ".$account->{className}." ... skipping"); + next; + } + elsif(!$pluggin->isa('WebGUI::Account')) { + $session->log->warn((ref $instance)." is not a subclass of WebGUI::Account ... skipping"); + next; + } + } + #Skip this module if the user can't view this + next unless ($instance->canView); + + #Push the tab variables onto the template + my %hash = %{$account}; + my $identifier = $account->{identifier}; + $hash{'is_'.$identifier} = "true"; + $hash{'url' } = $instance->getUrl("module=$identifier",1); + $hash{'isActive' } = "true" if($identifier eq $module); + WebGUI::Macro::process(\$hash{'title'}); + push(@pluggins,\%hash); + } + $var->{'account_loop'} = \@pluggins; + + my $layoutId = $pluggin->getLayoutTemplateId; + #Process the layout template + $output = $pluggin->processTemplate($var,$layoutId); #Wrap the layout in the user style - $session->http->setCacheControl("none"); - $output = $session->style->process($output,$session->setting->get("userFunctionStyleId")); + $output = $session->style->userStyle($output); } return $output; diff --git a/lib/WebGUI/Form/File.pm b/lib/WebGUI/Form/File.pm index 076c0d3d4..0c1e82542 100644 --- a/lib/WebGUI/Form/File.pm +++ b/lib/WebGUI/Form/File.pm @@ -174,6 +174,11 @@ deleting the file if it was specified. sub getValue { my $self = shift; my $value = $self->get("value"); + my $log = $self->session->log; + $log->warn("file is: ".$self->session->form->get($self->get("name")."_file")); + $log->warn("value is: ".$value); + $log->warn("action is: ".$self->session->form->param($self->privateName('action'))); + my $storage = WebGUI::Storage->get($self->session,$value); if (defined $storage) { foreach my $file (@{$storage->getFiles}) { @@ -195,6 +200,8 @@ sub getValue { } $storage->addFileFromFormPost($self->get("name")."_file",1000); my @files = @{ $storage->getFiles }; + $log->warn("storageId: ".$storage->getId); + $log->warn("number of files: ".scalar(@files)); if (scalar(@files) < 1) { $storage->delete; return undef; @@ -205,6 +212,7 @@ sub getValue { return $id; } } + $log->warn("returning: ".$value); return $value; } diff --git a/lib/WebGUI/Form/Image.pm b/lib/WebGUI/Form/Image.pm index 89d05b184..f1f923e8d 100644 --- a/lib/WebGUI/Form/Image.pm +++ b/lib/WebGUI/Form/Image.pm @@ -181,11 +181,12 @@ Displays the image using an img tag. =cut sub getValueAsHtml { - my ($self) = @_; - my $value = $self->getOriginalValue; + my ($self) = @_; + my $value = $self->getOriginalValue; return '' unless $value; my $location = WebGUI::Storage::Image->get($self->session, $value); my $file = shift @{ $location->getFiles }; + return '' unless $file; my $fileValue = sprintf qq| %s|, $location->getUrl($file), $file; return $fileValue; } diff --git a/lib/WebGUI/Group.pm b/lib/WebGUI/Group.pm index e93f2f7d1..8d65511c2 100755 --- a/lib/WebGUI/Group.pm +++ b/lib/WebGUI/Group.pm @@ -77,10 +77,11 @@ These methods are available from this class: #------------------------------------------------------------------- sub _create { - my $self = shift; - my $override = shift; + my $self = shift; + my $override = shift; + my $noAdmin = shift; $self->{_groupId} = $self->session->db->setRow("groups","groupId", $self->_defaults, $override); - $self->addGroups([3]); + $self->addGroups([3]) unless ($noAdmin); } @@ -850,7 +851,30 @@ u.expires > $time AND ( $scratchClause ) EOQ return $self->session->db->buildArrayRef($query, [ @scratchPlaceholders ]); -} +} + +#------------------------------------------------------------------- + +=head2 getUserList ( [ withoutExpired ] ) + +Returns a hash reference with key of userId and value of username for users in the group + +=head3 withoutExpired + +A boolean that if set to true will return only the groups that the user is in where +their membership hasn't expired. + +=cut + +sub getUserList { + my $self = shift; + my $withoutExpired = shift; + my $expireTime = 0; + if ($withoutExpired) { + $expireTime = $self->session->datetime->time(); + } + return $self->session->db->buildHashRef("select users.userId, users.username from users join groupings using(userId) where expireDate > ? and groupId = ? order by username asc", [$expireTime, $self->getId]); +} #------------------------------------------------------------------- @@ -1014,7 +1038,6 @@ sub isEditable { return $self->get("isEditable"); } - #------------------------------------------------------------------- =head2 lastUpdated ( ) @@ -1053,7 +1076,7 @@ sub name { #------------------------------------------------------------------- -=head2 new ( session, groupId [, overrideId ] ) +=head2 new ( session, groupId [, overrideId, noAdmin ] ) Constructor. @@ -1069,6 +1092,10 @@ The groupId of the group you're creating an object reference for. If specified a If you specified "new" for groupId, you can use this property to specify an id you wish to create, rather than having the system generate one for you. +=head3 noAdmin + +If you specified "new" for groupId, you can use this property to specify that you do not wish the admin user or group to be added to the group + =cut sub new { @@ -1078,13 +1105,14 @@ sub new { $self->{_session} = shift; $self->{_groupId} = shift; my $override = shift; + my $noAdmin = shift; my $cached = $self->{_session}->stow->get("groupObj"); return $cached->{$self->{_groupId}} if ($cached->{$self->{_groupId}}); bless $self, $class; if ($self->{_groupId} eq "new") { - $self->_create($override); + $self->_create($override,$noAdmin); } elsif ($self->{_groupId} eq "") { $self->{_group} = $self->_defaults(); diff --git a/lib/WebGUI/Inbox.pm b/lib/WebGUI/Inbox.pm index 852534dc1..a15f92a13 100644 --- a/lib/WebGUI/Inbox.pm +++ b/lib/WebGUI/Inbox.pm @@ -82,6 +82,39 @@ sub addPrivateMessage { #------------------------------------------------------------------- +=head2 canRead ( messageId [, user] ) + +Returns whether or not a user can view the message passed in. + +=head3 message + +A WebGUI::Inbox::Message object + +=head3 user + +WebGUI::User object to test against. Defaults to the current user. + +=cut + +sub canRead { + my $self = shift; + my $message = shift; + my $user = shift || $self->session->user; + + unless (ref $message eq "WebGUI::Inbox::Message") { + $self->session->log->warn("Message passed in was either empty or not a valid WebGUI::Inbox::Message. Got: ".(ref $message)); + return 0 + } + + my $userId = $message->get("userId"); + my $groupId = $message->get("groupId"); + + return ($user->userId eq $userId || (defined $groupId && $user->isInGroup($groupId))); + +} + +#------------------------------------------------------------------- + =head2 DESTROY ( ) Deconstructor. @@ -95,7 +128,7 @@ sub DESTROY { #------------------------------------------------------------------- -=head2 getMessage ( messageId ) +=head2 getMessage ( messageId [, userId] ) Returns a WebGUI::Inbox::Message object. @@ -103,17 +136,91 @@ Returns a WebGUI::Inbox::Message object. The id of the message to retrieve. +=head3 userId + +The id of the user to retrieve the message for. Defaults to the current user. + =cut sub getMessage { - my $self = shift; - return WebGUI::Inbox::Message->new($self->session, shift); -} + my $self = shift; + my $messageId = shift; + my $userId = shift; + return WebGUI::Inbox::Message->new($self->session, $messageId, $userId); +} #------------------------------------------------------------------- -=head2 getMessagesForUser ( user [ , limit ] ) +=head2 getNextMessage ( message [, userId] ) + +Returns the next message for the user + +=head3 message + +The message to find the next message for + +=head3 user + +The WebGUI::User object of the user to retrieve the message for. Defaults to the current user. + +=cut + +sub getNextMessage { + my $self = shift; + my $session = $self->session; + my $message = shift; + my $user = shift || $session->user; + + my $sql = $self->getMessageSql($user,{ + whereClause => "ibox.dateStamp < ".$message->get("dateStamp"), + sortBy => "ibox.dateStamp", + sortDir => "desc", + limit => 1 + }); + + my $message = $self->session->db->quickHashRef($sql); + + return $self->getMessage($message->{messageId}); +} + +#------------------------------------------------------------------- + +=head2 getPreviousMessage ( message [, userId] ) + +Returns the previous message for the user + +=head3 message + +The message to find the previous message for + +=head3 user + +The WebGUI::User object of the user to retrieve the message for. Defaults to the current user. + +=cut + +sub getPreviousMessage { + my $self = shift; + my $session = $self->session; + my $message = shift; + my $user = shift || $session->user; + + my $sql = $self->getMessageSql($user,{ + whereClause => "ibox.dateStamp > ".$message->get("dateStamp"), + sortBy => "ibox.dateStamp", + sortDir => "asc", + limit => 1 + }); + + my $message = $self->session->db->quickHashRef($sql); + + return $self->getMessage($message->{messageId}); +} + +#------------------------------------------------------------------- + +=head2 getMessagesForUser ( user [ , limit, page, sortBy ] ) Returns an array reference containing the most recent message objects for a given user. @@ -125,6 +232,14 @@ A user object. An integer indicating the number of messages to fetch. Defaults to 50. +=head3 page + +An integer indication the page to return. Defaults to 1 + +=head3 sortby + +The column to sort by + =cut sub getMessagesForUser { @@ -134,60 +249,263 @@ sub getMessagesForUser { my $page = shift || 1; my $sortBy = shift; - my @messages = (); - my $counter = 0; + my $p = $self->getMessagesPaginator( $user , { + sortBy => $sortBy, + sortDir => "desc", + paginateAfter => $perpage, + pageNumber => $page + + }); - my ( $sql, @bindvars ); - my $start = (($page-1) * $perpage); - my $end = $start + $page * $perpage; - my $limit = "$start, $perpage"; - - ### Here we're going to get enough rows to fill our needs ($end) from each subquery, then - ### use the UNION to grab only the rows we want to display ($limit) - - # If we have a way to sort, use that - if ( grep { $_ eq $sortBy } qw( subject sentBy dateStamp ) ) { - $sql = q{ ( SELECT messageId, userId, groupId, %s FROM inbox WHERE userId = "%s" ORDER BY %s LIMIT %s ) } - . q{ UNION } - . q{ ( SELECT messageId, userId, groupId, %s FROM inbox WHERE groupId IN ( %s ) ORDER BY %s LIMIT %s ) } - . q{ ORDER BY %s LIMIT %s } - ; - @bindvars = ( - $sortBy, $user->userId, $sortBy, $end, - $sortBy, $self->session->db->quoteAndJoin( $user->getGroupIdsRecursive ), $sortBy, $end, - $sortBy, $limit - ); - } - # Otherwise put "pending" messages above "completed" messaged and sort by date descending - else { - $sql = - q{ ( SELECT messageId, status, dateStamp FROM inbox WHERE status="pending" AND groupId IN ( %s ) ORDER BY dateStamp DESC LIMIT %s ) } - . q{ UNION } - . q{ ( SELECT messageId, status, dateStamp FROM inbox WHERE status="pending" AND userId = "%s" ORDER BY dateStamp DESC LIMIT %s ) } - . q{ UNION } - . q{ ( SELECT messageId, status, dateStamp FROM inbox WHERE status="completed" AND groupId IN ( %s ) ORDER BY dateStamp DESC LIMIT %s ) } - . q{ UNION } - . q{ ( SELECT messageId, status, dateStamp FROM inbox WHERE status="completed" AND userId = "%s" ORDER BY dateStamp DESC LIMIT %s ) } - . q{ ORDER BY status="pending" DESC, dateStamp DESC LIMIT %s } - ; - - @bindvars = ( - ( $self->session->db->quoteAndJoin( $user->getGroupIdsRecursive ), $end, - $user->userId, $end, - ) x 2, - $limit, - ); - } - - my $rs = $self->session->db->read( sprintf $sql, @bindvars ); - while ( my ( $messageId ) = $rs->array ) { - push @messages, $self->getMessage( $messageId ); - } - $rs->finish; - - return \@messages; + return $self->getMessagesOnPage($p); } +#------------------------------------------------------------------- + +=head2 getMessagesOnPage ( paginator ) + +Returns an array ref of WebGUI::Inbox::Message objects created from the current +page of data. + +=head3 paginator + +The id of the message to retrieve. + +=cut + +sub getMessagesOnPage { + my $self = shift; + my $p = shift; + my @messages = (); + + unless (defined $p and ref $p eq "WebGUI::Paginator") { + $self->session->log->warn("Paginator was not defined"); + return []; + } + + foreach my $row (@{$p->getPageData}) { + push @messages, $self->getMessage( $row->{messageId} ); + } + + return \@messages; +} + + + +#------------------------------------------------------------------- + +=head2 getMessagesPaginator ( user [, properties ] ) + +Returns an reference to a WebGUI::Paginator object filled with all the messages in a user's inbox + +=head3 user + +A user object. + +=head3 properties + +Properties which can be set to determine how many rows are returned, etc + +=head4 sortBy + +Column to sort the inbox by. Valid values are subject, sentBy, and dateStamp. Defaults to +dateStamp if value is invalid. Defaults to status="pending" DESC, dateStamp DESC if value not set. + +=head4 sortDir + +Direction to sort the results by. Defaults to desc. This only works if a sortBy value is set. + +=head4 baseUrl + +The URL of the current page including attributes. The page number will be appended to this in all links generated by the paginator. +Defaults to $session->url->pge + +=head4 paginateAfter + +The number of rows to display per page. If left blank it defaults to 25. + +=head4 formVar + +Specify the form variable the paginator should use in its links. Defaults to "pn". + +=head pageNumber + +By default the page number will be determined by looking at $self->session->form->process("pn"). If that is empty the page number will be defaulted to "1". If you'd like to override the page number specify it here. + +=cut + +sub getMessagesPaginator { + my $self = shift; + my $session = $self->session; + my $user = shift || $session->user; + my $properties = shift; + + my $userId = $user->userId; + my $sortBy = $properties->{sortBy}; + my $sortDir = $properties->{sortDir} || "desc"; + my $baseUrl = $properties->{baseUrl} || $session->url->page; + my $paginateAfter = $properties->{paginateAfter}; + my $formVar = $properties->{formVar}; + my $pageNumber = $properties->{pageNumber}; + + #Make sure a valid sortBy is passed in + if($sortBy && !WebGUI::Utility::isIn($sortBy,qw( subject sentBy dateStamp status ))) { + $sortBy = q{dateStamp} + } + #Sort by fullname if user wants to sort by who sent the message + if ($sortBy eq "sentBy") { + $sortBy = q{fullName}; + } + elsif ($sortBy eq "status") { + $sortBy = q{messageStatus}; + } + elsif($sortBy) { + $sortBy = qq{ibox.$sortBy}; + } + else { + $sortBy = q{messageStatus='pending' DESC, dateStamp DESC}; + $sortDir = q{}; + } + + my $sql = $self->getMessageSql($user, { + user => $user, + sortBy => $sortBy, + sortDir => $sortDir + }); + + #$session->log->warn($sql); + + my $p = WebGUI::Paginator->new( + $session, + $baseUrl, + $paginateAfter, + $formVar, + $pageNumber + ); + + $p->setDataByQuery($sql,undef,undef); + + return $p; +} + +#------------------------------------------------------------------- + +=head2 getMessageSql ( user, properties ) + +Returns the SQL used to return the messages in a user's inbox. + +=head3 user + +WebGUI::User object of user to get messages for. Defaults to current user. + +=head3 properties + +Hash reference of properties + +=head4 sortBy + +Column to sort by. Valid columns are: + + ibox.messageId, + ibox.subject, + ibox.sentBy, + ibox.dateStamp, + ibox.status, + messageStatus, + fullName + +=head4 sortDir + +Direction to sort by + +=head4 whereClause + +A where clause to use + +=head4 limit + +Column + +=cut + +sub getMessageSql { + my $self = shift; + my $session = $self->session; + my $user = shift || $session->user; + my $props = shift || {}; + + my $userId = $user->userId; + my $sortBy = $props->{sortBy}; + my $sortDir = $props->{sortDir}; + my $whereClause = $props->{whereClause}; + my $limit = $props->{limit}; + + if($sortBy) { + $sortBy = qq{ORDER BY $sortBy $sortDir}; + } + + if($whereClause) { + $whereClause = qq{WHERE $whereClause}; + } + + if($limit) { + $limit = qq{LIMIT $limit}; + } + + my $messageLimit = 20_000; + my $limitHalf = $messageLimit / 2; + my $limitQuarter = $messageLimit / 4; + my $userGroups = $session->db->quoteAndJoin( $user->getGroupIdsRecursive ); + + # for performance purposes don't use datasets larger than 20000 no matter how man messages are in the inbox + my $sql = qq{ + SELECT + ibox.messageId, ibox.subject, ibox.sentBy, ibox.dateStamp, + (IF(ibox.status = 'completed' or ibox.status = 'pending',ibox.status,IF(inbox_messageState.repliedTo,'replied',IF(inbox_messageState.isRead,'read','unread')))) as messageStatus, + (IF(userProfileData.firstName != '' and userProfileData.firstName is not null and userProfileData.lastName !='' and userProfileData.lastName is not null, concat(userProfileData.firstName,' ',userProfileData.lastName),users.username)) as fullName + FROM ( + ( SELECT messageId, subject, sentBy, dateStamp, status FROM inbox WHERE userId = '$userId' order by dateStamp desc limit $limitHalf) + UNION + ( SELECT messageId, subject, sentBy, dateStamp, status FROM inbox WHERE groupId IN ( $userGroups ) order by dateStamp desc limit $limitHalf ) + ) AS ibox + JOIN inbox_messageState on inbox_messageState.messageId=ibox.messageId and inbox_messageState.userId='$userId' and inbox_messageState.deleted=0 + LEFT JOIN users on users.userId=ibox.sentBy + LEFT JOIN userProfileData on userProfileData.userId=ibox.sentBy + $whereClause + $sortBy + $limit + }; + + #$session->log->warn($sql); + + return $sql; +} + + +#------------------------------------------------------------------- + +=head2 getUnreadMessageCount ( [userId] ) + +Returns the number of unread messages for the user passed in + +=head3 userId + +user to get unread message count for. Defaults to current user. + +=cut + +sub getUnreadMessageCount { + my $self = shift; + my $session = $self->session; + my $userId = shift || $session->user->userId; + + return $session->db->quickScalar( + qq{select count(*) from inbox_messageState where userId=? and deleted=0 and isRead=0 }, + [$userId] + ); +} + + #------------------------------------------------------------------- diff --git a/lib/WebGUI/Inbox/Message.pm b/lib/WebGUI/Inbox/Message.pm index 8b0438744..37af5703c 100644 --- a/lib/WebGUI/Inbox/Message.pm +++ b/lib/WebGUI/Inbox/Message.pm @@ -97,15 +97,43 @@ sub create { $self->{_properties}{subject} = $properties->{subject} || WebGUI::International->new($session)->get(523); $self->{_properties}{message} = $properties->{message}; $self->{_properties}{dateStamp} = time(); - $self->{_properties}{userId} = $properties->{userId}; + $self->{_properties}{userId} = $properties->{userId} || $session->user->userId; $self->{_properties}{groupId} = $properties->{groupId}; $self->{_properties}{sentBy} = $properties->{sentBy} || 3; - if ($self->{_properties}{status} eq "completed") { + + my $status = $self->{_properties}{status}; + + if ($status eq "completed") { $self->{_properties}{completedBy} = $session->user->userId; $self->{_properties}{completedOn} = time(); } + elsif($status ne "pending") { + $self->{_properties}{status} = "active"; + } + $self->{_messageId} = $self->{_properties}{messageId} = $session->db->setRow("inbox","messageId",$self->{_properties}); - + $self->{_userId } = $self->{_properties}{userId}; + $self->{_inbox } = $self->{_properties}; + + #Add the message state row for individual user passed in + if($self->{_properties}{userId}) { + $session->db->write( + q{ REPLACE INTO inbox_messageState (messageId,userId) VALUES (?,?) }, + [$self->{_messageId},$self->{_properties}{userId}] + ); + } + #Add the message state row for every user in the group + if($self->{_properties}{groupId}) { + my $g = WebGUI::Group->new($session,$self->{_properties}{groupId}); + my $users = $g->getAllUsers; + foreach my $userId (@{$users}) { + $session->db->write( + q{ REPLACE INTO inbox_messageState (messageId,userId) VALUES (?,?) }, + [$self->{_messageId},$userId] + ); + } + } + my $subject = (defined $properties->{emailSubject}) ? $properties->{emailSubject} : $self->{_properties}{subject}; my $mail = WebGUI::Mail::Send->create($session, { toUser=>$self->{_properties}{userId}, @@ -137,16 +165,34 @@ sub create { #------------------------------------------------------------------- -=head2 delete ( ) +=head2 delete ( userId ) -Deletes this message from the inbox. +Deletes this message from the inbox for the user passed in + +=head3 userId + +User to delete message for. If no user is passed in, the current user will be used. =cut sub delete { - my $self = shift; - my $sth = $self->session->db->prepare("delete from inbox where messageId=?"); - $sth->execute([$self->getId]); + my $self = shift; + my $session = $self->session; + my $db = $session->db; + my $messageId = $self->getId; + my $userId = shift || $self->{_userId}; + + $self->setDeleted($userId); + + my $isActive = $db->quickScalar( + q{ select count(*) from inbox_messageState where messageId=? and deleted=0 }, + [$messageId] + ); + #Delete the message from the database if everyone who was sent the message has deleted it + unless ($isActive) { + $db->write("delete from inbox where messageId=?",[$messageId]); + $db->write("delete from inbox_messageState where messageId=?",[$messageId]); + } } #------------------------------------------------------------------- @@ -158,8 +204,8 @@ Deconstructor. =cut sub DESTROY { - my $self = shift; - undef $self; + my $self = shift; + undef $self; } #------------------------------------------------------------------- @@ -189,6 +235,17 @@ An epoch date representing when the action associated with this message was comp sub get { my $self = shift; my $name = shift; + + if($name eq "status") { + my $status = $self->{_properties}{status}; + if($status eq "active") { + return "read" if($self->{_properties}{isRead}); + return "replied" if($self->{_properties}{repliedTo}); + return "unread"; + } + return $status; + } + return $self->{_properties}{$name}; } @@ -206,6 +263,48 @@ sub getId { return $self->{_messageId}; } + +#------------------------------------------------------------------- + +=head2 getStatus ( [ userId ] ) + +Gets the current status of the message for the user passed in + +=head3 userId + +The id of the user to get the status of the message for. Defaults to the current user. + +=cut + +sub getStatus { + my $self = shift; + my $userId = shift || $self->{_userId}; + + my $status = $self->{_properties}{status}; + my $statusCodes = $self->statusCodes; + + if($status eq "active") { + return $statusCodes->{"replied"} if($self->{_properties}{repliedTo}); + return $statusCodes->{"read" } if($self->{_properties}{isRead}); + return $statusCodes->{"unread" }; + } + + return $statusCodes->{$self->get("status")}; +} + +#------------------------------------------------------------------- + +=head2 isRead ( ) + +Returns whether or not the message has been read. + +=cut + +sub isRead { + my $self = shift; + return $self->{_properties}{isRead}; +} + #------------------------------------------------------------------- =head2 new ( session, messageId ) @@ -224,10 +323,31 @@ The unique id of a message. =cut sub new { - my $class = shift; - my $session = shift; + my $class = shift; + my $session = shift; my $messageId = shift; - bless {_properties=>$session->db->getRow("inbox","messageId",$messageId), _session=>$session, _messageId=>$messageId}, $class; + my $userId = shift || $session->user->userId; + + #Don't bother going on if a messageId wasn't passed in + return undef unless $messageId; + + my $inbox = $session->db->getRow("inbox","messageId",$messageId); + my $statusValues = $session->db->quickHashRef( + q{ select isRead, repliedTo, deleted from inbox_messageState where messageId=? and userId=? }, + [$messageId,$userId] + ); + + #Don't return messages that don't exist + return undef unless (scalar(keys %{$inbox})); + + #Don't return deleted messages + return undef if($statusValues->{deleted}); + + my $self = {}; + + my %properties = (%{$inbox},%{$statusValues}); + + bless {_properties=>\%properties, _inbox=>$inbox, _session=>$session, _messageId=>$messageId, _userId=>$userId}, $class; } #------------------------------------------------------------------- @@ -261,9 +381,78 @@ sub setCompleted { $self->{_properties}{status} = "completed"; $self->{_properties}{completedBy} = $userId; $self->{_properties}{completedOn} = time(); - $self->session->db->setRow("inbox","messageId",$self->{_properties}); + $self->session->db->setRow("inbox","messageId",$self->{_inbox}); + #Completed messages should also be marked read + $self->setRead($userId); } +#------------------------------------------------------------------- + +=head2 setDeleted ( [ userId ] ) + +Marks a message deleted. + +=head4 userId + +The id of the user that deleted this message. Defaults to the current user. + +=cut + +sub setDeleted { + my $self = shift; + my $userId = shift || $self->session->user->userId; + + $self->session->db->write( + q{update inbox_messageState set deleted=1 where messageId=? and userId=?}, + [$self->getId,$userId] + ); +} + +#------------------------------------------------------------------- + +=head2 setRead ( [ userId ] ) + +Marks a message read. + +=head4 userId + +The id of the user that reads this message. Defaults to the current user. + +=cut + +sub setRead { + my $self = shift; + my $userId = shift || $self->session->user->userId; + + $self->session->db->write( + q{update inbox_messageState set isRead=1 where messageId=? and userId=?}, + [$self->getId,$userId] + ); +} + +#------------------------------------------------------------------- + +=head2 setReplied ( [ userId ] ) + +Marks a message replied. + +=head4 userId + +The id of the user that replied to this message. Defaults to the current user. + +=cut + +sub setReplied { + my $self = shift; + my $userId = shift || $self->session->user->userId; + + $self->session->db->write( + q{update inbox_messageState set repliedTo=1, isRead=1 where messageId=? and userId=?}, + [$self->getId,$userId] + ); +} + + #------------------------------------------------------------------- =head2 setStatus ( status,[ userId ] ) @@ -281,22 +470,111 @@ The id of the user that completed this task. Defaults to the current user. =cut sub setStatus { - my $self = shift; - my $status = shift; - my $userId = shift || $self->session->user->userId; + my $self = shift; + my $status = shift; + my $session = $self->session; + my $userId = shift || $session->user->userId; unless ($status) { - $self->session->errorHandler->warn("No status passed in for message. Exit without update"); + $session->log->warn("No status passed in for message. Exit without update"); return undef; } - + + unless($self->isValidStatus($status)) { + $self->session->log->warn("Invalid status $status passed in for message. Exit without update"); + return undef; + } + if($status eq "completed") { $self->setCompleted($userId); return undef; } - $self->{_properties}{status} = $status; - $self->session->db->setRow("inbox","messageId",$self->{_properties}); + elsif($status eq "read") { + $self->setRead($userId); + } + elsif($status eq "unread") { + $self->setUnread($userId); + } + elsif($status eq "replied") { + $self->setReplied($userId); + } + + $self->{_properties}{status} = ( $status ne "pending") ? "active" : "pending"; + $self->session->db->setRow("inbox","messageId",$self->{_inbox}); return undef; } +#------------------------------------------------------------------- + +=head2 setUnread ( [ userId ] ) + +Marks a message unread. + +=head4 userId + +The id of the user that reads this message. Defaults to the current user. + +=cut + +sub setUnread { + my $self = shift; + my $userId = shift || $self->session->user->userId; + + $self->session->db->write( + q{update inbox_messageState set isRead=0 where messageId=? and userId=?}, + [$self->getId,$userId] + ); +} + +#------------------------------------------------------------------- + +=head2 statusCodes ( session ) + +Returns a hash ref of valid status values. Can be called as a class or instance method + +=head4 status + +The id of the user that replied to this message. Defaults to the current user. + +=cut + +sub statusCodes { + my $self = shift; + my $session = shift; + + if(ref $self eq "WebGUI::Inbox::Message") { + $session = $self->session; + } + + my $i18n = WebGUI::International->new($session); + return { + "active" => $i18n->get("inbox message status active"), + "pending" => $i18n->get(552), + "completed" => $i18n->get(350), + "unread" => $i18n->get("private message status unread"), + "read" => $i18n->get("private message status read"), + "replied" => $i18n->get("private message status replied"), + } +} + + +#------------------------------------------------------------------- + +=head2 isValidStatus ( status ) + +Returns whether or not the status passed in is valid. Can be called as a class or instance method + +=head4 status + +The id of the user that replied to this message. Defaults to the current user. + +=cut + +sub isValidStatus { + my $self = shift; + my $status = shift; + return (exists $self->statusCodes->{$status}); +} + + 1; diff --git a/lib/WebGUI/Macro/FileUrl.pm b/lib/WebGUI/Macro/FileUrl.pm index d3db012e0..556f23b4d 100644 --- a/lib/WebGUI/Macro/FileUrl.pm +++ b/lib/WebGUI/Macro/FileUrl.pm @@ -26,7 +26,7 @@ identified by it's asset URL. #------------------------------------------------------------------- -=head2 process ( url ) +=head2 process ( url, id, isStorageId, filename ) returns the file system URL if url is the URL for an Asset in the system that has storageId and filename properties. If no Asset @@ -37,13 +37,43 @@ be returned. The URL to the Asset. +head3 id + +If id is passed in, the macro will attempt to retrive the storageId using the +Id of the Asset instead of by the url + +=head3 isStorageId + +If id is passed in and the isStorageId flag is set, the macro will forgo +the asset and simply return the url of the first file it finds + +=head3 filename + +If id is passed in and the isStorageId flag is set, you may pass in filename +to specify the name of the file you'd like returned. + =cut sub process { - my $session = shift; - my $url = shift; - my $asset = WebGUI::Asset->newByUrl($session,$url); - my $i18n = WebGUI::International->new($session, 'Macro_FileUrl'); + my $session = shift; + my $url = shift; + my $id = shift; + my $isStorageId = shift; + my $filename = shift; + my $i18n = WebGUI::International->new($session, 'Macro_FileUrl'); + + #Handle storageId case + if($isStorageId && $id) { + my $store = WebGUI::Storage->get($session,$id); + $filename = $store->getFiles->[0] unless ($filename); + return "" unless ($filename); + return $store->getUrl($filename); + } + + my $asset = ($id) + ? WebGUI::Asset->newByDynamicClass($session,$id) + : WebGUI::Asset->newByUrl($session,$url); + if (not defined $asset) { return $i18n->get('invalid url'); } diff --git a/lib/WebGUI/Operation/Inbox.pm b/lib/WebGUI/Operation/Inbox.pm index c0356f564..89bbe5a9f 100644 --- a/lib/WebGUI/Operation/Inbox.pm +++ b/lib/WebGUI/Operation/Inbox.pm @@ -37,6 +37,9 @@ Operations for viewing message logs and individual messages. appends the form variables for the private message form +DEPRECATED: Do not use this method in new code. It is here for API +compatibility only + =cut sub _appendPrivateMessageForm { @@ -55,10 +58,6 @@ sub _appendPrivateMessageForm { $vars->{ message_to_label } = $i18n->get("private message to label"); $vars->{ message_to } = $userTo->username; - $vars->{ message_to } .= WebGUI::Form::hidden($session, { - name=>"uid", - value=>$userTo->userId - }); my $subject = $form->get("subject") || ""; if($subject eq "" && defined $message) { @@ -81,14 +80,10 @@ sub _appendPrivateMessageForm { value=>$form->get("message") || "", }); - $vars->{ form_header } = WebGUI::Form::formHeader($session); - $vars->{ form_header } .= WebGUI::Form::hidden($session, { - name => "op", - value => "sendPrivateMessageSave" - }); - $vars->{ form_header } .= WebGUI::Form::hidden($session, { - name => "messageId", - value => $form->get("messageId") || "", + my $messageId = $form->get("messageId") || $message->getId; + $vars->{'form_header' } = WebGUI::Form::formHeader($session,{ + action => $session->url->page->("op=account;module=inbox;do=sendMessageSave;messageId=$messageId;userId=$userTo->userId"), + extras => q{name="messageForm"} }); $vars->{ submit_button } = WebGUI::Form::submit($session,{}); @@ -104,24 +99,29 @@ sub _appendPrivateMessageForm { returns a hashref with internationalized values for message status. +DEPRECATED: Use WebGUI::Inbox::Message->statusCodes + =cut sub _status { my $session = shift; - my $i18n = WebGUI::International->new($session); - return { - "pending" =>$i18n->get(552), - "completed" =>$i18n->get(350), - "unread" =>$i18n->get("private message status unread"), - "read" =>$i18n->get("private message status read"), - "replied" =>$i18n->get("private message status replied"), - }; + return WebGUI::Inbox::Message->statusCodes($session); + #my $i18n = WebGUI::International->new($session); + #return { + # "pending" =>$i18n->get(552), + # "completed" =>$i18n->get(350), + # "unread" =>$i18n->get("private message status unread"), + # "read" =>$i18n->get("private message status read"), + # "replied" =>$i18n->get("private message status replied"), + #}; } #------------------------------------------------------------------- =head2 www_sendPrivateMessage ( ) +DEPRECATED: Use WebGUI::Account::Inbox + Form for sending private messages =cut @@ -169,6 +169,8 @@ sub www_sendPrivateMessage { =head2 www_sendPrivateMessageSave ( ) +DEPRECATED: Use WebGUI::Account::Inbox + Post process the form, check for required fields, handle inviting users who are already members (determined by email address) and send the email. @@ -244,6 +246,8 @@ sub www_sendPrivateMessageSave { =head2 www_viewInbox ( ) +DEPRECATED: Use WebGUI::Account::Inbox + Templated display all messages for the current user. =cut @@ -335,6 +339,8 @@ sub www_viewInbox { =head2 www_deletePrivateMessage ( ) +DEPRECATED: Use WebGUI::Account::Inbox + Mark a private message in the inbox as deleted. =cut @@ -356,6 +362,8 @@ sub www_deletePrivateMessage { =head2 www_viewInboxMessage ( ) +DEPRECATED: Use WebGUI::Account::Inbox + Templated display of a single message for the user. =cut diff --git a/lib/WebGUI/Operation/Profile.pm b/lib/WebGUI/Operation/Profile.pm index bfa3b8c72..4abf01362 100644 --- a/lib/WebGUI/Operation/Profile.pm +++ b/lib/WebGUI/Operation/Profile.pm @@ -46,7 +46,7 @@ These methods are available from this package: Returns an array of hashes for required profile fields. This array is ready to be used as template variables in the WebGUI template system. -This method is deprecated, and should not be used in new code. Use +DEPRECATED - This method is deprecated, and should not be used in new code. Use the getRequiredFields method from WebGUI::ProfileField and specify the translation to template variables directly instead. @@ -80,6 +80,9 @@ duplicated in the system. Returns true of false. Will return false if the email address passed in is same as the email address of the current user. +DEPRECATED - This method is deprecated, and should not be used in new code. Use +the isDuplicate method from WebGUI::ProfileField instead + =head3 email email address to check for duplication @@ -103,6 +106,9 @@ sub isDuplicateEmail { Saves profile data to a user's profile. Does not validate any of the data. +DEPRECATED - This method is deprecated, and should not be used in new code. Use +the saveProfileFields method from WebGUI::Account::Profile instead + =head3 session WebGUI session object @@ -122,9 +128,7 @@ sub saveProfileFields { my $u = shift; my $profile = shift; - foreach my $fieldName (keys %{$profile}) { - $u->profileField($fieldName,${$profile}{$fieldName}); - } + WebGUI::Account::Profile->saveProfileFields($session,$u,$profile); } #------------------------------------------------------------------- @@ -134,6 +138,9 @@ sub saveProfileFields { Validates profile data from the session form variables. Returns processed data, warnings and errors. +DEPRECATED - This method is deprecated, and should not be used in new code. Use +the validateProfileData method from WebGUI::Account::Profile instead + There are two levels of validation: =over 4 @@ -191,6 +198,8 @@ makes a large set of template variables which are passed to a template for prese and styling. The default template is PBtmpl0000000000000051 and is not user selectable. +DEPRECATED - Use WebGUI::Account::Profile::www_edit + Calls www_editProfileSave on submission. =head3 session @@ -253,6 +262,9 @@ object. Returns the user to WebGUI::Operation::Auth::www_auth when done. + +DEPRECATED: Use WebGUI::Account::Profile::www_editSave + =head3 session A reference to the current session. @@ -281,6 +293,8 @@ Validates that the user requesting the profile data is allowed to see it. Similarly to www_editProfile, this method is templated. The default template is PBtmpl0000000000000052. The template is not user selectable. +DEPRECATED: Use WebGUI::Account::Profile::www_view + =head3 session A reference to the current session. diff --git a/lib/WebGUI/Operation/ProfileSettings.pm b/lib/WebGUI/Operation/ProfileSettings.pm index 92644dffa..8ddcbb5d9 100644 --- a/lib/WebGUI/Operation/ProfileSettings.pm +++ b/lib/WebGUI/Operation/ProfileSettings.pm @@ -169,6 +169,12 @@ sub www_editProfileCategory { -hoverHelp => $i18n->get('470 description'), -value => $data->{label}, ); + $f->text( + -name => "shortLabel", + -label => $i18n->get('category short name'), + -hoverHelp => $i18n->get('category short name description'), + -value => $data->{shortLabel}, + ); $f->yesNo( -name=>"visible", -label=>$i18n->get(473), @@ -198,10 +204,11 @@ sub www_editProfileCategorySave { my $session = shift; return $session->privilege->adminOnly() unless canView($session); my %data = ( - label=>$session->form->text("label"), - visible=>$session->form->yesNo("visible"), - editable=>$session->form->yesNo("editable"), - ); + label =>$session->form->text("label"), + shortLabel =>$session->form->text("shortLabel"), + visible =>$session->form->yesNo("visible"), + editable =>$session->form->yesNo("editable"), + ); if ($session->form->process("cid") eq "new") { my $category = WebGUI::ProfileCategory->create($session,\%data); } else { diff --git a/lib/WebGUI/Operation/Settings.pm b/lib/WebGUI/Operation/Settings.pm index c980492d7..1c4e83f00 100644 --- a/lib/WebGUI/Operation/Settings.pm +++ b/lib/WebGUI/Operation/Settings.pm @@ -632,8 +632,8 @@ sub www_editSettings { # Get fieldsets for avaiable account methods my $accountConfigs = $session->config->get("account"); - foreach my $accountKey (keys %{$accountConfigs}) { - my $account = $accountConfigs->{$accountKey}; + + foreach my $account (@{$accountConfigs}) { #Create the instance my $className = $account->{className}; @@ -645,7 +645,7 @@ sub www_editSettings { } #Get the content of the settings form from the instance - my $settingsForm = $instance->editUserSettingsForm; + my $settingsForm = $instance->editSettingsForm; #If editUserSettingsForm is empty, skip it next if $settingsForm eq ""; @@ -698,6 +698,22 @@ sub www_saveSettings { } } + # Save account pluggin settings + my $accountConfigs = $session->config->get("account"); + foreach my $account (@{$accountConfigs}) { + #Create the instance + my $className = $account->{className}; + my $instance = eval { WebGUI::Pluggable::instanciate($className,"new",[ $session ]) }; + + if ( my $e = WebGUI::Error->caught ) { + $session->log->warn("Could not instantiate account pluggin $className...skipping"); + next; + } + #Save the settings + $instance->editSettingsFormSave; + } + + ### Handle special settings # Reset login message seen numbers if ( $session->form->get( 'showMessageOnLoginReset' ) ) { diff --git a/lib/WebGUI/Paginator.pm b/lib/WebGUI/Paginator.pm index 45111c606..2cce878ee 100644 --- a/lib/WebGUI/Paginator.pm +++ b/lib/WebGUI/Paginator.pm @@ -486,6 +486,7 @@ sub getPageLinks { "pagination.url" => '', "pagination.text" => $i+1, 'pagination.range' => ($first+1) . "-" . ($last+1), + 'pagination.activePage' => "true", }; } else { push @pages, '
'.($i+1).''; diff --git a/lib/WebGUI/ProfileCategory.pm b/lib/WebGUI/ProfileCategory.pm index b0eac652c..062746f08 100644 --- a/lib/WebGUI/ProfileCategory.pm +++ b/lib/WebGUI/ProfileCategory.pm @@ -177,6 +177,20 @@ sub getLabel { return WebGUI::Operation::Shared::secureEval($self->session,$self->get("label")); } +#------------------------------------------------------------------- + +=head2 getShortLabel ( ) + +Returns the eval'd label for this category. + +=cut + +sub getShortLabel { + my $self = shift; + return WebGUI::Operation::Shared::secureEval($self->session,$self->get("shortLabel")); +} + + #------------------------------------------------------------------- =head2 hasProtected ( ) @@ -332,6 +346,10 @@ A hash reference containing the properties to be updated. A perl structure that will return a scalar. Defaults to 'Undefined'. +=head4 shortLabel + +A perl structure that will return a scalar. Defaults to 'Undefined'. + =head4 visible A boolean indicating whether the fields in this category should be visible when a user views a user's profile. @@ -353,6 +371,7 @@ sub set { $properties->{editable} = 0 unless ($properties->{editable} == 1); $properties->{protected} = 0 unless ($properties->{protected} == 1); $properties->{label} = 'Undefined' if ($properties->{label} =~ /^[\"\']*$/); + $properties->{shortLabel} = 'Undefined' if ($properties->{shortLabel} =~ /^[\"\']*$/); $properties->{profileCategoryId} = $self->getId; $self->session->db->setRow("userProfileCategory","profileCategoryId",$properties); } diff --git a/lib/WebGUI/ProfileField.pm b/lib/WebGUI/ProfileField.pm index f6eba889d..ec4a493d2 100644 --- a/lib/WebGUI/ProfileField.pm +++ b/lib/WebGUI/ProfileField.pm @@ -253,6 +253,7 @@ sub formField { $properties->{value} = WebGUI::Operation::Shared::secureEval($self->session,$properties->{dataDefault}); } } + if ($withWrapper == 1) { return WebGUI::Form::DynamicField->new($self->session,%{$properties})->toHtmlWithWrapper; } elsif ($withWrapper == 2) { @@ -265,17 +266,24 @@ sub formField { #------------------------------------------------------------------- -=head2 formProcess ( ) +=head2 formProcess ( [user] ) Returns the value retrieved from a form post. =cut sub formProcess { - my $self = shift; - my $u = shift || $self->session->user; + my $self = shift; + my $u = shift || $self->session->user; + my $userId = $u->userId; + my $properties = $self->formProperties({value => $u->profileField($self->getId)}); - my $result = $self->session->form->process($self->getId,$self->get("fieldType"),WebGUI::Operation::Shared::secureEval($self->session,$self->get("dataDefault")), $properties); + my $result = $self->session->form->process( + $self->getId, + $self->get("fieldType"), + WebGUI::Operation::Shared::secureEval($self->session,$self->get("dataDefault")), + $properties + ); if (ref $result eq "ARRAY") { my @results = @$result; for (my $count=0;$count_listFieldsWhere($session, "f.required = 1 OR f.editable = 1 OR f.showAtRegistration = 1"); + return $class->_listFieldsWhere($session, "c.editable=1 AND (f.required = 1 OR f.editable = 1 OR f.showAtRegistration = 1)"); } #------------------------------------------------------------------- @@ -448,6 +457,7 @@ sub getRegistrationFields { return $class->_listFieldsWhere($session, "f.showAtRegistration = 1"); } +#------------------------------------------------------------------- =head2 getPasswordRecoveryFields ( session ) Returns an array reference of profile field objects that are required @@ -463,6 +473,31 @@ sub getPasswordRecoveryFields { #------------------------------------------------------------------- +=head2 isDuplicate( fieldValue ) + +Checks the value of the field to see if it is duplicated in the system. Returns true of false. + +=head3 fieldValue + +value to check for duplicates against + +=cut + +sub isDuplicate { + my $self = shift; + my $session = $self->session; + + my $fieldId = $self->getId; + my $value = shift; + + my $sql = qq{select count(*) from userProfileData where $fieldId = ? and userId <> ?}; + my ($duplicate) = $session->db->quickArray($sql,[$value, $session->user->userId]); + + return ($duplicate > 0); +} + +#------------------------------------------------------------------- + =head2 isEditable ( ) Returns a boolean indicating whether this field may be editable by a user. @@ -503,6 +538,30 @@ sub isRequired { #------------------------------------------------------------------- +=head2 isValid ( [fieldValue] ) + +Validates the profile field returning true (1) if valid or false(1) if false + +=head3 fieldValue + +value to validate the field against + +=cut + +sub isValid { + my $self = shift; + my $fieldValue = shift; + + #If the field value is an array ref, set the value to the first element + if(ref $fieldValue eq "ARRAY") { + $fieldValue = $fieldValue->[0]; + } + + return !$self->isRequired || ($self->isRequired && $fieldValue ne ""); +} + +#------------------------------------------------------------------- + =head2 isViewable ( ) Returns a boolean indicating whether this field may be viewed by a user. diff --git a/lib/WebGUI/Storage.pm b/lib/WebGUI/Storage.pm index 228a0b066..0f07d3b35 100644 --- a/lib/WebGUI/Storage.pm +++ b/lib/WebGUI/Storage.pm @@ -226,10 +226,13 @@ sub addFileFromFormPost { require Apache2::Upload; my $filename; my $attachmentCount = 1; + $self->session->log->warn("trying to uplaod: ".$formVariableName); foreach my $upload ($self->session->request->upload($formVariableName)) { - $self->session->errorHandler->info("Trying to get " . $upload->filename); + $self->session->errorHandler->warn("Trying to get " . $upload->filename); return $filename if $attachmentCount > $attachmentLimit; my $tempFilename = $upload->filename(); + $self->session->log->warn("templFile is: ".$tempFilename); + next unless $tempFilename; next unless $upload->size > 0; next if ($upload->size > 1024 * $self->session->setting->get("maxAttachmentSize")); diff --git a/lib/WebGUI/User.pm b/lib/WebGUI/User.pm index b392cced4..57c63ab34 100644 --- a/lib/WebGUI/User.pm +++ b/lib/WebGUI/User.pm @@ -114,6 +114,9 @@ sub acceptsPrivateMessages { my $self = shift; my $userId = shift; + return 0 if ($self->isVisitor); #Visitor can't get private messages + return 0 if ($self->userId eq $userId); #Can't send private messages to yourself + my $pmSetting = $self->profileField('allowPrivateMessages'); return 0 if ($pmSetting eq "none"); @@ -131,6 +134,33 @@ sub acceptsPrivateMessages { #------------------------------------------------------------------- +=head2 acceptsFriendsRequests ( user ) + +Returns whether or this user will accept friends requests from the user passed in + +=head3 user + +WebGUI::User object to check to see if user will accept requests from. + +=cut + +sub acceptsFriendsRequests { + my $self = shift; + my $user = shift; + + return 0 unless ($user && ref $user eq "WebGUI::User"); #Sanity checks + return 0 if($self->isVisitor); #Visitors can't have friends + return 0 if($self->userId eq $user->userId); #Can't be your own friend (why would you want to be?) + + my $friends = WebGUI::Friends->new($self->session,$self); + return 0 if ($friends->isFriend($user->userId)); #Already a friend + return 0 if ($friends->isInvited($user->userId)); #Invitation already sent + + return $self->profileField('ableToBeFriend'); #Return profile setting +} + +#------------------------------------------------------------------- + =head2 authMethod ( [ value ] ) Returns the authentication method for this user. @@ -288,13 +318,12 @@ Returns the WebGUI::Group for this user's Friend's Group. sub friends { my $self = shift; if ($self->{_user}{"friendsGroup"} eq "") { - my $myFriends = WebGUI::Group->new($self->session, "new"); + my $myFriends = WebGUI::Group->new($self->session, "new",0,1); $myFriends->name($self->username." Friends"); $myFriends->description("Friends of user ".$self->userId); $myFriends->expireOffset(60*60*24*365*60); $myFriends->showInForms(0); $myFriends->isEditable(0); - $myFriends->deleteUsers(['3']); $self->uncache; $self->{_user}{"friendsGroup"} = $myFriends->getId; $self->{_user}{"lastUpdated"} = $self->session->datetime->time(); @@ -387,6 +416,31 @@ sub getGroupIdsRecursive { return [ keys %groupIds ]; } +#------------------------------------------------------------------- + +=head2 getProfileUrl ( [page] ) + +Returns a link to the user's profile + +=head3 page + +If page is passed in, the profile ops will be appended to the page, otherwise +the method will return the ops appended to the current page. + +=cut + +sub getProfileUrl { + my $self = shift; + my $session = $self->session; + my $page = shift || $session->url->page; + + my $identifier = $session->config->get("profileModuleIdentifier"); + + return qq{$page?op=account;module=$identifier;do=view;uid=}.$self->userId; + +} + + #------------------------------------------------------------------- =head2 getWholeName ( ) @@ -404,6 +458,21 @@ sub getWholeName { return $self->profileField("alias") || $self->username; } + +#------------------------------------------------------------------- + +=head2 hasFriends ( ) + +Returns whether or not the user has any friends on the site. + +=cut + +sub hasFriends { + my $self = shift; + my $users = $self->friends->getUsers(1); + return scalar(@{$users}) > 0; +} + #------------------------------------------------------------------- # This method is depricated and is provided only for reverse compatibility. See WebGUI::Auth instead. sub identifier { diff --git a/lib/WebGUI/i18n/English/Account_Inbox.pm b/lib/WebGUI/i18n/English/Account_Inbox.pm index ad27f61e0..39d2732c4 100644 --- a/lib/WebGUI/i18n/English/Account_Inbox.pm +++ b/lib/WebGUI/i18n/English/Account_Inbox.pm @@ -9,7 +9,276 @@ our $I18N = { context => q{Tab label for Inbox Account pluggin}, }, + 'inbox style template label' => { + message => q|Style Template|, + lastUpdated => 1119068809 + }, + + 'inbox style template hoverHelp' => { + message => q|Select a style template from the list to enclose the inbox in.|, + lastUpdated => 1119068809 + }, + + 'inbox layout template label' => { + message => q|Edit Layout Template|, + lastUpdated => 1119068809 + }, + 'inbox layout template hoverHelp' => { + message => q{Choose a layout from the list to display the various account pluggins that are editable by the current user as well as the contents of the one currently chosen}, + lastUpdated => 1119068809 + }, + + 'inbox view template label' => { + message => q|View Template|, + lastUpdated => 1119068809 + }, + + 'inbox view template hoverHelp' => { + message => q|Choose the main template for viewing the inbox|, + lastUpdated => 1119068809 + }, + + 'inbox view message template label' => { + message => q|View Message Template|, + lastUpdated => 1119068809 + }, + + 'inbox view message template hoverHelp' => { + message => q|Choose the template for viewing a message in the inbox|, + lastUpdated => 1119068809 + }, + + 'inbox message confirm template label' => { + message => q|Inbox Message Confirm Template|, + lastUpdated => 1119068809 + }, + + 'inbox message confirm template hoverHelp' => { + message => q|Choose the template for displaying confirmation that a message has been sent|, + lastUpdated => 1119068809 + }, + + 'inbox error message template label' => { + message => q|Inbox Error Message Template|, + lastUpdated => 1119068809 + }, + + 'inbox error message template hoverHelp' => { + message => q|Choose the template for viewing inbox errors|, + lastUpdated => 1119068809 + }, + + 'inbox manage invitations template label' => { + message => q|Manage Invitations Template|, + lastUpdated => 1119068809 + }, + + 'inbox manage invitations template hoverHelp' => { + message => q|Choose the template to user for managing invitations|, + lastUpdated => 1119068809 + }, + + 'invitation error message template label' => { + message => q|Inbox Error Message Template|, + lastUpdated => 1119068809 + }, + + 'invitation error message template hoverHelp' => { + message => q|Choose the template for viewing inbox errors|, + lastUpdated => 1119068809 + }, + + 'subject label' => { + message => q|Subject|, + lastUpdated => 1119068809 + }, + + 'status label' => { + message => q{Status}, + lastUpdated => 1119068809 + }, + + 'date label' => { + message => q{Date}, + lastUpdated => 1119068809 + }, + + 'received label' => { + message => q{Received}, + lastUpdated => 1119068809 + }, + + 'recipients label' => { + message => q{Add Recipients}, + lastUpdated => 1119068809 + }, + + 'from label' => { + message => q{From}, + lastUpdated => 1119068809 + }, + + 'to label' => { + message => q{To}, + lastUpdated => 1119068809 + }, + + 'member since' => { + message => q{Member Since }, + lastUpdated => 1119068809 + }, + + 'delete label' => { + message => q{Delete}, + lastUpdated => 1119068809 + }, + + 'view my profile' => { + message => q{view my profile as others see it}, + lastUpdated => 1119068809 + }, + + 'messages label' => { + message => q{Messages}, + lastUpdated => 1119068809 + }, + + 'invitations label' => { + message => q{Invitations}, + lastUpdated => 1119068809 + }, + + 'previous label' => { + message => q{Previous}, + lastUpdated => 1119068809 + }, + + 'next label' => { + message => q{Next}, + lastUpdated => 1119068809 + }, + + 'reply label' => { + message => q{Reply}, + lastUpdated => 1119068809 + }, + + 'delete label' => { + message => q{Delete}, + lastUpdated => 1119068809 + }, + + 'cancel label' => { + message => q{Cancel}, + lastUpdated => 1119068809 + }, + + 'back label' => { + message => q{Back to Inbox}, + lastUpdated => 1119068809 + }, + + 'new message label' => { + message => q{New Message}, + lastUpdated => 1119068809 + }, + + 'send label' => { + message => q{Send}, + lastUpdated => 1181019679, + }, + + 'no access' => { + message => q{You do not have permission to view this message.}, + lastUpdated => 1119068809 + }, + + 'no reply error' => { + message => q{You do not have permission to reply to this message.}, + lastUpdated => 1119068809 + }, + + 'system message error' => { + message => q{This message was sent by the system and cannot be replied to}, + lastUpdated => 1119068809 + }, + + 'message does not exist' => { + message => q{The message you are trying to view has been deleted.}, + lastUpdated => 1119068809 + }, + + 'message count' => { + message => q{messages}, + lastUpdated => 1119068809 + }, + + 'compose message label' => { + message => q{Compose new message}, + lastUpdated => 1119068809 + }, + + 'reply message label' => { + message => q{Reply to message}, + lastUpdated => 1119068809 + }, + + 'no self error' => { + message => q|You may not send messages to yourself.|, + lastUpdated => 1181019679, + }, + + 'no friends error' => { + message => q{You do not have any active friends in the system. If you wish to send a new private message to a user without having to locate their profile, you must first add them as a friend.}, + lastUpdated => 1181019679, + }, + + 'no friends hover' => { + message => q{You must have active friends in the system if you wish to send new private messages without having to first locate their profile}, + lastUpdated => 1181019679, + }, + + 'no subject error' => { + message => q{You have not entered a subject for this message}, + lastUpdated => 1181019679, + }, + + 'no message error' => { + message => q{You have not entered a message}, + lastUpdated => 1181019679, + }, + + 'no user error' => { + message => q{You have not selected anyone to send this message to}, + lastUpdated => 1181019679, + }, + + 'blocked error' => { + message => q|This user does not wish to receive private messages.|, + lastUpdated => 1181019679, + }, + + 'remove text' => { + message => q{remove}, + lastUpdated => 1181019679, + }, + + 'update label' => { + message => q{Update}, + lastUpdated => 1181019679, + }, + + 'message sent label' => { + message => q{Message Sent}, + lastUpdated => 1181019679, + }, + + 'message sent text' => { + message => q{Your message has been sent successfully}, + lastUpdated => 1181019679, + }, + }; 1; diff --git a/lib/WebGUI/i18n/English/Account_Profile.pm b/lib/WebGUI/i18n/English/Account_Profile.pm index 621e24fde..27153da32 100644 --- a/lib/WebGUI/i18n/English/Account_Profile.pm +++ b/lib/WebGUI/i18n/English/Account_Profile.pm @@ -15,17 +15,17 @@ our $I18N = { }, 'profile style template hoverHelp' => { - message => q|Select a style template from the list to enclose your Wobject if it is viewed directly. If the Wobject is displayed as part of a Layout Asset, the Layout Asset's Style Template is used instead.|, + message => q|Select a style template from the list to enclose the inbox in.|, lastUpdated => 1119068809 }, 'profile layout template label' => { - message => q|Layout Template|, + message => q|Edit Layout Template|, lastUpdated => 1119068809 }, 'profile layout template hoverHelp' => { - message => q|Choose a layout from the list to display the various account pluggins and the contents of the one currently chosen|, + message => q{Choose a layout from the list to display the various account pluggins that are editable by the current user as well as the contents of the one currently chosen}, lastUpdated => 1119068809 }, @@ -48,6 +48,71 @@ our $I18N = { message => q|Choose the main template for editing a profile|, lastUpdated => 1119068809 }, + + 'profile edit layout template label' => { + message => q{Display Layout Template}, + lastUpdated => 1119068809 + }, + + 'profile edit layout template hoverHelp' => { + message => q{Choose a layout from the list to display the various account pluggins that are viewable by others as well as the contents of the one currently chosen}, + lastUpdated => 1119068809 + }, + + 'required error' => { + message => q|%s is required.|, + lastUpdated => 1031514049 + }, + + 'language not installed error' => { + message => q|%s is not installed. Please select another language|, + lastUpdated => 1031514049 + }, + + 'email already in use error' => { + message => q|The email address is already in use. Please use a different email address.|, + lastUpdated => 1068703399 + }, + + 'visitor profile restricted' => { + message => q|The visitor profile is restricted|, + lastUpdated => 1068703399 + }, + + 'edit my profile' => { + message => q|edit my profile|, + lastUpdated => 1068703399 + }, + + 'view my profile' => { + message => q|view my profile|, + lastUpdated => 1068703399 + }, + + 'profile as others label' => { + message => q{view my profile as others see it}, + lastUpdated => 1119068809 + }, + + 'member since' => { + message => q{Member Since }, + lastUpdated => 1119068809 + }, + + 'send private message label' => { + message => q{Send Private Message}, + lastUpdated => 1119068809 + }, + + 'send friend request label' => { + message => q{Send Friend Request}, + lastUpdated => 1119068809 + }, + + 'back label' => { + message => q{go back}, + lastUpdated => 1119068809 + } }; 1; diff --git a/lib/WebGUI/i18n/English/WebGUI.pm b/lib/WebGUI/i18n/English/WebGUI.pm index f58144ee1..68abf64aa 100644 --- a/lib/WebGUI/i18n/English/WebGUI.pm +++ b/lib/WebGUI/i18n/English/WebGUI.pm @@ -188,6 +188,11 @@ our $I18N = { lastUpdated => 1031514049 }, + 'home info short' => { + message => q|Home|, + lastUpdated => 1031514049 + }, + '118' => { message => q|Anonymous Registration|, lastUpdated => 1031514049 @@ -617,6 +622,11 @@ our $I18N = { lastUpdated => 1031514049 }, + 'demographic info short' => { + message => q|Demographic|, + lastUpdated => 1031514049 + }, + '39' => { message => q|You do not have sufficient privileges to access this page.|, lastUpdated => 1031514049 @@ -835,6 +845,11 @@ to add or remove users from their groups. lastUpdated => 1031514049 }, + 'preferences short' => { + message => q|Preferences|, + lastUpdated => 1031514049 + }, + '1026' => { message => q|Allow rich edit?|, lastUpdated => 1065966219 @@ -1247,6 +1262,11 @@ You must be using mod_perl and configure PerlSetEnv SYBASE /opt/sybase/11.0.2 message => q|Miscellaneous Information|, lastUpdated => 1031514049 }, + + 'misc info short' => { + message => q|Miscellaneous|, + lastUpdated => 1031514049 + }, '967' => { message => q|Empty everyone's trash.|, @@ -1516,6 +1536,11 @@ sent in HTML format. No attachments can be included.|, lastUpdated => 1031514049 }, + 'work info short' => { + message => q|Work|, + lastUpdated => 1031514049 + }, + '429' => { message => q|Login Time|, lastUpdated => 1031514049 @@ -1906,6 +1931,11 @@ This group could then be named "Employees in HMO 1", and would allow you to rest lastUpdated => 1031514049 }, + 'contact info short' => { + message => q|Contact Info|, + lastUpdated => 1031514049 + }, + '230' => { message => q|Message|, lastUpdated => 1031514049 @@ -2247,6 +2277,11 @@ This group could then be named "Employees in HMO 1", and would allow you to rest lastUpdated => 1031514049 }, + 'personal info short' => { + message => q|Personal|, + lastUpdated => 1031514049 + }, + '317' => { message => q|ICQ UIN|, lastUpdated => 1031514049 @@ -3539,6 +3574,11 @@ LongTruncOk=1

message => q|Read|, lastUpdated => 1181019679, }, + + 'inbox message status active' => { + message => q|Active|, + lastUpdated => 1181019679, + }, 'private message prev label' => { message => q|Previous|, diff --git a/lib/WebGUI/i18n/English/WebGUIProfile.pm b/lib/WebGUI/i18n/English/WebGUIProfile.pm index 5d4e671d6..09387ffa1 100644 --- a/lib/WebGUI/i18n/English/WebGUIProfile.pm +++ b/lib/WebGUI/i18n/English/WebGUIProfile.pm @@ -17,6 +17,16 @@ our $I18N = { lastUpdated => 1031514049 }, + 'category short name' => { + message => q|Category Short Name|, + lastUpdated => 1031514049 + }, + + 'category short name description' => { + message => q|The short name of the this category.|, + lastUpdated => 1122315199, + }, + '475' => { message => q|Field Name|, lastUpdated => 1031514049 diff --git a/www/extras/FileUploadControl.js b/www/extras/FileUploadControl.js index 53e6ece14..687254f73 100755 --- a/www/extras/FileUploadControl.js +++ b/www/extras/FileUploadControl.js @@ -85,7 +85,7 @@ function FileUploadControl_swapImage(firedobj) { var img = row.childNodes[0].childNodes[0]; img.src = imgPath; img.style.visibility="visible"; - img.alt = alternate; + img.alt = alternative; } //removes a row from the control From aec93573f02acbbf362bb73eac893c18543a2a96 Mon Sep 17 00:00:00 2001 From: Doug Bell Date: Fri, 14 Nov 2008 20:29:05 +0000 Subject: [PATCH 5/8] added test --- t/Account.t | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 t/Account.t diff --git a/t/Account.t b/t/Account.t new file mode 100644 index 000000000..7b67756d6 --- /dev/null +++ b/t/Account.t @@ -0,0 +1,76 @@ +# vim:syntax=perl +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2008 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 +#------------------------------------------------------------------ + +# This tests the operation of WebGUI::Account modules. You can use +# as a base to test your own modules. + +use FindBin; +use strict; +use lib "$FindBin::Bin/lib"; +use Test::More; +use WebGUI::Test; # Must use this before any other WebGUI modules +use WebGUI::Session; + +#---------------------------------------------------------------------------- +# Init +my $session = WebGUI::Test->session; + + +#---------------------------------------------------------------------------- +# Tests + +plan tests => 7; # Increment this number for each test you create + +#---------------------------------------------------------------------------- +# Test the creation of WebGUI::Account + +# Can we load WebGUI::Account? +use_ok( "WebGUI::Account" ); + +SKIP: { # Not everyone has Test::Exception yet + eval { require Test::Exception; import Test::Exception }; + # Skip 1 test if Test::Exception couldn't be loaded + skip 1, 'Test::Exception not found' if $@; + throws_ok( sub { WebGUI::Account->new }, 'WebGUI::Error::InvalidObject', + 'new() throws exception without session object' + ); +}; + +my $account; +# ok() tests booleans. assignment evaluates to the value assigned (it's how '$a = $b = 4' works) +ok( $account = WebGUI::Account->new( $session ), + "WebGUI::Account object created successfully" +); + +# Test $account->isa +isa_ok( $account, "WebGUI::Account", 'Blessed into the right class' ); + +#---------------------------------------------------------------------------- +# Test getUrl + +is( $account->getUrl, $session->url->page('op=account;module=;do='), + 'getUrl adds op, module, and do' +); + +is( $account->getUrl( 'foo=bar' ), $session->url->page( 'op=account;foo=bar' ), + 'getUrl adds op if passed other parameters' +); + +is( $account->getUrl( 'op=account' ), $session->url->page( 'op=account' ), + 'getUrl doesnt add op=account if already exists' +); + +#---------------------------------------------------------------------------- +# Cleanup +END { + +} +#vim:ft=perl From 11d18075fac0910ad1583f6ca5c623471ad1be1a Mon Sep 17 00:00:00 2001 From: Frank Dillon Date: Sat, 15 Nov 2008 02:39:23 +0000 Subject: [PATCH 6/8] Account release candidate - final changes before merge --- docs/upgrades/upgrade_7.6.1-7.6.2.pl | 59 +- lib/WebGUI/Account.pm | 266 +++++++- lib/WebGUI/Account/Friends.pm | 487 +++++++++++++- lib/WebGUI/Account/Inbox.pm | 331 +++++++++- lib/WebGUI/Account/Profile.pm | 195 ++---- lib/WebGUI/Account/Shop.pm | 297 +++++++++ lib/WebGUI/Account/User.pm | 67 +- lib/WebGUI/Account/_NewModule.skeleton | 145 +++++ lib/WebGUI/Asset/Post.pm | 4 +- lib/WebGUI/Asset/Shortcut.pm | 2 +- lib/WebGUI/Auth.pm | 30 +- lib/WebGUI/Auth/LDAP.pm | 47 +- lib/WebGUI/Auth/WebGUI.pm | 13 +- lib/WebGUI/Content/Account.pm | 161 ++--- lib/WebGUI/Form/File.pm | 8 - lib/WebGUI/Friends.pm | 74 ++- lib/WebGUI/Inbox.pm | 22 +- lib/WebGUI/Inbox/Message.pm | 12 +- lib/WebGUI/Macro/FileUrl.pm | 13 +- lib/WebGUI/Macro/NewMail.pm | 2 +- lib/WebGUI/Macro/User.pm | 27 +- lib/WebGUI/Operation.pm | 7 - lib/WebGUI/Operation/Friends.pm | 346 +--------- lib/WebGUI/Operation/Inbox.pm | 318 +-------- lib/WebGUI/Operation/Profile.pm | 204 ++---- lib/WebGUI/Operation/Settings.pm | 74 +-- lib/WebGUI/Operation/Shared.pm | 65 +- lib/WebGUI/ProfileField.pm | 14 +- lib/WebGUI/Shop/Transaction.pm | 9 +- lib/WebGUI/Storage.pm | 5 +- lib/WebGUI/User.pm | 140 +++- lib/WebGUI/i18n/English/Account_Friends.pm | 238 +++++++ lib/WebGUI/i18n/English/Account_Inbox.pm | 84 ++- lib/WebGUI/i18n/English/Account_Profile.pm | 71 +- lib/WebGUI/i18n/English/Account_Shop.pm | 40 ++ lib/WebGUI/i18n/English/Account_User.pm | 27 +- lib/WebGUI/i18n/English/WebGUI.pm | 12 +- www/extras/account/account.css | 724 +++++++++++++++++++++ www/extras/account/images/new.png | Bin 0 -> 452 bytes www/extras/account/images/next.gif | Bin 0 -> 857 bytes www/extras/account/images/no_photo.gif | Bin 0 -> 390 bytes www/extras/account/images/old.png | Bin 0 -> 536 bytes www/extras/account/images/prev.gif | Bin 0 -> 170 bytes www/extras/account/images/save_changes.gif | Bin 0 -> 1589 bytes www/extras/account/inbox.js | 64 ++ 45 files changed, 3379 insertions(+), 1325 deletions(-) create mode 100644 lib/WebGUI/Account/Shop.pm create mode 100644 lib/WebGUI/Account/_NewModule.skeleton create mode 100644 lib/WebGUI/i18n/English/Account_Shop.pm create mode 100644 www/extras/account/account.css create mode 100644 www/extras/account/images/new.png create mode 100644 www/extras/account/images/next.gif create mode 100644 www/extras/account/images/no_photo.gif create mode 100644 www/extras/account/images/old.png create mode 100644 www/extras/account/images/prev.gif create mode 100644 www/extras/account/images/save_changes.gif create mode 100644 www/extras/account/inbox.js diff --git a/docs/upgrades/upgrade_7.6.1-7.6.2.pl b/docs/upgrades/upgrade_7.6.1-7.6.2.pl index 7cae6ebd9..6f564de79 100644 --- a/docs/upgrades/upgrade_7.6.1-7.6.2.pl +++ b/docs/upgrades/upgrade_7.6.1-7.6.2.pl @@ -80,6 +80,11 @@ sub upgradeAccount { title => "^International(title,Account_Friends);", className => "WebGUI::Account::Friends" }, + { + identifier => "shop", + title => "^International(title,Account_Shop);", + className => "WebGUI::Account::Shop" + }, { identifier => "user", title => "^International(title,Account_User);", @@ -100,23 +105,44 @@ sub upgradeAccount { $session->config->set( "contentHandlers", \@newHandlers ); } - #Add the settings for the profile + #Add the settings for the profile module $setting->add("profileStyleTemplateId",""); #Use the userStyle by default $setting->add("profileLayoutTemplateId","N716tpSna0iIQTKxS4gTWA"); $setting->add("profileEditLayoutTemplateId","FJbUTvZ2nUTn65LpW6gjsA"); $setting->add("profileEditTemplateId","75CmQgpcCSkdsL-oawdn3Q"); $setting->add("profileViewTempalteId","2CS-BErrjMmESOtGT90qOg"); + $setting->add("profileErrorTempalteId","MBmWlA_YEA2I6D29OMGtRg"); - #Add the settings for the inbox + #Add the settings for the inbox module $setting->add("inboxStyleTemplateId",""); #Use the userStyle by default $setting->add("inboxLayoutTempalteId","N716tpSna0iIQTKxS4gTWA"); $setting->add("inboxViewTemplateId","c8xrwVuu5QE0XtF9DiVzLw"); $setting->add("inboxViewMessageTemplateId","0n4HtbXaWa_XJHkFjetnLQ"); $setting->add("inboxSendMessageTemplateId","6uQEULvXFgCYlRWnYzZsuA"); $setting->add("inboxErrorTemplateId","ErEzulFiEKDkaCDVmxUavw"); - $setting->add("inboxInvitationErrorTemplateId","5A8Hd9zXvByTDy4x-H28qw"); $setting->add("inboxMessageConfirmationTemplateId","DUoxlTBXhVS-Zl3CFDpt9g"); + #Invitations $setting->add("inboxManageInvitationsTemplateId","1Q4Je3hKCJzeo0ZBB5YB8g"); + $setting->add("inboxViewInvitationTemplateId","VBkY05f-E3WJS50WpdKd1Q"); + $setting->add("inboxInvitationConfirmTemplateId","5A8Hd9zXvByTDy4x-H28qw"); + + #Add the settings for the friends module + $setting->add("friendsStyleTemplateId",""); #Use the userStyle by default + $setting->add("friendsLayoutTempalteId","N716tpSna0iIQTKxS4gTWA"); + $setting->add("friendsViewTemplateId","1Yn_zE_dSiNuaBGNLPbxtw"); + $setting->add("friendsEditTemplateId","AZFU33p0jpPJ-E6qLSWZng"); + $setting->add("friendsSendRequestTemplateId","AGJBGviWGAwjnwziiPjvDg"); + $setting->add("friendsErrorTemplateId","7Ijdd8SW32lVgg2H8R-Aqw"); + $setting->add("friendsConfirmTemplateId","K8F0j_cq_jgo8dvWY_26Ag"); + $setting->add("friendsRemoveConfirmTemplateId","G5V6neXIDiFXN05oL-U3AQ"); + + #Add the settings for the user module + $setting->add("userAccountStyleTemplateId",""); #Use the userStyle by default + $setting->add("userAccountLayoutTemplateId","9ThW278DWLV0-Svf68ljFQ"); + + #Add the settings for the shop module + $setting->add("shopStyleTemplateId",""); #Use the userStyle by default + $setting->add("shopLayoutTemplateId","aUDsJ-vB9RgP-AYvPOy8FQ"); #Add inbox changes $session->db->write(q{ @@ -179,6 +205,33 @@ sub upgradeAccount { $session->db->write(q{update userProfileCategory set shortLabel='WebGUI::International::get("work info short","WebGUI");' where profileCategoryId='6'}); $session->db->write(q{update userProfileCategory set shortLabel='WebGUI::International::get("demographic info short","WebGUI");' where profileCategoryId='7'}); + $session->db->write(q{alter table userProfileData modify publicProfile char(10) default 'none'}); + $session->db->write(q{update userProfileData set publicProfile='none' where publicProfile='0' || publicProfile is NULL || publicProfile=''}); + $session->db->write(q{update userProfileData set publicProfile='all' where publicProfile='1'}); + $session->db->write(q{REPLACE INTO `userProfileField` VALUES ('publicProfile','WebGUI::International::get(861)',1,0,'RadioList','{ all=>WebGUI::International::get(\'public label\',\'Account_Profile\'), friends=>WebGUI::International::get(\'friends only label\',\'Account_Profile\'), none=>WebGUI::International::get(\'private label\',\'Account_Profile\')}','[\"none\"]',8,'4',1,1,0,0,0,'')}) + + + #Clean up old templates and settings + my $oldtemplates = { + editUserProfileTemplate => 'Operation/Profile/Edit', + viewUserProfileTemplate => 'Operation/Profile/View', + manageFriendsTemplateId => 'friends/manage', + sendPrivateMessageTemplateId => 'Inbox/SendPrivateMessage', + viewInboxTemplateId => 'Inbox', + viewInboxMessageTemplateId => 'Inbox/Message', + }; + + foreach my $setting (keys %{$oldtemplates}) { + #Remove the setting + $session->db->write("delete from settings where name=?",[$setting]); + #Remove all the templates with the related namespace + my $assets = $session->db->buildArrayRef("select distinct assetId from template where namespace=?",[$oldtemplates->{$setting}]); + #Purge the template + foreach my $assetId (@{$assets}) { + WebGUI::Asset->newByDynamicClass($session,$assetId)->purge; + } + } + print "DONE!\n" unless $quiet; } diff --git a/lib/WebGUI/Account.pm b/lib/WebGUI/Account.pm index 82cc50d6a..3f1901ff6 100644 --- a/lib/WebGUI/Account.pm +++ b/lib/WebGUI/Account.pm @@ -4,6 +4,7 @@ use strict; use Class::InsideOut qw{ :std }; use WebGUI::Exception; +use Carp qw(croak); use WebGUI::International; use WebGUI::Pluggable; use WebGUI::Utility; @@ -29,7 +30,254 @@ These subroutines are available from this package: =cut readonly session => my %session; -public store => my %store; #This is an all purpose hash to store stuff in: $store{id $self}->{something} = "something" +readonly module => my %module; +public method => my %method; +public uid => my %uid; +public store => my %store; #This is an all purpose hash to store stuff in: $store{id $self}->{something} = "something" + +#------------------------------------------------------------------- + +=head2 appendAccountLinks ( session , var) + + Class method which appends common links to preform various account tasks + +=head3 session + + WebGUI::Session object + +=head3 var + + hash ref to append template variables to + +=cut + +sub appendAccountLinks { + my $class = shift; + my $session = shift; + my $var = shift; + + return unless $var; + + my $i18n = WebGUI::International->new($session); + my $format = q{%s}; + my @array = (); + + #Turn Admin On + if ($session->user->isInGroup(12)) { + if ($session->var->isAdminOn) { + $var->{'admin_mode_url' } = $session->url->page('op=switchOffAdmin'); + $var->{'admin_mode_text'} = $i18n->get(12); + } + else { + $var->{'admin_mode_url' } = $session->url->page('op=switchOnAdmin'); + $var->{'admin_mode_text'} = $i18n->get(63); + } + push(@array,{ + 'options.display' => sprintf($format,$var->{'admin_mode_url'},$var->{'admin_mode_text'}) + }); + } + + #Pluggin - delete eventually + push(@array, {'options.display' => ''.$i18n->get('my purchases', 'Shop').''}); + + #Pluggin - delete eventually + if ($session->setting->get('userInvitationsEnabled')) { + push @array, { + 'options.display' => sprintf('%s', $session->url->page('op=inviteUser'), $i18n->get('invite a friend')), + }; + } + + #Logout + $var->{'logout_url' } = $session->url->page('op=auth;method=logout'); + $var->{'logout_text'} = $i18n->get(64); + push(@array,{ + 'options.display' => sprintf($format,$var->{'logout_url'},$var->{'logout_text'}) + }); + + #Deactivate Account + if ($session->setting->get("selfDeactivation") && !$session->user->isAdmin){ + $var->{'self_deactivation_url' } = $session->url->page('op=auth;method=deactivateAccount'); + $var->{'self_deactivation_text'} = $i18n->get(65); + push(@array,{ + 'options.display' => sprintf($format,$var->{'self_deactivation_url' },$var->{'self_deactivation_text'}) + }); + } + + #Return to site + $var->{'return_to_site_url' } = $session->url->getBackToSiteURL; + $var->{'return_to_site_link'} = $i18n->get(493); + push(@array,{ + 'options.display' => sprintf($format,$var->{'return_to_site_url'},$var->{'return_to_site_link'}) + }); + + $var->{'account.options'} = \@array; +} + + +#------------------------------------------------------------------- + +=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 = $session->user; + + $var->{'user_full_name' } = $user->getWholeName; + $var->{'user_member_since' } = $user->dateCreated; + $var->{'view_profile_url' } = $user->getProfileUrl; + $var->{'gateway_url' } = $session->url->page("op=account"); + $var->{'back_url' } = $session->env->get("HTTP_REFERER") || $var->{'view_profile_url'} +} + + +#------------------------------------------------------------------- + +=head2 callMethod ( [ method, args, uid ] ) + +Calls the method passed in + +=method + +Method to call. If no method is passed in, the view method is called + +=args + +array reference of arguments to pass to the method being called. + +=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; + + $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; + } + + #Set the method in the object + $self->method($method); + #Set the uid in the object + $self->uid($uid); + + #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 + +=content + +Content to wrap in the pluggin style and layout + +=withoutStyle + +Return the layout without the style wrapper + +=cut + +sub displayContent { + my $self = shift; + my $content = shift; + my $noStyle = shift; + my $session = $self->session; + + #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}; + my $identifier = $account->{identifier}; + + $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(\$hash{'title'}); + push(@pluggins,\%hash); + + #Append common display variables to the main template + $instance->appendCommonVars($var); + } + $var->{'account_loop'} = \@pluggins; + + #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); +} + #------------------------------------------------------------------- @@ -130,10 +378,10 @@ sub getUrl { } } else { - $pairs = q{op=account;module=}.$form->get("module").q{;do=}.$form->get("do"); + $pairs = q{op=account;module=}.$self->module.q{;do=}.$self->method; } - my $uid = $form->get("uid"); + my $uid = $self->uid; $pairs .= ";uid=".$uid if($appendUID && $uid); return $session->url->page($pairs); @@ -141,7 +389,7 @@ sub getUrl { #------------------------------------------------------------------- -=head2 new ( $session ) +=head2 new ( session, module [,method ,uid] ) Constructor. @@ -149,11 +397,16 @@ Constructor. 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( @@ -165,8 +418,13 @@ sub new { my $self = register $class; my $id = id $self; + $session { $id } = $session; + $module { $id } = $module; $store { $id } = {}; + $method { $id } = "view"; + $uid { $id } = undef; + return $self; } diff --git a/lib/WebGUI/Account/Friends.pm b/lib/WebGUI/Account/Friends.pm index 77e4fe034..68ecf8d89 100644 --- a/lib/WebGUI/Account/Friends.pm +++ b/lib/WebGUI/Account/Friends.pm @@ -26,6 +26,52 @@ These subroutines are available from this package: =cut +#------------------------------------------------------------------- + +=head2 appendCommonVars ( var ) + + Appends common template variables that all inbox templates 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 = $session->user; + my $pageUrl = $session->url->page; + + $var->{'user_full_name' } = $user->getWholeName; + $var->{'user_member_since' } = $user->dateCreated; + $var->{'view_profile_url' } = $user->getProfileUrl($pageUrl); + $var->{'edit_profile_url' } = $session->url->page("op=account"); + $var->{'back_url' } = $session->env->get("HTTP_REFERER") || $var->{'view_profile_url'} +} + +#------------------------------------------------------------------- + +=head2 canView ( ) + + Whether or not the current user can view this user's friends + +=cut + +sub canView { + my $self = shift; + my $session = $self->session; + my $uid = $self->uid; + + return 1 if (($session->user->userId eq $uid || $uid eq "") && $session->user->profileField('ableToBeFriend')); + + my $user = WebGUI::User->new($session,$uid); + return 0 if($user->isVisitor); #This should never happen but let's make sure + return 0 unless ($user->profileField('ableToBeFriend')); #User doesn't have friends enabled + return WebGUI::User->new($session,$uid)->profileIsViewable($session->user); #User's profile isn't viewable by this user +} #------------------------------------------------------------------- @@ -38,17 +84,68 @@ These subroutines are available from this package: sub editSettingsForm { my $self = shift; my $session = $self->session; - my $setting = $session->setting; my $i18n = WebGUI::International->new($session,'Account_Friends'); my $f = WebGUI::HTMLForm->new($session); -# $f->template( -# name => "profileStyleTemplateId", -# value => $self->getStyleTemplateId, -# namespace => "style", -# label => $i18n->get("profile style template label"), -# hoverHelp => $i18n->get("profile style template hoverHelp") -# ); + $f->template( + name => "friendsStyleTemplateId", + value => $self->getStyleTemplateId, + namespace => "style", + label => $i18n->get("friends style template label"), + hoverHelp => $i18n->get("friends style template hoverHelp") + ); + $f->template( + name => "friendsLayoutTempalteId", + value => $self->getLayoutTemplateId, + namespace => "Account/Layout", + label => $i18n->get("friends layout template label"), + hoverHelp => $i18n->get("friends layout template hoverHelp") + ); + $f->template( + name => "friendsViewTemplateId", + value => $self->getViewTemplateId, + namespace => "Account/Friends/View", + label => $i18n->get("friends view template label"), + hoverHelp => $i18n->get("friends view template hoverHelp") + ); + $f->template( + name => "friendsEditTemplateId", + value => $self->getEditTemplateId, + namespace => "Account/Friends/Edit", + label => $i18n->get("friends edit template label"), + hoverHelp => $i18n->get("friends edit template hoverHelp") + ); + $f->template( + name => "friendsSendRequestTemplateId", + value => $self->getSendRequestTemplateId, + namespace => "Account/Friends/SendRequest", + label => $i18n->get("friends send request template label"), + hoverHelp => $i18n->get("friends send request template hoverHelp") + ); + + $f->template( + name => "friendsErrorTemplateId", + value => $self->getErrorTemplateId, + namespace => "Account/Friends/Error", + label => $i18n->get("friends error template label"), + hoverHelp => $i18n->get("friends error template hoverHelp") + ); + + $f->template( + name => "friendsConfirmTemplateId", + value => $self->getConfirmTemplateId, + namespace => "Account/Friends/Confirm", + label => $i18n->get("friends confirm template label"), + hoverHelp => $i18n->get("friends confirm template hoverHelp") + ); + + $f->template( + name => "friendsRemoveConfirmTemplateId", + value => $self->getRemoveConfirmTemplateId, + namespace => "Account/Friends/Confirm", + label => $i18n->get("friends remove confirm template label"), + hoverHelp => $i18n->get("friends remove confirm template hoverHelp") + ); return $f->printRowsOnly; } @@ -62,19 +159,60 @@ sub editSettingsForm { =cut sub editSettingsFormSave { + my $self = shift; + my $session = $self->session; + my $setting = $session->setting; + my $form = $session->form; + + $setting->set("friendsStyleTemplateId", $form->process("friendsStyleTemplateId","template")); + $setting->set("friendsLayoutTempalteId", $form->process("friendsLayoutTempalteId","template")); + $setting->set("friendsViewTemplateId", $form->process("friendsViewTemplateId","template")); + $session->set("friendsEditTemplateId",$form->process("friendsEditTemplateId","template")); + $session->set("friendsSendRequestTemplateId",$form->process("friendsSendRequestTemplateId","template")); + $session->set("friendsErrorTemplateId",$form->process("friendsErrorTemplateId","template")); + $session->set("friendsConfirmTemplateId",$form->process("friendsConfirmTemplateId","template")); + $session->set("friendsRemoveConfirmTemplateId",$form->process("friendsRemoveConfirmTemplateId","template")); + } #------------------------------------------------------------------- -=head2 getDisplayTemplateId ( ) +=head2 getConfirmTemplateId ( ) -This method returns the template ID for the account layout. +This method returns the template ID for the confirmation screen. =cut -sub getDisplayTemplateId { +sub getConfirmTemplateId { my $self = shift; - return $self->session->setting->get("friendsDisplayTempalteId") || "defaultAssetId"; + return $self->session->setting->get("friendsConfirmTemplateId") || "K8F0j_cq_jgo8dvWY_26Ag"; +} + + +#------------------------------------------------------------------- + +=head2 getEditTemplateId ( ) + +This method returns the template ID for editing friends. + +=cut + +sub getEditTemplateId { + my $self = shift; + return $self->session->setting->get("friendsEditTemplateId") || "AZFU33p0jpPJ-E6qLSWZng"; +} + +#------------------------------------------------------------------- + +=head2 getErrorTemplateId ( ) + +This method returns the template ID for displaying errors. + +=cut + +sub getErrorTemplateId { + my $self = shift; + return $self->session->setting->get("friendsErrorTemplateId") || "7Ijdd8SW32lVgg2H8R-Aqw"; } #------------------------------------------------------------------- @@ -91,6 +229,33 @@ sub getLayoutTemplateId { } +#------------------------------------------------------------------- + +=head2 getConfirmTemplateId ( ) + +This method returns the template ID for the confirmation screen. + +=cut + +sub getRemoveConfirmTemplateId { + my $self = shift; + return $self->session->setting->get("friendsRemoveConfirmTemplateId") || "G5V6neXIDiFXN05oL-U3AQ"; +} + + +#------------------------------------------------------------------- + +=head2 getSendRequestTemplateId ( ) + +This method returns the template ID for the send request page. + +=cut + +sub getSendRequestTemplateId { + my $self = shift; + return $self->session->setting->get("friendsSendRequestTemplateId") || "AGJBGviWGAwjnwziiPjvDg"; +} + #------------------------------------------------------------------- =head2 getStyleTemplateId ( ) @@ -114,40 +279,310 @@ This method returns the template ID for the main view. sub getViewTemplateId { my $self = shift; - return $self->session->setting->get("friendsViewTemplateId") || "defaultAssetId"; + return $self->session->setting->get("friendsViewTemplateId") || "1Yn_zE_dSiNuaBGNLPbxtw"; +} + + +#------------------------------------------------------------------- + +=head2 www_removeFriend ( ) + +This is a confirmation page of whether or not the user wishes to remove the selected user from friend + +=cut + +sub www_removeFriend { + my $self = shift; + my $session = $self->session; + my $friendId = $session->form->get("friendId"); + my $var = {}; + + $self->appendCommonVars($var); + my $friend = WebGUI::Friends->new($session); + + my $errorMsg = ""; + if (!$friendId) { + my $i18n = WebGUI::International->new($session,"Account_Friends"); + $errorMsg = $i18n->get("no friend selected"); + } + elsif(!$friend->isFriend($friendId)){ + my $i18n = WebGUI::International->new($session,"Account_Friends"); + $errorMsg = $i18n->get("not a friend error"); + } + + if($errorMsg ne "") { + my $backUrl = $self->getUrl("module=friends"); + return $self->showError($var,$errorMsg,$backUrl,$self->getErrorTemplateId); + } + + my $user = WebGUI::User->new($session,$friendId); + $var->{'user_full_name'} = $user->getWholeName; + + $var->{'yes_url' } = $self->getUrl("module=friends;do=removeFriendConfirm;friendId=".$friendId); + $var->{'no_url' } = $self->getUrl("module=friends"); + + return $self->processTemplate($var,$self->getRemoveConfirmTemplateId); +} + + +#------------------------------------------------------------------- + +=head2 www_removeFriend ( ) + +This is a confirmation page of whether or not the user wishes to remove the selected user from friend + +=cut + +sub www_removeFriendConfirm { + my $self = shift; + my $session = $self->session; + my $friendId = $session->form->get("friendId"); + my $var = {}; + my $i18n = WebGUI::International->new($session,"Account_Friends"); + + + $self->appendCommonVars($var); + my $friend = WebGUI::Friends->new($session); + + my $errorMsg = ""; + if (!$friendId) { + $errorMsg = $i18n->get("no friend selected"); + } + elsif(!$friend->isFriend($friendId)){ + $errorMsg = $i18n->get("not a friend error"); + } + + if($errorMsg ne "") { + my $backUrl = $self->getUrl("module=friends"); + return $self->showError($var,$errorMsg,$backUrl,$self->getErrorTemplateId); + } + + my $user = WebGUI::User->new($session,$friendId); + my $msg = sprintf($i18n->get("friend removed"),$user->getWholeName); + + $friend->delete([$friendId]); + + return $self->www_view($msg); + } #------------------------------------------------------------------- -=head2 www_display ( ) +=head2 www_sendFriendsRequest ( ) -The main view page for displaying the user's profile. +The page which allows users to submit friends requests. =cut -sub www_display { - my $self = shift; - my $session = $self->session; - my $var = {}; +sub www_sendFriendsRequest { + my $self = shift; + my $session = $self->session; + my $var = {}; + my $uid = $self->uid; + + my $user = WebGUI::User->new($session,$uid); + my $i18n = WebGUI::International->new($session,'Account_Friends'); + + unless ($user->acceptsFriendsRequests($session->user)) { + my $errorMsg = $i18n->get('does not want to be a friend'); + my $friend = WebGUI::Friends->new($session); + if($friend->isFriend($uid)) { + $errorMsg = $i18n->get("error user is already friend"); + } + elsif($friend->isInvited($uid)) { + $errorMsg = $i18n->get("error user is already invited"); + } + return $self->showError($var,$errorMsg,$session->user->getProfileUrl,$self->getErrorTemplateId); + } + + $self->appendCommonVars($var); + + #Overwrite these + $var->{'user_full_name' } = $user->getWholeName; + $var->{'user_member_since' } = $user->dateCreated; + + my $defaultComment = sprintf( + $i18n->get('default friend comments'), + $user->getFirstName, + $session->user->getFirstName + ); + $var->{'form_message_text'} = WebGUI::Form::textarea($session, { + name =>"message", + value =>$defaultComment, + width =>600, + height =>200 + }); + + $var->{'form_message_rich'} = WebGUI::Form::HTMLArea($session, { + name => "message", + value => $defaultComment, + width => "600", + }); + + $var->{'form_header' } = WebGUI::Form::formHeader($session,{ + action => $self->getUrl("module=friends;do=sendFriendsRequestSave;uid=$uid"), + extras => q{name="messageForm"} + }); + + $var->{'submit_button' } = WebGUI::Form::submit($session,{}); + $var->{'form_footer' } = WebGUI::Form::formFooter($session, {}); + + $var->{'cancel_url' } = $user->getProfileUrl; + + return $self->processTemplate($var,$self->getSendRequestTemplateId); +} + + +#------------------------------------------------------------------- + +=head2 www_sendFriendsRequestSave ( ) + +This method allows users to save friends requests + +=cut + +sub www_sendFriendsRequestSave { + my $self = shift; + my $session = $self->session; + my $var = {}; + my $uid = $self->uid; + + my $user = WebGUI::User->new($session,$uid); + + #Errors fall through to the view page. + unless ($user->acceptsFriendsRequests($session->user)) { + return $self->www_sendFriendsRequest; + } + + my $inboxUrl = WebGUI::Account::Inbox->getViewInvitationUrl($session); + my $friends = WebGUI::Friends->new($session); + $friends->sendAddRequest($uid, $session->form->get('message'),$inboxUrl); + + $self->appendCommonVars($var); + + #Overwrite this + $var->{'user_full_name' } = $user->getWholeName; + $var->{'user_profile_url' } = $user->getProfileUrl; + + return $self->processTemplate($var,$self->getConfirmTemplateId); - return $self->processTemplate($var,$self->getDisplayTemplateId); } #------------------------------------------------------------------- =head2 www_view ( ) -The main view page for editing the user's profile. +The main view page for editing your friends. =cut sub www_view { - my $self = shift; - my $session = $self->session; - my $var = {}; + my $self = shift; + my $msg = shift; + my $session = $self->session; + my $var = {}; - return $self->processTemplate($var,$self->getViewTemplateId); + my $uid = $self->uid; + my $user = ($uid) ? WebGUI::User->new($session,$uid) : $session->user; + + $self->appendCommonVars($var); + + my $displayView = $uid ne ""; + $var->{'can_edit' } = $session->user->userId eq $user->userId; + $var->{'display_message'} = $msg; + + #Override these + $var->{'user_full_name' } = $user->getWholeName; + $var->{'user_member_since' } = $user->dateCreated; + + unless ($user->profileField('ableToBeFriend') && $user->profileIsViewable($session->user)) { + my $i18n = WebGUI::International->new($session,"Account_Friends"); + my $errorMsg = ""; + if($var->{'can_edit'}) { + $errorMsg = $i18n->get("friends is off"); + } + else { + $errorMsg = $i18n->get("no access"); + } + my $backUrl = $self->getUrl("op=account"); + return $self->showError($var,$errorMsg,$backUrl,$self->getErrorTemplateId); + } + + #Deal with rows per page + my $rpp = $session->form->get("rpp") || 25; + my $rpp_url = ";rpp=$rpp"; + + #Cache the base url + my $friendsUrl = $self->getUrl("op=account;module=friends;do=view"); + + #Note for anyone who attempts to sort this list by the user's whole name: + #You can do this, but the only way to do it efficiently is to join + #the users, userProfileData, and groupings table. This will break if the groups API + #changes in WebGUI 8, so we decided to leave it sorted by username only. + + #Create the paginator + my $friends = $user->friends->getUserList(1); + my @friendIds = keys %{$friends}; + my $p = WebGUI::Paginator->new( + $session, + $friendsUrl.$rpp_url, + $rpp + ); + $p->setDataByArrayRef(\@friendIds); + + #Export page to template + my @friends = (); + foreach my $friendId ( @{$p->getPageData} ) { + my $friend = WebGUI::User->new($session,$friendId); + next if($friend->isVisitor); + #If you have friends turned off you shouldn't show up when other people view your friends friends + next if($displayView && !$friend->profileField('ableToBeFriend')); + + my $hash = {}; + $hash->{'friend_full_name' } = $friend->getWholeName; + $hash->{'isViewable' } = $friend->profileIsViewable; + $hash->{'friend_id' } = $friend->userId; + $hash->{'friend_member_since' } = $friend->dateCreated; + $hash->{'friend_member_since_human'} = $session->datetime->epochToHuman($friend->dateCreated); + $hash->{'friend_isOnline' } = $friend->isOnline; + if($hash->{'isViewable'}) { + $hash->{'friend_profile_url'} = $friend->getProfileUrl; + if($friend->profileField("photo")) { + my $store = WebGUI::Storage::Image->get($session,$friend->profileField("photo")); + my $file = $store->getFiles->[0]; + $hash->{'friend_photo_url' } = $store->getUrl($file); + $hash->{'friend_photo_url_thumb'} = $store->getThumbnailUrl($file); + } + } + + $hash->{'acceptsPrivateMessages'} = $friend->acceptsPrivateMessages($session->user->userId); + if ($displayView) { + if($friend->acceptsFriendsRequests($session->user)) { + $hash->{'friend_request_url'} = $self->getUrl("module=friends;do=sendFriendsRequest;uid=".$friend->userId); + } + } + else { + $hash->{'remove_url'} = $self->getUrl("module=friends;do=removeFriend;friendId=".$friend->userId); + } + push(@friends,$hash); + } + my $friendCount = $p->getRowCount; + + $var->{'friends_loop' } = \@friends; + $var->{'has_friends' } = $friendCount > 0; + $var->{'friends_total' } = $friendCount; + + tie my %rpps, "Tie::IxHash"; + %rpps = (25 => "25", 50 => "50", 100=>"100"); + $var->{'message_rpp' } = WebGUI::Form::selectBox($session,{ + name =>"rpp", + options => \%rpps, + value => $session->form->get("rpp") || 25, + extras => q{onchange="location.href='}.$friendsUrl.q{;rpp='+this.options[this.selectedIndex].value"} + }); + + my $templateId = ($displayView) ? $self->getViewTemplateId : $self->getEditTemplateId; + return $self->processTemplate($var,$templateId); } - 1; diff --git a/lib/WebGUI/Account/Inbox.pm b/lib/WebGUI/Account/Inbox.pm index 7f36efd1f..f5b2fa181 100644 --- a/lib/WebGUI/Account/Inbox.pm +++ b/lib/WebGUI/Account/Inbox.pm @@ -46,17 +46,18 @@ These subroutines are available from this package: sub appendCommonVars { my $self = shift; - my $var = shift; - my $inbox = shift; my $session = $self->session; + my $var = shift; + my $inbox = shift || WebGUI::Inbox->new($session); my $user = $session->user; - $var->{'user_full_name' } = $user->getWholeName; - $var->{'user_member_since' } = $user->dateCreated; - $var->{'view_profile_url' } = $user->getProfileUrl; + $self->SUPER::appendCommonVars($var); + $var->{'view_inbox_url' } = $self->getUrl("module=inbox;do=view"); $var->{'view_invitations_url'} = $self->getUrl("module=inbox;do=manageInvitations"); $var->{'unread_message_count'} = $inbox->getUnreadMessageCount; + $var->{'invitation_count' } = $self->getInvitationCount; + $var->{'invitations_enabled' } = $session->user->profileField('ableToBeFriend'); } @@ -70,7 +71,7 @@ sub appendCommonVars { sub canView { my $self = shift; - return ($self->session->form->get("uid") eq ""); + return ($self->uid eq ""); } #------------------------------------------------------------------- @@ -145,11 +146,18 @@ sub editSettingsForm { hoverHelp => $i18n->get("inbox manage invitations template hoverHelp") ); $f->template( - name => "inboxInvitationErrorTemplateId", - value => $self->getInvitationErrorTemplateId, - namespace => "Account/Inbox/Error", - label => $i18n->get("invitation error message template label"), - hoverHelp => $i18n->get("invitation error message template hoverHelp") + name => "inboxViewInvitationTemplateId", + value => $self->getViewInvitationTemplateId, + namespace => "Account/Inbox/ViewInvitation", + label => $i18n->get("inbox view invitation template label"), + hoverHelp => $i18n->get("inbox view invitation template hoverHelp") + ); + $f->template( + name => "inboxInvitationConfirmTemplateId", + value => $self->getInvitationConfirmTemplateId, + namespace => "Account/Inbox/Confirm", + label => $i18n->get("invitation confirm message template label"), + hoverHelp => $i18n->get("invitation confirm message template hoverHelp") ); return $f->printRowsOnly; @@ -179,7 +187,8 @@ sub editSettingsFormSave { $session->set("inboxErrorTemplateId",$form->process("inboxErrorTemplateId","template")); #Invitations Settings $session->set("inboxManageInvitationsTemplateId",$form->process("inboxManageInvitationsTemplateId","template")); - $session->set("inboxInvitationErrorTemplateId",$form->process("inboxInvitationErrorTemplateId","template")); + $session->set("inboxViewInvitationTemplateId",$form->process("inboxViewInvitationTemplateId","template")); + $session->set("inboxInvitationConfirmTemplateId",$form->process("inboxInvitationConfirmTemplateId","template")); } #------------------------------------------------------------------- @@ -195,20 +204,37 @@ sub getInboxErrorTemplateId { return $self->session->setting->get("inboxErrorTemplateId") || "ErEzulFiEKDkaCDVmxUavw"; } +#------------------------------------------------------------------- + +=head2 getInvitationCount ( ) + +This method returns the total number of invitations in the invitation box. + +=cut + +sub getInvitationCount { + my $self = shift; + my $session = $self->session; + return $session->db->quickScalar( + q{select count(*) from friendInvitations where friendId=?}, + [$session->user->userId] + ); +} #------------------------------------------------------------------- -=head2 getInvitationErrorTemplateId ( ) +=head2 getInvitationConfirmTemplateId ( ) This method returns the template ID for invitation errors. =cut -sub getInvitationErrorTemplateId { +sub getInvitationConfirmTemplateId { my $self = shift; - return $self->session->setting->get("inboxInvitationErrorTemplateId") || "5A8Hd9zXvByTDy4x-H28qw"; + return $self->session->setting->get("inboxInvitationConfirmTemplateId") || "5A8Hd9zXvByTDy4x-H28qw"; } + #------------------------------------------------------------------- =head2 getLayoutTemplateId ( ) @@ -222,6 +248,7 @@ sub getLayoutTemplateId { return $self->session->setting->get("inboxLayoutTempalteId") || $self->SUPER::getLayoutTemplateId; } + #------------------------------------------------------------------- =head2 getManageInvitationsTemplateId ( ) @@ -295,6 +322,40 @@ sub getUserProfileUrl { return $self->store->{$userId}; } +#------------------------------------------------------------------- + +=head2 getViewInvitationTemplateId ( ) + +This method returns the id for the view message template. + +=cut + +sub getViewInvitationTemplateId { + my $self = shift; + return $self->session->setting->get("inboxViewInvitationTemplateId") || "VBkY05f-E3WJS50WpdKd1Q"; +} + +#------------------------------------------------------------------- + +=head2 getViewInvitationUrl ( session ) + +Class method which returns the base url for viewing invitations + +=head3 session + +session object + +=cut + +sub getViewInvitationUrl { + my $class = shift; + my $session = shift; + my $url = $session->url; + + return $url->append($url->getSiteURL,"op=account;module=inbox;do=viewInvitation"); +} + + #------------------------------------------------------------------- =head2 getViewMessageTemplateId ( ) @@ -323,6 +384,54 @@ sub getViewTemplateId { #------------------------------------------------------------------- +=head2 www_approveDenyInvitations ( ) + +Approves or denies invitations passed in. + +=cut + +sub www_approveDenyInvitations { + my $self = shift; + my $session = $self->session; + my $form = $session->form; + + my @messages = $form->process("inviteId","checkList"); + my $approve = $form->get("accept"); + my $deny = $form->get("deny"); + + my $friends = WebGUI::Friends->new($session); + + my @users = (); + + foreach my $inviteId (@messages) { + my $invite = $friends->getAddRequest($inviteId); + my $inviter = WebGUI::User->new($session, $invite->{inviterId}); + next unless ($invite->{inviterId}); #Not sure how this could ever happen, but check for it + next unless ($session->user->userId eq $invite->{friendId}); #Protect against malicious stuff + if($deny) { + $friends->rejectAddRequest($inviteId); + } + elsif($approve) { + $friends->approveAddRequest($inviteId); + } + push (@users, { + 'friend_name' => $inviter->getWholeName, + 'is_denied' => ($deny ne ""), + 'is_approved' => ($approve ne ""), + }); + } + my $var = {}; + $var->{'friends_loop'} = \@users; + + #Append common vars + $self->appendCommonVars($var,WebGUI::Inbox->new($session)); + + #Return a confirm message + return $self->processTemplate($var,$self->getInvitationConfirmTemplateId); +} + +#------------------------------------------------------------------- + =head2 www_deleteMessage ( ) Deletes a single messages passed in @@ -389,15 +498,84 @@ The page on which users can manage their friends requests =cut sub www_manageInvitations { - my $self = shift; - my $session = $self->session; - my $user = $session->user; + my $self = shift; + my $session = $self->session; + my $user = $session->user; + my $var = {}; + my $i18n = WebGUI::International->new($session,'Account_Inbox'); + + #Deal with rows per page + my $rpp = $session->form->get("rpp") || 25; + my $rpp_url = ";rpp=$rpp"; + + #Cache the base url + my $inboxUrl = $self->getUrl("op=account;module=inbox;do=manageInvitations"); - my $var = {}; + #Create the paginator + my $sql = q{ select * from friendInvitations where friendId=? order by dateSent desc }; + my $p = WebGUI::Paginator->new( + $session, + $inboxUrl.$rpp_url, + $rpp + ); + $p->setDataByQuery($sql,undef,undef,[$user->userId]); + + #Export page to template + my @msg = (); + foreach my $row ( @{$p->getPageData} ) { + my $inviter = WebGUI::User->new($session,$row->{inviterId}); + next if($inviter->isVisitor); # Inviter account got deleted + + my $epoch = WebGUI::DateTime->new(mysql => $row->{dateSent} )->epoch; + + my $hash = {}; + $hash->{'invite_id' } = $row->{inviteId}; + $hash->{'message_url' } = $self->getUrl("module=inbox;do=viewInvitation;inviteId=".$row->{inviteId}); + $hash->{'from_id' } = $row->{inviterId}; + $hash->{'from_url' } = $inviter->getProfileUrl; #Get the profile url of this user which may be cached. + $hash->{'from' } = $inviter->getWholeName; + $hash->{'dateStamp' } = $epoch; + $hash->{'dateStamp_formatted'} = $session->datetime->epochToHuman($epoch); + $hash->{'form_checkbox' } = WebGUI::Form::checkbox($session,{ + name => "inviteId", + value => $row->{inviteId} + }); + push(@msg,$hash); + } + my $msgCount = $p->getRowCount; + + $var->{'message_loop' } = \@msg; + $var->{'has_messages' } = $msgCount > 0; + $var->{'message_total' } = $msgCount; - #Add common template variable for displaying the inbox - my $inbox = WebGUI::Inbox->new($session); - $self->appendCommonVars($var,$inbox); + $var->{'form_start' } = WebGUI::Form::formHeader($session,{ + action => $self->getUrl("module=inbox;do=approveDenyInvitations") + }); + $var->{'form_end' } = WebGUI::Form::formFooter($session); + + $var->{'form_accept' } = WebGUI::Form::submit($session,{ + name =>"accept", + value =>$i18n->get("accept button label") + }); + + $var->{'form_deny' } = WebGUI::Form::submit($session,{ + name =>"deny", + value =>$i18n->get("deny button label") + }); + + tie my %rpps, "Tie::IxHash"; + %rpps = (25 => "25", 50 => "50", 100=>"100"); + $var->{'message_rpp' } = WebGUI::Form::selectBox($session,{ + name =>"rpp", + options => \%rpps, + value => $session->form->get("rpp") || 25, + extras => q{onchange="location.href='}.$inboxUrl.q{;rpp='+this.options[this.selectedIndex].value"} + }); + + #Append common vars + $self->appendCommonVars($var,WebGUI::Inbox->new($session)); + #Append pagination vars + $p->appendTemplateVars($var); return $self->processTemplate($var,$self->getManageInvitationsTemplateId); } @@ -453,6 +631,7 @@ sub www_sendMessage { $errorMsg = $i18n->get("system message error"); } if($errorMsg) { + $var->{'isInbox'} = "true"; return $self->showError($var,$errorMsg,$backUrl,$self->getInboxErrorTemplateId); } @@ -478,6 +657,7 @@ sub www_sendMessage { $errorMsg = $i18n->get("no self error"); } if($errorMsg) { + $var->{'isInbox'} = "true"; return $self->showError($var,$errorMsg,$backUrl,$self->getInboxErrorTemplateId); } @@ -530,6 +710,7 @@ sub www_sendMessage { unless($activeFriendCount) { my $i18n = WebGUI::International->new($session,'Account_Inbox'); $errorMsg = $i18n->get("no friends error"); + $var->{'isInbox'} = "true"; return $self->showError($var,$errorMsg,$backUrl,$self->getInboxErrorTemplateId); } @@ -553,8 +734,10 @@ sub www_sendMessage { $var->{'message_body' } = $form->get('message'); $var->{'form_message_text'} = WebGUI::Form::textarea($session, { - name =>"message", - value =>$var->{'message_body'} || "", + name =>"message", + value =>$var->{'message_body'} || "", + width =>600, + height =>200 }); $var->{'form_message_rich'} = WebGUI::Form::HTMLArea($session, { @@ -771,6 +954,99 @@ sub www_view { #------------------------------------------------------------------- +=head2 www_viewInvitation ( ) + +The page on which users view their messages + +=cut + +sub www_viewInvitation { + my $self = shift; + my $session = $self->session; + my $user = $session->user; + + my $var = {}; + my $inviteId = shift || $session->form->get("inviteId"); + my $errorMsg = shift; + my $i18n = WebGUI::International->new($session,'Account_Inbox'); + + + my $friends = WebGUI::Friends->new($session); + my $invitation = $friends->getAddRequest($inviteId); + my $inviter = WebGUI::User->new($session,$invitation->{inviterId}); + + #Add common template variable for displaying the inbox + $self->appendCommonVars($var,WebGUI::Inbox->new($session)); + + #Handle Errors + if (!($invitation->{inviteId})) { #Invitation is invalid + $errorMsg = $i18n->get("invitation does not exist"); + } + elsif ($inviter->isVisitor) { #Inviter user account was deleted + $errorMsg = $i18n->get("inviter no longer exists"); + } + elsif ($session->user->userId ne $invitation->{friendId}) { #User trying to view someone else's invitation + $errorMsg = $i18n->get("no access to invitation"); + } + + if($errorMsg) { + my $backUrl = $var->{'view_invitations_url'}; + $var->{'isInvitation'} = "true"; + return $self->showError($var,$errorMsg,$backUrl,$self->getInboxErrorTemplateId); + } + + my $epoch = WebGUI::DateTime->new(mysql => $invitation->{dateSent} )->epoch; + + $var->{'invite_id' } = $inviteId; + $var->{'message_from_id' } = $inviter->userId; + $var->{'message_from' } = $inviter->getWholeName; + $var->{'message_from_url' } = $inviter->getProfileUrl; + $var->{'message_dateStamp' } = $epoch; + $var->{'message_dateStamp_human'} = $session->datetime->epochToHuman($epoch); + $var->{'message_body' } = $invitation->{comments}; + + unless ($var->{'message_body'} =~ /\{'message_body'} =~ s/(http\S*)/\$1\<\/a\>/g; + } + unless ($var->{'message_body'} =~ /\
{'message_body'} =~ /\
{'message_body'} =~ /\

{'message_body'} =~ s/\n/\
\n/g; + } + + #Build the action URLs + my $nextInvitation = $friends->getPreviousInvitation($invitation); #Messages sorted descending so next is actually previous + if( $nextInvitation->{inviteId} ) { + $var->{'hasNext' } = "true"; + $var->{'next_message_url'} = $self->getUrl("module=inbox;do=viewInvitation;inviteId=".$nextInvitation->{inviteId}); + } + + my $prevInvitation = $friends->getNextInvitation($invitation); #Messages sorted descending so previous is actually next + if( $prevInvitation->{inviteId} ) { + $var->{'hasPrevious' } = "true"; + $var->{'prev_message_url'} = $self->getUrl("module=inbox;do=viewInvitation;inviteId=".$prevInvitation->{inviteId}); + } + + $var->{'form_header' } = WebGUI::Form::formHeader($session,{ + action => $self->getUrl("module=inbox;do=approveDenyInvitations;inviteId=".$inviteId) + }); + $var->{'form_footer' } = WebGUI::Form::formFooter($session); + + $var->{'form_accept' } = WebGUI::Form::submit($session,{ + name =>"accept", + value =>$i18n->get("accept button label") + }); + + $var->{'form_deny' } = WebGUI::Form::submit($session,{ + name =>"deny", + value =>$i18n->get("deny button label") + }); + + return $self->processTemplate($var,$self->getViewInvitationTemplateId); +} + +#------------------------------------------------------------------- + =head2 www_viewMessage ( ) The page on which users view their messages @@ -804,6 +1080,7 @@ sub www_viewMessage { if($errorMsg) { my $backUrl = $var->{'view_inbox_url'}; + $var->{'isInvitation'} = "true"; return $self->showError($var,$errorMsg,$backUrl,$self->getInboxErrorTemplateId); } @@ -812,7 +1089,7 @@ sub www_viewMessage { $var->{'message_id' } = $messageId; $var->{'message_subject' } = $message->get("subject"); $var->{'message_dateStamp' } = $message->get("dateStamp"); - $var->{'message_dateStemp_human'} = $session->datetime->epochToHuman($var->{'message_dateStamp'}); + $var->{'message_dateStamp_human'} = $session->datetime->epochToHuman($var->{'message_dateStamp'}); $var->{'message_status' } = $message->getStatus; $var->{'message_body' } = $message->get("message"); @@ -848,13 +1125,13 @@ sub www_viewMessage { $var->{'reply_url'} = $self->getUrl("module=inbox;do=sendMessage;messageId=".$messageId); } - my $nextMessage = $inbox->getNextMessage($message); + my $nextMessage = $inbox->getPreviousMessage($message); #Message are displayed in descending order so next is actually previous if( defined $nextMessage ) { $var->{'hasNext' } = "true"; $var->{'next_message_url'} = $self->getUrl("module=inbox;do=viewMessage;messageId=".$nextMessage->getId); } - my $prevMessage = $inbox->getPreviousMessage($message); + my $prevMessage = $inbox->getNextMessage($message); #Messages are displayed in descending order so previous is actually next if(defined $prevMessage) { $var->{'hasPrevious' } = "true"; $var->{'prev_message_url'} = $self->getUrl("module=inbox;do=viewMessage;messageId=".$prevMessage->getId); diff --git a/lib/WebGUI/Account/Profile.pm b/lib/WebGUI/Account/Profile.pm index 6adbe4854..ba14b5670 100644 --- a/lib/WebGUI/Account/Profile.pm +++ b/lib/WebGUI/Account/Profile.pm @@ -32,7 +32,7 @@ These subroutines are available from this package: =head2 appendCommonVars ( var ) - Appends common template variables that all inbox templates use + Appends common template variables that all profile templates use =head3 var @@ -47,11 +47,12 @@ sub appendCommonVars { my $user = $session->user; my $pageUrl = $session->url->page; - $var->{'user_full_name' } = $user->getWholeName; - $var->{'user_member_since' } = $user->dateCreated; - $var->{'view_profile_url' } = $user->getProfileUrl($pageUrl); - $var->{'edit_profile_url' } = $self->getUrl("module=profile;do=edit"); - $var->{'back_url' } = $session->env->get("HTTP_REFERER") || $var->{'view_profile_url'} + $var->{'user_full_name' } = $user->getWholeName; + $var->{'user_member_since' } = $user->dateCreated; + $var->{'view_profile_url' } = $user->getProfileUrl($pageUrl); + $var->{'edit_profile_url' } = $self->getUrl("module=profile;do=edit"); + $var->{'back_url' } = $session->env->get("HTTP_REFERER") || $var->{'view_profile_url'}; + $var->{'invitations_enabled' } = $session->user->profileField('ableToBeFriend'); } #------------------------------------------------------------------- @@ -104,6 +105,14 @@ sub editSettingsForm { label => $i18n->get("profile view template label"), hoverHelp => $i18n->get("profile view template hoverHelp") ); + $f->template( + name => "profileErrorTemplateId", + value => $self->getErrorTemplateId, + namespace => "Account/Profile/Error", + label => $i18n->get("profile error template label"), + hoverHelp => $i18n->get("profile error template hoverHelp") + ); + return $f->printRowsOnly; } @@ -128,6 +137,7 @@ sub editSettingsFormSave { $setting->set("profileDisplayLayoutTemplateId", $form->process("profileDisplayLayoutTemplateId","template")); $setting->set("profileEditTemplateId", $form->process("profileEditTemplateId","template")); $setting->set("profileViewTempalteId", $form->process("profileViewTemplateId","template")); + $setting->set("profileErrorTemplateId",$form->process("profileErrorTemplateId","template")); } @@ -194,6 +204,20 @@ sub getEditTemplateId { return $self->session->setting->get("profileEditTemplateId") || "75CmQgpcCSkdsL-oawdn3Q"; } +#------------------------------------------------------------------- + +=head2 getErrorTemplateId ( ) + +This method returns the template ID used to display the error page. + +=cut + +sub getErrorTemplateId { + my $self = shift; + return $self->session->setting->get("profileErrorTemplateId") || "MBmWlA_YEA2I6D29OMGtRg"; +} + + #------------------------------------------------------------------- =head2 getLayoutTemplateId ( ) @@ -205,9 +229,9 @@ This method returns the template ID for the account layout. sub getLayoutTemplateId { my $self = shift; my $session = $self->session; - my $method = $session->form->get("do"); - my $uid = $session->form->get("uid"); - + my $method = $self->method; + my $uid = $self->uid; + return $self->getEditLayoutTemplateId if($method eq "edit" || $uid eq ""); return $session->setting->get("profileLayoutTemplateId") || $self->SUPER::getLayoutTemplateId; } @@ -240,114 +264,6 @@ sub getViewTemplateId { #------------------------------------------------------------------- -=head2 saveProfileFields ( session, user, profile ) - -Saves profile data to a user's profile. Does not validate any of the data. - -=head3 session - -WebGUI session object - -=head3 user - -User object. Profile data will be placed in this user's profile. - -=head3 profile - -Hash ref of profile data to save. - -=cut - -sub saveProfileFields { - my $class = shift; - my $session = shift; - my $u = shift; - my $profile = shift; - - foreach my $fieldName (keys %{$profile}) { - $u->profileField($fieldName,${$profile}{$fieldName}); - } -} - -#------------------------------------------------------------------- - -=head2 validateProfileFields ( session, fields ) - -Class method which validates profile data from the session form variables. Returns an data structure which contains the following - -{ - profile => Hash reference containing all of the profile fields and their values - errors => Array reference of error messages to be displayed - errorCategory => Category in which the first error was thrown - warnings => Array reference of warnings to be displayed - errorFields => Array reference of the fieldIds that threw an error - warningFields => Array reference of the fieldIds that threw a warning -} - -=head3 session - -WebGUI session object - -=head3 fields - -An array reference of profile fields to validate. - -=cut - -sub validateProfileFields { - my $class = shift; - my $session = shift; - my $fields = shift; - - my $i18n = WebGUI::International->new($session, 'Account_Profile'); - - my $data = {}; - my $errors = []; - my $warnings = []; - my $errorCat = undef; - my $errorFields = []; - my $warnFields = []; - - foreach my $field (@{$fields}) { - my $fieldId = $field->getId; - my $fieldLabel = $field->getLabel; - my $fieldValue = $field->formProcess; - my $isValid = $field->isValid($fieldValue); - - $data->{$fieldId} = (ref $fieldValue eq "ARRAY") ? $fieldValue->[0] : $fieldValue; - - if(!$isValid) { - $errorCat = $field->get("profileCategoryId") unless (defined $errorCat); - push (@{$errors}, sprintf($i18n->get("required error"),$fieldLabel)); - push(@{$errorFields},$fieldId); - } - #The language field is special and must be always be valid or WebGUI will croak - elsif($fieldId eq "language" && !(exists $i18n->getLanguages()->{$data->{$fieldId}})) { - $errorCat = $field->get("profileCategoryId") unless (defined $errorCat); - $session->log->warn("language $fieldValue does not exist"); - push (@{$errors}, sprintf($i18n->get("language not installed error"),$data->{$fieldId})); - push(@{$errorFields},$fieldId); - } - #Duplicate emails throw warnings - elsif($fieldId eq "email" && $field->isDuplicate($fieldValue)) { - $errorCat = $field->get("profileCategoryId") unless (defined $errorCat); - push (@{$warnings},$i18n->get("email already in use error")); - push(@{$warnFields},$fieldId); - } - } - - return { - profile => $data, - errors => $errors, - warnings => $warnings, - errorCategory => $errorCat, - errorFields => $errorFields, - warningFields => $warnFields, - }; -} - -#------------------------------------------------------------------- - =head2 www_edit ( ) The edit page for the user's profile. @@ -369,6 +285,10 @@ sub www_edit { my @errorFields = (); @errorFields = (@{$errors->{errorFields}},@{$errors->{warningFields}}) if($hasErrors); + $var->{'profile_errors' } = []; + map{ push(@{$var->{'profile_errors'}},{ error_message => $_ }) } @{$errors->{errors}} if($hasErrors); + $var->{'hasErrors' } = scalar(@{$var->{'profile_errors'}}) > 0; + my @categories = (); foreach my $category (@{WebGUI::ProfileCategory->getCategories($session)}) { next unless $category->isEditable; @@ -415,6 +335,7 @@ sub www_edit { 'profile_category_shortLabel' => $shortCategoryLabel, 'profile_category_index' => $categoryIndex, 'profile_fields_loop' => \@fields, + 'profile_errors' => $var->{'profile_errors'}, }); #This value will determine whether or not a valid category is active or not $active ||= $isActive; @@ -431,11 +352,8 @@ sub www_edit { }); $var->{'profile_form_footer' } = WebGUI::Form::formFooter($session); - $var->{'profile_errors' } = []; - map{ push(@{$var->{'profile_errors'}},{ error_message => $_ }) } @{$errors->{errors}} if($hasErrors); - $self->appendCommonVars($var); - + return $self->processTemplate($var,$self->getEditTemplateId); } @@ -453,7 +371,7 @@ sub www_editSave { my $session = $self->session; my $fields = WebGUI::ProfileField->getEditableFields($session); - my $retHash = $self->validateProfileFields($session,$fields); + my $retHash = $session->user->validateProfileDataFromForm($fields); push (@{$retHash->{errors}},@{$retHash->{warnings}}); unless(scalar(@{$retHash->{errors}})) { @@ -476,9 +394,8 @@ The display page of the . sub www_view { my $self = shift; my $session = $self->session; - my $i18n = WebGUI::International->new($session, 'Account_Profile'); my $var = {}; - my $uid = $session->form->get("uid"); + my $uid = $self->uid; my $selected = $session->form->get("selected"); #Allow users to template tabs or other category dividers my $active = 0; #Whether or not a category is selected @@ -487,15 +404,23 @@ sub www_view { #Ensure uid is passed in if they want to view a profile. This controls the tab state. return $self->www_edit unless ($uid); - my $user = WebGUI::User->new($session,$uid); + my $user = WebGUI::User->new($session,$uid); + + $self->appendCommonVars($var); + + #Overwrite these + $var->{'user_full_name' } = $user->getWholeName; + $var->{'user_member_since' } = $user->dateCreated; #Check user privileges - #return $session->style->userStyle($vars->{displayTitle}.'. '.$i18n->get(862)) if($u->profileField("publicProfile") < 1 && ($session->user->userId ne $session->form->process("uid") || $session->user->isAdmin)); - #return $session->privilege->insufficient() if(!$session->user->isRegistered); - - if($user->isVisitor) { - $var->{'restricted' } = "true"; - $var->{'error_message'} = $i18n->get("visitor profile restricted"); + unless ($user->profileIsViewable($session->user)) { + my $i18n = WebGUI::International->new($session,'Account_Profile'); + return $self->showError( + $var, + $i18n->get("profile not public error"), + $var->{'back_url'}, + $self->getErrorTemplateId + ); } my @categories = (); @@ -549,6 +474,8 @@ sub www_view { #If not category is selected, set the first category as the active one $categories[0]->{profile_category_isActive} = 1 unless($active); + my $privacySetting = $user->profileField("publicProfile") || "none"; + $var->{'profile_privacy_'.$privacySetting } = "true"; $var->{'profile_category_loop' } = \@categories; $var->{'profile_user_id' } = $user->userId; @@ -556,12 +483,6 @@ sub www_view { $var->{'acceptsPrivateMessages'} = $user->acceptsPrivateMessages($session->user->userId); $var->{'acceptsFriendsRequests'} = $user->acceptsFriendsRequests($session->user); - $self->appendCommonVars($var); - - #Overwrite these - $var->{'user_full_name' } = $user->getWholeName; - $var->{'user_member_since' } = $user->dateCreated; - return $self->processTemplate($var,$self->getViewTemplateId); } diff --git a/lib/WebGUI/Account/Shop.pm b/lib/WebGUI/Account/Shop.pm new file mode 100644 index 000000000..1eb720fbe --- /dev/null +++ b/lib/WebGUI/Account/Shop.pm @@ -0,0 +1,297 @@ +package WebGUI::Account::Shop; + +use strict; + +use WebGUI::Exception; +use WebGUI::International; +use WebGUI::Pluggable; +use WebGUI::Utility; +use base qw/WebGUI::Account/; + +=head1 NAME + +Package WebGUI::Account::Shop + +=head1 DESCRIPTION + +Shop Features built into the Account system + +=head1 SYNOPSIS + +use WebGUI::Account::Shop; + +=head1 METHODS + +These methods are available from this class: + +=cut + +#------------------------------------------------------------------- + +=head2 appendCommonVars ( var ) + + Appends common template variables that shop templates will use + +=head3 var + + The hash reference to append template variables to + +=cut + +sub appendCommonVars { + my $self = shift; + my $var = shift; + + $self->SUPER::appendCommonVars($var); + + my $session = $self->session; + my $user = $session->user; + my $method = $session->form->get("do"); + + $var->{'manage_purchases_url' } = $self->getUrl("module=shop;do=managePurchases"); + $var->{'managesPurchasesIsActive'} = WebGUI::Utility::isIn($method,("","managePurchases","view","viewTransaction")); +} + +#------------------------------------------------------------------- + +=head2 canView ( ) + + Returns whether or not the user can view the the tab for this module + +=cut + +sub canView { + my $self = shift; + return ($self->uid eq ""); +} + +#------------------------------------------------------------------- + +=head2 editSettingsForm ( ) + + Creates form elements for user settings page custom to this account module + +=cut + +sub editSettingsForm { + my $self = shift; + my $session = $self->session; + my $i18n = WebGUI::International->new($session,'Account_Shop'); + my $shopi18n = WebGUI::International->new($session,'Shop'); + my $f = WebGUI::HTMLForm->new($session); + + $f->template( + name => "shopStyleTemplateId", + value => $self->getStyleTemplateId, + namespace => "style", + label => $i18n->get("shop style template label"), + hoverHelp => $i18n->get("shop style template hoverHelp") + ); + $f->template( + name => "shopLayoutTemplateId", + value => $self->getLayoutTemplateId, + namespace => "Account/Layout", + label => $i18n->get("shop layout template label"), + hoverHelp => $i18n->get("shop layout template hoverHelp") + ); + $f->template( + name => "shopMyPurchasesTemplateId", + value => $self->session->setting->get("shopMyPurchasesTemplateId"), + namespace => "Shop/MyPurchases", + label => $shopi18n->get("my purchases template"), + hoverHelp => $shopi18n->get("my purchases template help") + ); + $f->template( + name => "shopMyPurchasesDetailTemplateId", + value => $self->session->setting->get("shopMyPurchasesDetailTemplateId"), + namespace => "Shop/MyPurchasesDetail", + label => $shopi18n->get("my purchases detail template"), + hoverHelp => $shopi18n->get("my purchases detail template help") + ); + + return $f->printRowsOnly; +} + +#------------------------------------------------------------------- + +=head2 editSettingsFormSave ( ) + + Creates form elements for the settings page custom to this account module + +=cut + +sub editSettingsFormSave { + my $self = shift; + my $session = $self->session; + my $setting = $session->setting; + my $form = $session->form; + + $setting->set("shopStyleTemplateId", $form->process("shopStyleTemplateId","template")); + $setting->set("shopLayoutTemplateId", $form->process("shopLayoutTemplateId","template")); + $setting->set("shopMyPurchasesTemplateId", $form->process("shopMyPurchasesTemplateId","template")); + $setting->set("shopMyPurchasesDetailTemplateId", $form->process("shopMyPurchasesDetailTemplateId","template")); +} + +#------------------------------------------------------------------- + +=head2 getLayoutTemplateId ( ) + +This method returns the templateId for the layout of your new module. + +=cut + +sub getLayoutTemplateId { + my $self = shift; + return $self->session->setting->get("shopLayoutTemplateId") || "aUDsJ-vB9RgP-AYvPOy8FQ"; +} + + +#------------------------------------------------------------------- + +=head2 getStyleTemplateId ( ) + +This method returns the template ID for the main style. + +=cut + +sub getStyleTemplateId { + my $self = shift; + return $self->session->setting->get("shopStyleTemplateId") || $self->SUPER::getStyleTemplateId; +} + +#------------------------------------------------------------------- + +=head2 www_managePurchases ( ) + +The main view page for editing the user's profile. + +=cut + +sub www_managePurchases { + my $self = shift; + my $session = $self->session; + my $url = $session->url; + + my $var = {}; + + # build list + foreach my $id (@{WebGUI::Shop::Transaction->getTransactionIdsForUser($session)}) { + my $transaction = WebGUI::Shop::Transaction->new($session, $id); + push @{$var->{transactions}}, { + %{$transaction->get}, + viewDetailUrl => $self->getUrl('op=account;module=shop;do=viewTransaction;transactionId='.$id), + amount => sprintf("%.2f", $transaction->get('amount')), + }; + } + + $self->appendCommonVars($var); + + return $self->processTemplate($var,$session->setting->get("shopMyPurchasesTemplateId")); +} + +#------------------------------------------------------------------- + +=head2 www_view ( ) + +The main view page for editing the user's profile. + +=cut + +sub www_view { + my $self = shift; + + #Use the view class as the driver for now. This will likely grow + return $self->www_managePurchases(); + +} + +#------------------------------------------------------------------- + +=head2 www_viewTransaction ( ) + +The main view page for editing the user's profile. + +=cut + +sub www_viewTransaction { + my $self = shift; + my $session = $self->session; + + my $transactionId = $session->form->get('transactionId'); + my $transaction = shift || WebGUI::Shop::Transaction->new($session,$transactionId); + my $notice = shift; + + return $session->insufficient unless ($transaction->get('userId') eq $session->user->userId); + + my $i18n = WebGUI::International->new($session, 'Shop'); + my $i18n = WebGUI::International->new($session, 'Shop'); + my ($style, $url) = $session->quick(qw(style url)); + + my %var = ( + %{$transaction->get}, + notice => $notice, + cancelRecurringUrl => $url->page('shop=transaction;method=cancelRecurring;transactionId='.$transaction->getId), + amount => sprintf("%.2f", $transaction->get('amount')), + inShopCreditDeduction => sprintf("%.2f", $transaction->get('inShopCreditDeduction')), + taxes => sprintf("%.2f", $transaction->get('taxes')), + shippingPrice => sprintf("%.2f", $transaction->get('shippingPrice')), + shippingAddress => $transaction->formatAddress({ + name => $transaction->get('shippingAddressName'), + address1 => $transaction->get('shippingAddress1'), + address2 => $transaction->get('shippingAddress2'), + address3 => $transaction->get('shippingAddress3'), + city => $transaction->get('shippingCity'), + state => $transaction->get('shippingState'), + code => $transaction->get('shippingCode'), + country => $transaction->get('shippingCountry'), + phoneNumber => $transaction->get('shippingPhoneNumber'), + }), + paymentAddress => $transaction->formatAddress({ + name => $transaction->get('paymentAddressName'), + address1 => $transaction->get('paymentAddress1'), + address2 => $transaction->get('paymentAddress2'), + address3 => $transaction->get('paymentAddress3'), + city => $transaction->get('paymentCity'), + state => $transaction->get('paymentState'), + code => $transaction->get('paymentCode'), + country => $transaction->get('paymentCountry'), + phoneNumber => $transaction->get('paymentPhoneNumber'), + }), + ); + + # items + my @items = (); + foreach my $item (@{$transaction->getItems}) { + my $address = ''; + if ($transaction->get('shippingAddressId') ne $item->get('shippingAddressId')) { + $address = $transaction->formatAddress({ + name => $item->get('shippingAddressName'), + address1 => $item->get('shippingAddress1'), + address2 => $item->get('shippingAddress2'), + address3 => $item->get('shippingAddress3'), + city => $item->get('shippingCity'), + state => $item->get('shippingState'), + code => $item->get('shippingCode'), + country => $item->get('shippingCountry'), + phoneNumber => $item->get('shippingPhoneNumber'), + }); + } + push @items, { + %{$item->get}, + viewItemUrl => $url->page('shop=transaction;method=viewItem;transactionId='.$transaction->getId.';itemId='.$item->getId), + price => sprintf("%.2f", $item->get('price')), + itemShippingAddress => $address, + orderStatus => $i18n->get($item->get('orderStatus')), + }; + } + $var{items} = \@items; + + $self->appendCommonVars(\%var); + + # render + return $self->processTemplate(\%var,$session->setting->get("shopMyPurchasesDetailTemplateId")); +} + + + +1; diff --git a/lib/WebGUI/Account/User.pm b/lib/WebGUI/Account/User.pm index 46f3b4d42..37185c1bf 100644 --- a/lib/WebGUI/Account/User.pm +++ b/lib/WebGUI/Account/User.pm @@ -6,6 +6,8 @@ use WebGUI::Exception; use WebGUI::International; use WebGUI::Pluggable; use WebGUI::Utility; +use WebGUI::Operation::Auth; + use base qw/WebGUI::Account/; =head1 NAME @@ -26,6 +28,18 @@ These subroutines are available from this package: =cut +#------------------------------------------------------------------- + +=head2 canView ( ) + + Returns whether or not the user can view the inbox tab + +=cut + +sub canView { + my $self = shift; + return ($self->uid eq ""); +} #------------------------------------------------------------------- @@ -42,13 +56,24 @@ sub editSettingsForm { my $i18n = WebGUI::International->new($session,'Account_User'); my $f = WebGUI::HTMLForm->new($session); -# $f->template( -# name => "profileStyleTemplateId", -# value => $self->getStyleTemplateId, -# namespace => "style", -# label => $i18n->get("profile style template label"), -# hoverHelp => $i18n->get("profile style template hoverHelp") -# ); + $f->template( + name => "userAccountStyleTemplateId", + value => $self->session->setting->get("userAccountStyleTemplateId"), + namespace => "style", + label => $i18n->get("user style template label"), + hoverHelp => $i18n->get("user style template hoverHelp") + ); + $f->template( + name => "userAccountLayoutTemplateId", + value => $self->session->setting->get("userAccountLayoutTemplateId"), + namespace => "Account/Layout", + label => $i18n->get("layout template label"), + hoverHelp => $i18n->get("layout template hoverHelp") + ); + $f->raw(q{ }); + $f->readOnly ( + value => $i18n->get("templates in auth method message"), + ); return $f->printRowsOnly; } @@ -62,6 +87,13 @@ sub editSettingsForm { =cut sub editSettingsFormSave { + my $self = shift; + my $session = $self->session; + my $setting = $session->setting; + my $form = $session->form; + + $setting->set("userAccountStyleTemplateId", $form->process("userAccountStyleTemplateId","template")); + $setting->set("userAccountLayoutTemplateId", $form->process("userAccountLayoutTemplateId","template")); } #------------------------------------------------------------------- @@ -74,7 +106,7 @@ This method returns the template ID for the account layout. sub getLayoutTemplateId { my $self = shift; - return $self->session->setting->get("userLayoutTempalteId") || $self->SUPER::getLayoutTemplateId; + return $self->session->setting->get("userAccountLayoutTemplateId") || "9ThW278DWLV0-Svf68ljFQ"; } @@ -88,21 +120,9 @@ This method returns the template ID for the main style. sub getStyleTemplateId { my $self = shift; - return $self->session->setting->get("userStyleTemplateId") || $self->SUPER::getStyleTemplateId; + return $self->session->setting->get("userAccountStyleTemplateId") || $self->SUPER::getStyleTemplateId; } -#------------------------------------------------------------------- - -=head2 getViewTemplateId ( ) - -This method returns the template ID for the main view. - -=cut - -sub getViewTemplateId { - my $self = shift; - return $self->session->setting->get("userViewTemplateId") || "defaultAssetId"; -} #------------------------------------------------------------------- @@ -115,9 +135,10 @@ The main view page for editing the user's profile. sub www_view { my $self = shift; my $session = $self->session; - my $var = {}; - return $self->processTemplate($var,$self->getViewTemplateId); + my $auth = WebGUI::Operation::Auth::getInstance($session); + + return $auth->displayAccount; } diff --git a/lib/WebGUI/Account/_NewModule.skeleton b/lib/WebGUI/Account/_NewModule.skeleton new file mode 100644 index 000000000..7c665f462 --- /dev/null +++ b/lib/WebGUI/Account/_NewModule.skeleton @@ -0,0 +1,145 @@ +package WebGUI::Account::NewModule; + +use strict; + +use WebGUI::Exception; +use WebGUI::International; +use WebGUI::Pluggable; +use WebGUI::Utility; +use base qw/WebGUI::Account/; + +=head1 NAME + +Package WebGUI::Account::NewAsset + +=head1 DESCRIPTION + +Describe your New Account Module's functionality and features here. + +=head1 SYNOPSIS + +use WebGUI::Account::NewModule; + + +=head1 METHODS + +These methods are available from this class: + +=cut + +#------------------------------------------------------------------- + +=head2 canView ( ) + + Returns whether or not the user can view the the tab for this module + +=cut + +sub canView { + my $self = shift; + return 1; +} + +#------------------------------------------------------------------- + +=head2 editSettingsForm ( ) + + Creates form elements for user settings page custom to this account module + +=cut + +sub editSettingsForm { + my $self = shift; + my $session = $self->session; + my $i18n = WebGUI::International->new($session,'Account_NewModule'); + my $f = WebGUI::HTMLForm->new($session); + + $f->template( + name => "moduleStyleTemplateId", + value => $self->getStyleTemplateId, + namespace => "style", + label => $i18n->get("style template label"), + hoverHelp => $i18n->get("style template hoverHelp") + ); + $f->template( + name => "moduleLayoutTemplateId", + value => $self->getLayoutTemplateId, + namespace => "Account/Layout", + label => $i18n->get("layout template label"), + hoverHelp => $i18n->get("layout template hoverHelp") + ); + $f->template( + name => "moduleViewTemplateId", + value => $self->session->setting->get("moduleViewTemplateId"), + namespace => "Account/NewModule/View", + label => $i18n->get("view template label"), + hoverHelp => $i18n->get("view template hoverHelp") + ); + + return $f->printRowsOnly; +} + +#------------------------------------------------------------------- + +=head2 editSettingsFormSave ( ) + + Creates form elements for the settings page custom to this account module + +=cut + +sub editSettingsFormSave { + my $self = shift; + my $session = $self->session; + my $setting = $session->setting; + my $form = $session->form; + + $setting->set("moduleStyleTemplateId", $form->process("moduleStyleTemplateId","template")); + $setting->set("moduleLayoutTemplateId", $form->process("moduleLayoutTemplateId","template")); + $setting->set("moduleViewTemplateId", $form->process("moduleViewTemplateId","template")); +} + +#------------------------------------------------------------------- + +=head2 getLayoutTemplateId ( ) + +This method returns the templateId for the layout of your new module. + +=cut + +sub getLayoutTemplateId { + my $self = shift; + return $self->session->setting->get("moduleLayoutTempalteId") || $self->SUPER::getLayoutTemplateId; +} + + +#------------------------------------------------------------------- + +=head2 getStyleTemplateId ( ) + +This method returns the template ID for the main style. + +=cut + +sub getStyleTemplateId { + my $self = shift; + return $self->session->setting->get("moduleStyleTemplateId") || $self->SUPER::getStyleTemplateId; +} + +#------------------------------------------------------------------- + +=head2 www_view ( ) + +The main view page for editing the user's profile. + +=cut + +sub www_view { + my $self = shift; + my $session = $self->session; + my $var = {}; + + return $self->processTemplate($var,$session->setting->get("moduleViewTemplateId")); +} + + +1; diff --git a/lib/WebGUI/Asset/Post.pm b/lib/WebGUI/Asset/Post.pm index ddb7d4531..399b0c465 100644 --- a/lib/WebGUI/Asset/Post.pm +++ b/lib/WebGUI/Asset/Post.pm @@ -424,7 +424,7 @@ Formats the url to view a users profile. sub getPosterProfileUrl { my $self = shift; - return $self->getUrl("op=viewProfile;uid=".$self->get("ownerUserId")); + return WebGUI::User->new($self->session,$self->get("ownerUserId"))->getProfileUrl; } #------------------------------------------------------------------- @@ -534,7 +534,7 @@ sub getTemplateVars { $var{"userId"} = $self->get("ownerUserId"); $var{"user.isPoster"} = $self->isPoster; $var{"avatar.url"} = $self->getAvatarUrl; - $var{"userProfile.url"} = $self->getUrl("op=viewProfile;uid=".$self->get("ownerUserId")); + $var{"userProfile.url"} = $self->getPosterProfileUrl; $var{"dateSubmitted.human"} =$self->session->datetime->epochToHuman($self->get("creationDate")); $var{"dateUpdated.human"} =$self->session->datetime->epochToHuman($self->get("revisionDate")); $var{'title.short'} = $self->chopTitle; diff --git a/lib/WebGUI/Asset/Shortcut.pm b/lib/WebGUI/Asset/Shortcut.pm index 0497f6151..41921b3d7 100644 --- a/lib/WebGUI/Asset/Shortcut.pm +++ b/lib/WebGUI/Asset/Shortcut.pm @@ -847,7 +847,7 @@ sub www_saveUserPrefs { my $field = WebGUI::ProfileField->new($self->session,$fieldId); next unless $field; $data{$field->getId} = $field->formProcess; - if ($field->getId eq 'email' && WebGUI::Operation::Profile::isDuplicateEmail($self->session,$data{$field->getId})) { + if ($field->getId eq 'email' && $field->isDuplicate($data{$field->getId})) { return '

  • '.$i18n->get(1072).'
  • '; } if ($field->isRequired && !$data{$field->getId}) { diff --git a/lib/WebGUI/Auth.pm b/lib/WebGUI/Auth.pm index 0b8cf4fd6..d8b7c421a 100644 --- a/lib/WebGUI/Auth.pm +++ b/lib/WebGUI/Auth.pm @@ -30,6 +30,7 @@ use WebGUI::Operation::Shared; use WebGUI::Operation::Profile; use WebGUI::Workflow::Instance; use WebGUI::Inbox; +use WebGUI::Exception; # Profile field name for the number of times the showMessageOnLogin has been # seen. @@ -270,7 +271,7 @@ Password entered by the user. This is only used in for sending the user a notif =head3 profile -Hashref of profile values returned by the function WebGUI::Operation::Profile::validateProfileData($self->session) +Hashref of profile values returned by the function WebGUI::User::validateProfileDataFromForm($fields); =cut @@ -290,7 +291,7 @@ sub createAccountSave { $u->username($username); $u->authMethod($self->authMethod); $u->karma($self->session->setting->get("karmaPerLogin"),"Login","Just for logging in.") if ($self->session->setting->get("useKarma")); - WebGUI::Operation::Profile::saveProfileFields($self->session,$u,$profile) if($profile); + $u->updateProfileFields($profile) if ($profile); $self->saveParams($userId,$self->authMethod,$properties); if ($self->getSetting("sendWelcomeMessage")){ @@ -460,10 +461,10 @@ Array ref of template vars from subclass =cut sub displayAccount { - my $self = shift; - my $method = $_[0]; - my $vars = $_[1]; - + my $self = shift; + my $method = shift; + my $vars = shift; + my $i18n = WebGUI::International->new($self->session); $vars->{title} = $i18n->get(61); @@ -477,8 +478,21 @@ sub displayAccount { $vars->{'account.form.submit'} = WebGUI::Form::submit($self->session,{}); $vars->{'account.form.footer'} = WebGUI::Form::formFooter($self->session,); - $vars->{'account.options'} = WebGUI::Operation::Shared::accountOptions($self->session); - return WebGUI::Asset::Template->new($self->session,$self->getAccountTemplateId)->process($vars); + #Appends 'account.options' loop along with some new links + WebGUI::Account->appendAccountLinks($self->session,$vars); + + ########### ACCOUNT SHUNT + #The following is a shunt which allows the displayAccount page to be displayed in the + #Account system. This shunt will be replaced in WebGUI 8 when the API can be broken + my $output = WebGUI::Asset::Template->new($self->session,$self->getAccountTemplateId)->process($vars); + #If the account system is calling this method, just return the template + my $op = $self->session->form->get("op"); + if($op eq "account") { + return $output; + } + #Otherwise wrap the template into the account layout + my $instance = WebGUI::Content::Account->createInstance($self->session,"user"); + return $instance->displayContent($output,1); } #------------------------------------------------------------------- diff --git a/lib/WebGUI/Auth/LDAP.pm b/lib/WebGUI/Auth/LDAP.pm index bbf23d7d2..a4fdf252b 100644 --- a/lib/WebGUI/Auth/LDAP.pm +++ b/lib/WebGUI/Auth/LDAP.pm @@ -304,9 +304,18 @@ sub createAccountSave { #Check that username is valid and not a duplicate in the system. $error .= $self->error if(!$self->validUsername($username)); #Validate profile data. - my ($profile, $temp, $warning) = WebGUI::Operation::Profile::validateProfileData($self->session); + my $fields = WebGUI::ProfileField->getEditableFields($self->session); + my $retHash = $self->user->validateProfileDataFromForm($fields); + my $profile = $retHash->{profile}; + my $temp = ""; + my $warning = ""; + + my $format = "
  • %s
  • "; + map { $warning .= sprintf($format,$_) } @{$retHash->{warnings}}; + map { $temp .= sprintf($format,$_) } @{$retHash->{errors}}; + $error .= $temp; - return $self->createAccount("
  • ".$error."") unless ($error eq ""); + return $self->createAccount("
  • ".$error."
  • ") unless ($error eq ""); #If Email address is not unique, a warning is displayed if($warning ne "" && !$self->session->form->process("confirm")){ return $self->createAccount('
  • '.$i18n->get(1078).'
  • ', 1); @@ -336,18 +345,30 @@ sub deactivateAccountConfirm { #------------------------------------------------------------------- sub displayAccount { - my $self = shift; - my $vars; - return $self->displayLogin($_[0]) if ($self->isVisitor); + my $self = shift; + my $vars; + return $self->displayLogin($_[0]) if ($self->isVisitor); my $i18n = WebGUI::International->new($self->session); - $vars->{displayTitle} = '

    '.$i18n->get(61).'

    '; - $vars->{'account.message'} = $i18n->get(856); - if($self->session->setting->get("useKarma")){ - $vars->{'account.form.karma'} = $self->session->user->profileField("karma"); - $vars->{'account.form.karma.label'} = $i18n->get(537); - } - $vars->{'account.options'} = WebGUI::Operation::Shared::accountOptions($self->session); - return WebGUI::Asset::Template->new($self->session,$self->getAccountTemplateId)->process($vars); + $vars->{displayTitle} = '

    '.$i18n->get(61).'

    '; + $vars->{'account.message'} = $i18n->get(856); + if($self->session->setting->get("useKarma")){ + $vars->{'account.form.karma'} = $self->session->user->profileField("karma"); + $vars->{'account.form.karma.label'} = $i18n->get(537); + } + WebGUI::Account->appendAccountLinks($self->session,$vars); + + ########### ACCOUNT SHUNT + #The following is a shunt which allows the displayAccount page to be displayed in the + #Account system. This shunt will be replaced in WebGUI 8 when the API can be broken + my $output = WebGUI::Asset::Template->new($self->session,$self->getAccountTemplateId)->process($vars); + #If the account system is calling this method, just return the template + my $op = $self->session->form->get("op"); + if($op eq "account") { + return $output; + } + #Otherwise wrap the template into the account layout + my $instance = WebGUI::Content::Account->createInstance($self->session,"user"); + return $instance->displayContent($output,1); } #------------------------------------------------------------------- diff --git a/lib/WebGUI/Auth/WebGUI.pm b/lib/WebGUI/Auth/WebGUI.pm index f93aa1b0b..5b28c7e41 100644 --- a/lib/WebGUI/Auth/WebGUI.pm +++ b/lib/WebGUI/Auth/WebGUI.pm @@ -229,7 +229,18 @@ sub createAccountSave { } } $error .= $self->error unless($self->_isValidPassword($password,$passConfirm)); - my ($profile, $temp, $warning) = WebGUI::Operation::Profile::validateProfileData($self->session, {regOnly => 1}); + + my $fields = WebGUI::ProfileField->getRegistrationFields($session); + my $retHash = $self->user->validateProfileDataFromForm($fields); + my $profile = $retHash->{profile}; + my $temp = ""; + my $warning = ""; + + my $format = "
  • %s
  • "; + map { $warning .= sprintf($format,$_) } @{$retHash->{warnings}}; + map { $temp .= sprintf($format,$_) } @{$retHash->{errors}}; + + $error .= $temp; unless ($error eq "") { diff --git a/lib/WebGUI/Content/Account.pm b/lib/WebGUI/Content/Account.pm index 619687ca7..6978381e0 100644 --- a/lib/WebGUI/Content/Account.pm +++ b/lib/WebGUI/Content/Account.pm @@ -16,7 +16,7 @@ package WebGUI::Content::Account; use strict; use WebGUI::Session; -use WebGUI::Exception::Account; +use WebGUI::Exception; use Carp qw(croak); =head1 NAME @@ -56,6 +56,65 @@ These subroutines are available from this package: =cut + +#------------------------------------------------------------------- + +=head2 createInstance ( session, module ) + +Creates an instance of an account pluggin + +=session + +WebGUI::Session object + +=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; + } + + #Visitor cannot access the acccount system + return $session->privilege->insufficient if($session->user->isVisitor); + + #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 ) @@ -99,97 +158,21 @@ sub handler { my $form = $session->form; my $setting = $session->setting; - my $op = $form->get("op"); - return undef unless ($op eq "account"); + #Pass through if it's not the account op + return undef unless ($form->get("op") eq "account"); - my $output = undef; + my $module = $form->get("module"); + my $method = $form->get("do"); + my $uid = $form->get("uid"); - my $module = $form->get("module") || $session->config->get("profileModuleIdentifier"); + 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); - my $configs = $session->config->get("account"); - my $config = __PACKAGE__->getAccountConfig($session,$module,$configs); - - if (defined $config) { - #Visitor cannot do anything to the profile. - return $session->privilege->insufficient if($session->user->isVisitor); - - #Create Pluggin Object - #Don't eval this as pluggable will croak and we want WebGUI::URL::Content to handle the exception - my $pluggin = WebGUI::Pluggable::instanciate($config->{className}, "new", [ $session ] ); - - #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' - ); - } - - #Check to see if the user has permission to see what they are calling - return $session->privilege->insufficient unless ($pluggin->canView); - - #Process the method call - my $method = $form->get("do") || "view"; - $method = "www_".$method; - - if($pluggin->can($method)) { - $output = $pluggin->$method; - } - else { - WebGUI::Error::MethodNotFound->throw( - error => "Couldn't call non-existant method $method", - method => $method - ); - } - - #Wrap content returned from method call into the layout - my $var = {}; - $var->{content} = $output; - - # Get fieldsets for avaiable account methods in the order they exist in the config file - my @pluggins = (); - foreach my $account (@{$configs}) { - #Instantiate the pluggin - #Use the currently instantiated pluggin if we are checking this pluggin - my $instance = undef; - if($account->{identifier} eq $module) { - $instance = $pluggin; - } - else { - $instance = eval { WebGUI::Pluggable::instanciate($account->{className}, "new", [ $session ] ) }; - if (my $e = WebGUI::Error->caught) { - $session->log->warn("Couldn't instantiate Account Pluggin ".$account->{className}." ... skipping"); - next; - } - elsif(!$pluggin->isa('WebGUI::Account')) { - $session->log->warn((ref $instance)." is not a subclass of WebGUI::Account ... skipping"); - next; - } - } - #Skip this module if the user can't view this - next unless ($instance->canView); - - #Push the tab variables onto the template - my %hash = %{$account}; - my $identifier = $account->{identifier}; - $hash{'is_'.$identifier} = "true"; - $hash{'url' } = $instance->getUrl("module=$identifier",1); - $hash{'isActive' } = "true" if($identifier eq $module); - WebGUI::Macro::process(\$hash{'title'}); - push(@pluggins,\%hash); - } - $var->{'account_loop'} = \@pluggins; - - my $layoutId = $pluggin->getLayoutTemplateId; - #Process the layout template - $output = $pluggin->processTemplate($var,$layoutId); - #Wrap the layout in the user style - $output = $session->style->userStyle($output); - } - - return $output; } diff --git a/lib/WebGUI/Form/File.pm b/lib/WebGUI/Form/File.pm index 0c1e82542..076c0d3d4 100644 --- a/lib/WebGUI/Form/File.pm +++ b/lib/WebGUI/Form/File.pm @@ -174,11 +174,6 @@ deleting the file if it was specified. sub getValue { my $self = shift; my $value = $self->get("value"); - my $log = $self->session->log; - $log->warn("file is: ".$self->session->form->get($self->get("name")."_file")); - $log->warn("value is: ".$value); - $log->warn("action is: ".$self->session->form->param($self->privateName('action'))); - my $storage = WebGUI::Storage->get($self->session,$value); if (defined $storage) { foreach my $file (@{$storage->getFiles}) { @@ -200,8 +195,6 @@ sub getValue { } $storage->addFileFromFormPost($self->get("name")."_file",1000); my @files = @{ $storage->getFiles }; - $log->warn("storageId: ".$storage->getId); - $log->warn("number of files: ".scalar(@files)); if (scalar(@files) < 1) { $storage->delete; return undef; @@ -212,7 +205,6 @@ sub getValue { return $id; } } - $log->warn("returning: ".$value); return $value; } diff --git a/lib/WebGUI/Friends.pm b/lib/WebGUI/Friends.pm index 2b7d98242..5aa7e6acd 100644 --- a/lib/WebGUI/Friends.pm +++ b/lib/WebGUI/Friends.pm @@ -149,6 +149,61 @@ sub getAllPendingAddRequests { } +#------------------------------------------------------------------- + +=head2 getNextInvitation ( invitation ) + +Returns the invitation that was sent to the user just after the invitation passed in. + +=cut + +sub getNextInvitation { + my $self = shift; + my $invitation = shift; + + my $sql = q{ + select + * + from + friendInvitations + where + friendId = ? + and dateSent > ? + order by dateSent asc + limit 1 + }; + my $bindvars = [$self->user->userId,$invitation->{dateSent}]; + return $self->session->db->quickHashRef($sql,$bindvars); +} + + +#------------------------------------------------------------------- + +=head2 getPreviousInvitation ( invitation ) + +Returns the invitation that was sent to the user just before the invitation passed in. + +=cut + +sub getPreviousInvitation { + my $self = shift; + my $invitation = shift; + + my $sql = q{ + select + * + from + friendInvitations + where + friendId = ? + and dateSent < ? + order by dateSent desc + limit 1 + }; + my $bindvars = [$self->user->userId,$invitation->{dateSent}]; + return $self->session->db->quickHashRef($sql,$bindvars); +} + #------------------------------------------------------------------- =head2 isFriend ( userId ) @@ -193,7 +248,7 @@ sub isInvited { inviterId = ? and friendId = ? }, - [$session->user->userId,$userId]); + [$self->user->userId,$userId]); return $isInvited; } @@ -268,12 +323,19 @@ The user to invite to be a friend. The message to lure them to accept. +=head inviteUrl + +The url to view the friend request + =cut sub sendAddRequest { - my $self = shift; - my $userId = shift; - my $comments = shift; + my $self = shift; + my $userId = shift; + my $comments = shift; + my $url = $self->session->url; + my $inviteUrl = shift || $url->append($url->getSiteURL,'op=account'); + my $i18n = WebGUI::International->new($self->session, "Friends"); # No sneaky attack paths... @@ -281,7 +343,9 @@ sub sendAddRequest { # Create the invitation url. my $inviteId = $self->session->id->generate(); - my $inviteUrl = $self->session->url->append($self->session->url->getSiteURL, 'op=friendRequest;inviteId='.$inviteId); + + $inviteUrl = $url->append($inviteUrl,'inviteId='.$inviteId); + # Build the message my $messageText = sprintf $i18n->get("invitation approval email"), $self->user->getWholeName, $self->session->url->getSiteURL, $comments, $inviteUrl; diff --git a/lib/WebGUI/Inbox.pm b/lib/WebGUI/Inbox.pm index a15f92a13..162a615f3 100644 --- a/lib/WebGUI/Inbox.pm +++ b/lib/WebGUI/Inbox.pm @@ -154,7 +154,7 @@ sub getMessage { =head2 getNextMessage ( message [, userId] ) -Returns the next message for the user +Returns the message that was send after the message passed in for the user =head3 message @@ -167,15 +167,15 @@ The WebGUI::User object of the user to retrieve the message for. Defaults to th =cut sub getNextMessage { - my $self = shift; + my $self = shift; my $session = $self->session; my $message = shift; my $user = shift || $session->user; - - my $sql = $self->getMessageSql($user,{ - whereClause => "ibox.dateStamp < ".$message->get("dateStamp"), + + my $sql = $self->getMessageSql($user,{ + whereClause => "ibox.dateStamp > ".$message->get("dateStamp"), sortBy => "ibox.dateStamp", - sortDir => "desc", + sortDir => "asc", limit => 1 }); @@ -188,7 +188,7 @@ sub getNextMessage { =head2 getPreviousMessage ( message [, userId] ) -Returns the previous message for the user +Returns the message that was sent before the message passed in for the user =head3 message @@ -205,11 +205,11 @@ sub getPreviousMessage { my $session = $self->session; my $message = shift; my $user = shift || $session->user; - - my $sql = $self->getMessageSql($user,{ - whereClause => "ibox.dateStamp > ".$message->get("dateStamp"), + + my $sql = $self->getMessageSql($user,{ + whereClause => "ibox.dateStamp < ".$message->get("dateStamp"), sortBy => "ibox.dateStamp", - sortDir => "asc", + sortDir => "desc", limit => 1 }); diff --git a/lib/WebGUI/Inbox/Message.pm b/lib/WebGUI/Inbox/Message.pm index 37af5703c..0abd30ad6 100644 --- a/lib/WebGUI/Inbox/Message.pm +++ b/lib/WebGUI/Inbox/Message.pm @@ -378,9 +378,12 @@ The id of the user that completed this task. Defaults to the current user. sub setCompleted { my $self = shift; my $userId = shift || $self->session->user->userId; - $self->{_properties}{status} = "completed"; + $self->{_properties}{status} = "completed"; $self->{_properties}{completedBy} = $userId; $self->{_properties}{completedOn} = time(); + $self->{_inbox}{status} = "completed"; + $self->{_inbox}{completedBy} = $userId; + $self->{_inbox}{completedOn} = time(); $self->session->db->setRow("inbox","messageId",$self->{_inbox}); #Completed messages should also be marked read $self->setRead($userId); @@ -498,7 +501,12 @@ sub setStatus { $self->setReplied($userId); } - $self->{_properties}{status} = ( $status ne "pending") ? "active" : "pending"; + #Only let completed stuff go back to pending + if ( $status eq "pending" && $self->{_properties}{status} eq "completed") { + $self->{_properties}{status} = "pending"; + $self->{_inbox}{status} = "pending" + } + $self->session->db->setRow("inbox","messageId",$self->{_inbox}); return undef; } diff --git a/lib/WebGUI/Macro/FileUrl.pm b/lib/WebGUI/Macro/FileUrl.pm index 556f23b4d..5c412db7c 100644 --- a/lib/WebGUI/Macro/FileUrl.pm +++ b/lib/WebGUI/Macro/FileUrl.pm @@ -52,6 +52,10 @@ the asset and simply return the url of the first file it finds If id is passed in and the isStorageId flag is set, you may pass in filename to specify the name of the file you'd like returned. +head3 isImage + +If id is passed in and the isImage flag is set, the first image will be returned + =cut sub process { @@ -60,11 +64,18 @@ sub process { my $id = shift; my $isStorageId = shift; my $filename = shift; + my $isImage = shift; my $i18n = WebGUI::International->new($session, 'Macro_FileUrl'); #Handle storageId case if($isStorageId && $id) { - my $store = WebGUI::Storage->get($session,$id); + my $store = undef; + if($isImage) { + $store = WebGUI::Storage::Image->get($session,$id); + } + else { + $store = WebGUI::Storage->get($session,$id); + } $filename = $store->getFiles->[0] unless ($filename); return "" unless ($filename); return $store->getUrl($filename); diff --git a/lib/WebGUI/Macro/NewMail.pm b/lib/WebGUI/Macro/NewMail.pm index 2debd1531..1ba2b6a61 100644 --- a/lib/WebGUI/Macro/NewMail.pm +++ b/lib/WebGUI/Macro/NewMail.pm @@ -29,7 +29,7 @@ sub _createURL { my $session = shift; my $text = shift; my $class = shift; - my $url = '
    url->page("op=account;module=inbox").'"'; $url .= ' class="'.$class.'"' if($class); $url .= '>'.$text.''; return $url; diff --git a/lib/WebGUI/Macro/User.pm b/lib/WebGUI/Macro/User.pm index af451c7d1..6e90d01f6 100644 --- a/lib/WebGUI/Macro/User.pm +++ b/lib/WebGUI/Macro/User.pm @@ -18,19 +18,34 @@ Package WebGUI::Macro::User =head1 DESCRIPTION -Macro for displaying information from the current User's profile. +Macro for displaying information from the a User's profile. -=head2 process( field ) +=head2 process( field [, userId] ) -process takes a single parameter, the name of a field in the current user's User Profile from -the data stored in $session . If the field does not exist, undef is returned. +This macro tries to return the profile field passed in for the user +passed in. If not user is passed in, the current user in session +will be used. + +=head3 field + + =cut #------------------------------------------------------------------- sub process { - my $session = shift; - return $session->user->profileField(shift); + my $session = shift; + my $field = shift; + my $userId = shift; + + return undef unless ($field); + + my $user = ($userId) + ? WebGUI::User->new($session,$userId) + : $session->user + ; + + return $user->profileField($field); } diff --git a/lib/WebGUI/Operation.pm b/lib/WebGUI/Operation.pm index 12ab28ab5..10e528fc6 100644 --- a/lib/WebGUI/Operation.pm +++ b/lib/WebGUI/Operation.pm @@ -135,20 +135,14 @@ sub getOperations { 'viewInbox' => 'Inbox', 'viewInboxMessage' => 'Inbox', 'sendPrivateMessage' => 'Inbox', - 'sendPrivateMessageSave' => 'Inbox', - 'deletePrivateMessage' => 'Inbox', 'inviteUser' => 'Invite', 'inviteUserSave' => 'Invite', 'acceptInvite' => 'Invite', 'addFriend' => 'Friends', - 'addFriendSave' => 'Friends', 'friendRequest' => 'Friends', - 'friendRequestSave' => 'Friends', 'manageFriends' => 'Friends', - 'removeFriends' => 'Friends', - 'sendMessageToFriends' => 'Friends', 'copyLDAPLink' => 'LDAPLink', 'deleteLDAPLink' => 'LDAPLink', @@ -159,7 +153,6 @@ sub getOperations { 'viewLoginHistory' => 'LoginHistory', 'editProfile' => 'Profile', - 'editProfileSave' => 'Profile', 'viewProfile' => 'Profile', 'deleteProfileCategory' => 'ProfileSettings', diff --git a/lib/WebGUI/Operation/Friends.pm b/lib/WebGUI/Operation/Friends.pm index 6334aab51..350ce1096 100644 --- a/lib/WebGUI/Operation/Friends.pm +++ b/lib/WebGUI/Operation/Friends.pm @@ -25,373 +25,53 @@ Package WebGUI::Operation::Friends Operation handler for handling the friends network. +DEPRECATED - Do not use this package in new code. + =cut #------------------------------------------------------------------- =head2 www_addFriend ( ) -Form for inviting a user to become your friend. +DEPRECATED - See WebGUI::Account::Friends::sendFriendsRequest =cut sub www_addFriend { my $session = shift; - return $session->privilege->insufficient() unless ($session->user->isRegistered); - my $friendId = $session->form->get('userId'); - my $protoFriend = WebGUI::User->new($session, $friendId); - - my $i18n = WebGUI::International->new($session, 'Friends'); - - my $friends = WebGUI::Friends->new($session); - if($friends->isFriend($friendId)) { - my $returnToProfile = sprintf($i18n->get('add to friends profile'),$protoFriend->getFirstName); - my $backUrl = $session->url->append($session->url->getRequestedUrl, 'op=viewProfile;uid='.$friendId); - return $session->style->userStyle( - sprintf($i18n->get("error user is already friend"),$backUrl,$returnToProfile) - ); - } - elsif($friends->isInvited($friendId)) { - my $returnToProfile = sprintf($i18n->get('add to friends profile'),$protoFriend->getFirstName); - my $backUrl = $session->url->append($session->url->getRequestedUrl, 'op=viewProfile;uid='.$friendId); - return $session->style->userStyle( - sprintf($i18n->get("error user is already invited"),$backUrl,$returnToProfile) - ); - } - - # Check for non-existant user id. - if ((!$protoFriend->username) || (!$protoFriend->profileField('ableToBeFriend'))) { - my $output = sprintf qq!

    %s

    \n

    %s

    %s!, - $i18n->get('add to friends'), - $i18n->get('does not want to be a friend'), - $session->url->getBackToSiteURL(), - $i18n->get('493', 'WebGUI'); - return $session->style->userStyle($output); - } - - my $output = join '', - sprintf("

    %s

    \n", $i18n->get('add to friends')), - '

    ', - sprintf($i18n->get('add to friends description'), - $protoFriend->getWholeName), - '

    ', - WebGUI::Form::formHeader($session), - WebGUI::Form::hidden($session, - { - name => 'op', - value => 'addFriendSave', - } - ), - WebGUI::Form::hidden($session, - { - name => 'userId', - value => $friendId, - } - ), - WebGUI::Form::textarea($session, - { - name => 'comments', - value => sprintf($i18n->get('default friend comments'), $protoFriend->getFirstName, $session->user->getFirstName), - } - ), - WebGUI::Form::Submit($session, - { - value => $i18n->get('add') - } - ), - WebGUI::Form::Button($session, - { - value => $i18n->get('cancel', 'WebGUI'), - extras => q|onclick="history.go(-1);" class="backwardButton"|, - } - ), - WebGUI::Form::formFooter($session), - ; - return $session->style->userStyle($output); + my $uid = $session->form->process("userId"); + my $instance = WebGUI::Content::Account->createInstance($session,"friends"); + return $instance->displayContent($instance->callMethod("sendFriendsRequest",[],$uid)); } -#------------------------------------------------------------------- - -=head2 www_addFriendSave ( ) - -Post process the form, check for required fields, handle inviting users who are already -members (determined by email address) and send the email. - -=cut - -sub www_addFriendSave { - my $session = shift; - return $session->privilege->insufficient() unless ($session->user->isRegistered); - - my $friendId = $session->form->get('userId'); - my $protoFriend = WebGUI::User->new($session, $friendId); - my $i18n = WebGUI::International->new($session, 'Friends'); - - my $friends = WebGUI::Friends->new($session); - if($friends->isFriend($friendId) || $friends->isInvited($friendId)) { - return www_addFriend($session); - } - - # Check for non-existant user id. - if ((!$protoFriend->username) || (!$protoFriend->profileField('ableToBeFriend'))) { - my $output = sprintf qq!

    %s

    \n

    %s

    %s!, - $i18n->get('add to friends'), - $i18n->get('does not want to be a friend'), - $session->url->getBackToSiteURL(), - $i18n->get('493', 'WebGUI'); - return $session->style->userStyle($output); - } - - my $friends = WebGUI::Friends->new($session); - $friends->sendAddRequest($friendId, $session->form->get('comments')); - - # display result - my $output = sprintf( - q!

    %s

    %s

    %s

    %s

    !, - $i18n->get('add to friends'), - sprintf($i18n->get('add to friends confirmation'), $protoFriend->getWholeName), - $session->url->append($session->url->getRequestedUrl, 'op=viewProfile;uid='.$friendId), - sprintf($i18n->get('add to friends profile'), $protoFriend->getFirstName), - $session->url->getBackToSiteURL(), - $i18n->get('493', 'WebGUI'), - ); - return $session->style->userStyle($output); -} #------------------------------------------------------------------- =head2 www_friendRequest ( ) -Form for the friend to accept or deny the request. +DEPRECATED - See WebGUI::Account::Inbox::viewInvitation =cut sub www_friendRequest { my $session = shift; - return $session->privilege->insufficient() unless ($session->user->isRegistered); - - my $i18n = WebGUI::International->new($session, 'Friends'); - - my $inviteId = $session->form->get('inviteId'); - my $friends = WebGUI::Friends->new($session); - - my $invitation = $friends->getAddRequest($inviteId); - - ##Invalid invite ID - unless (exists $invitation->{friendId}) { ##No userId corresponds to the inviteId - my $output = sprintf qq!

    %s

    \n

    %s

    %s!, - $i18n->get('invalid invite code'), - $i18n->get('invalid invite code message'), - $session->url->page("op=viewInbox"), - $i18n->get('354', 'WebGUI'); - return $session->style->userStyle($output); - } - - ##Already a friend (check friendId already in the group) - if ($friends->isFriend($invitation->{inviterId})) { - my $output = sprintf qq!

    %s

    \n

    %s

    %s!, - $i18n->get('invalid invite code'), - $i18n->get('already a friend'), - $session->url->page("op=viewInbox"), - $i18n->get('354', 'WebGUI'); - return $session->style->userStyle($output); - } - - ##Someone else's invite (check friendId vs current userId). - if ($session->user->userId ne $invitation->{friendId}) { ##This isn't your invitation, dude. - my $output = sprintf qq!

    %s

    \n

    %s

    %s!, - $i18n->get('invalid invite code'), - $i18n->get('not the right user'), - $session->url->page("op=viewInbox"), - $i18n->get('354', 'WebGUI'); - return $session->style->userStyle($output); - } - - ##Everything looks good. Make the form! - my $inviter = WebGUI::User->new($session, $invitation->{inviterId}); - my $output = join '', - sprintf("

    %s

    \n", $i18n->get('friend request')), - '

    ', - sprintf($i18n->get('friend request description'), - $inviter->getWholeName), - '

    ', - WebGUI::Form::formHeader($session), - WebGUI::Form::hidden($session, - { - name => 'op', - value => 'friendRequestSave', - } - ), - WebGUI::Form::hidden($session, - { - name => 'inviteId', - value => $inviteId, - } - ), - WebGUI::Form::textarea($session, - { - name => 'comments', - value => $invitation->{comments}, - extras => 'disabled=disabled', - } - ), - WebGUI::Form::Submit($session, ##Approve - { - name => 'doWhat', - value => $i18n->get('572', 'WebGUI'), - } - ), - WebGUI::Form::Submit($session, ##Deny - { - name => 'doWhat', - value => $i18n->get('574', 'WebGUI'), - } - ), - WebGUI::Form::formFooter($session), - ; - return $session->style->userStyle($output); -} - -#------------------------------------------------------------------- - -=head2 www_friendRequestSave ( ) - -Handle form data from the friend's response to the invitation - -=cut - -sub www_friendRequestSave { - my $session = shift; - return $session->privilege->insufficient() unless ($session->user->isRegistered); - - my $i18n = WebGUI::International->new($session, 'Friends'); - my $doWhat = $session->form->get('doWhat'); - my $inviteId = $session->form->get('inviteId'); - my $friends = WebGUI::Friends->new($session); - my $invite = $friends->getAddRequest($inviteId); - my $inviter = WebGUI::User->new($session, $invite->{inviterId}); - ##Invalid invite ID - if (!$invite->{inviterId}) { ##No userId corresponds to the inviteId - my $output = sprintf qq!

    %s

    \n

    %s

    %s!, - $i18n->get('invalid invite code'), - $i18n->get('invalid invite code message'), - $session->url->page("op=viewInbox"), - $i18n->get('354', 'WebGUI'); - return $session->style->userStyle($output); - } - - ##If deny, change the status of the request to denied. - if ($doWhat ne $i18n->get('572', 'WebGUI')) { ##request denied - $friends->rejectAddRequest($inviteId); - ##Return screen that says they denied the request. - my $output = sprintf qq!

    %s

    \n

    %s

    %s!, - $i18n->get('friend request'), - sprintf($i18n->get('you have not been added'), $inviter->getWholeName), - $session->url->page("op=viewInbox"), - $i18n->get('354', 'WebGUI'); - return $session->style->userStyle($output); - } - - ##If accepted, - # set the status to accepted. - $friends->approveAddRequest($inviteId); - - # Return screen that says they accepted the request. - my $output = sprintf qq!

    %s

    \n

    %s

    %s!, - $i18n->get('friend request'), - sprintf($i18n->get('you have been added'), $inviter->getWholeName), - $session->url->page("op=viewInbox"), - $i18n->get('354', 'WebGUI'); - return $session->style->userStyle($output); + my $instance = WebGUI::Content::Account->createInstance($session,"inbox"); + return $instance->displayContent($instance->callMethod("viewInvitation")); } #------------------------------------------------------------------- =head2 www_manageFriends ( ) -Display the list of friends and allow the user to remove friends or -send private messages to a subset of them. + +DEPRECATED - See WebGUI::Account::Friends::view =cut sub www_manageFriends { my $session = shift; - my ($user, $url, $style) = $session->quick(qw(user url style)); - return $session->privilege->insufficient() unless ($user->isRegistered); - my $i18n = WebGUI::International->new($session, 'Friends'); - - ##You have no friends! - my $friends = $user->friends->getUsers; - unless (scalar(@{$friends})) { - my $output = sprintf qq!

    %s

    \n

    %s

    %s!, - $i18n->get('my friends'), - $i18n->get('no friends'), - $url->getBackToSiteURL(), - $i18n->get('493', 'WebGUI'); - return $style->userStyle($output); - } - - # show the friend manager - my %var = ( - "account.options" => WebGUI::Operation::Shared::accountOptions($session), - formHeader => WebGUI::Form::formHeader($session) - . WebGUI::Form::hidden($session, { name => 'op', value => 'sendMessageToFriends', }), - removeFriendButton => WebGUI::Form::button($session, { value => $i18n->get('remove'), extras => q|onclick="confirmRemovalOfFriends(form);"|, }), - subjectForm => WebGUI::Form::text($session, { name=>"subject" }), - sendMessageButton => WebGUI::Form::Submit($session, { value => $i18n->get('send message'), }), - messageForm => WebGUI::Form::textarea($session, { name=>"message" }), - formFooter => WebGUI::Form::formFooter($session), - ); - foreach my $userId (@{ $friends}) { - my $friend = WebGUI::User->new($session, $userId); - push(@{$var{friends}}, { - name => $friend->getWholeName, - profileUrl => $url->append($url->getRequestedUrl, 'op=viewProfile;uid='.$userId), - status => ($friend->isOnline ? $i18n->get('online') : $i18n->get('offline')), - checkboxForm => WebGUI::Form::checkbox($session, { name => 'userId', value => $userId, }), - }); - } - my $template = WebGUI::Asset->new( - $session, - $session->setting->get("manageFriendsTemplateId"), - "WebGUI::Asset::Template", - ); - return $style->userStyle($template->process(\%var)); -} - - -#------------------------------------------------------------------- - -=head2 www_removeFriends () - -Removes friends from the current user's friends list. - -=cut - -sub www_removeFriends { - my $session = shift; - return $session->privilege->insufficient() unless ($session->user->isRegistered); - my @users = $session->form->param("userId"); - WebGUI::Friends->new($session)->delete(\@users); - return www_manageFriends($session); -} - - -#------------------------------------------------------------------- - -=head2 www_sendMessageToFriends () - -Sends a message to selected friends. - -=cut - -sub www_sendMessageToFriends { - my $session = shift; - return $session->privilege->insufficient() unless ($session->user->isRegistered); - my @users = $session->form->param("userId"); - my $friends = WebGUI::Friends->new($session); - $friends->sendMessage($session->form->process("subject", "text"), $session->form->process("message","textarea"), \@users); - return www_manageFriends($session); + my $instance = WebGUI::Content::Account->createInstance($session,"friends"); + return $instance->displayContent($instance->callMethod("view")); } 1; diff --git a/lib/WebGUI/Operation/Inbox.pm b/lib/WebGUI/Operation/Inbox.pm index 89bbe5a9f..b0753035f 100644 --- a/lib/WebGUI/Operation/Inbox.pm +++ b/lib/WebGUI/Operation/Inbox.pm @@ -79,18 +79,23 @@ sub _appendPrivateMessageForm { name=>"message", value=>$form->get("message") || "", }); - - my $messageId = $form->get("messageId") || $message->getId; + + my $messageId = ""; + if($form->get("messageId")) { + $messageId = $form->get("messageId"); + } + elsif(defined $message) { + $messageId = $message->getId; + } + $vars->{'form_header' } = WebGUI::Form::formHeader($session,{ - action => $session->url->page->("op=account;module=inbox;do=sendMessageSave;messageId=$messageId;userId=$userTo->userId"), + action => $session->url->page("op=account;module=inbox;do=sendMessageSave;messageId=$messageId;userId=".$userTo->userId), extras => q{name="messageForm"} }); $vars->{ submit_button } = WebGUI::Form::submit($session,{}); $vars->{ submit_label } = $i18n->get("private message submit label"); $vars->{ form_footer } = WebGUI::Form::formFooter($session, {}); - - } #------------------------------------------------------------------- @@ -99,263 +104,42 @@ sub _appendPrivateMessageForm { returns a hashref with internationalized values for message status. -DEPRECATED: Use WebGUI::Inbox::Message->statusCodes +DEPRECATED: Do not use this method in new code. Use WebGUI::Inbox::Message->statusCodes =cut sub _status { my $session = shift; return WebGUI::Inbox::Message->statusCodes($session); - #my $i18n = WebGUI::International->new($session); - #return { - # "pending" =>$i18n->get(552), - # "completed" =>$i18n->get(350), - # "unread" =>$i18n->get("private message status unread"), - # "read" =>$i18n->get("private message status read"), - # "replied" =>$i18n->get("private message status replied"), - #}; } #------------------------------------------------------------------- =head2 www_sendPrivateMessage ( ) -DEPRECATED: Use WebGUI::Account::Inbox - -Form for sending private messages +DEPRECATED: See WebGUI::Account::Inbox::sendMessage =cut sub www_sendPrivateMessage { - my $session = shift; - return $session->privilege->insufficient() unless ($session->user->isRegistered); - - my $i18n = WebGUI::International->new($session); - my $form = $session->form; - my $user = $session->user; - my $style = $session->style; - my $settings = $session->setting; - - my $templateId = $settings->get("sendPrivateMessageTemplateId"); - my $uid = $form->get("uid"); - my $userTo = WebGUI::User->new($session,$uid); - - my $vars = {}; - $vars->{title} = $i18n->get('private message title'); - - if($uid eq "") { - $vars->{'error_msg'} = $i18n->get('private message no user'); - return $style->userStyle(WebGUI::Asset::Template->new($session,$templateId)->process($vars)); - - } - elsif($uid eq $user->userId) { - $vars->{'error_msg'} = $i18n->get('private message no self error'); - return $style->userStyle(WebGUI::Asset::Template->new($session,$templateId)->process($vars)); - } - - unless($userTo->acceptsPrivateMessages($user->userId)) { - $vars->{'error_msg'} = $i18n->get('private message blocked error'); - return $style->userStyle(WebGUI::Asset::Template->new($session,$templateId)->process($vars)); - } - - _appendPrivateMessageForm($session,$vars,$userTo); - - $vars->{ accountOptions } = WebGUI::Operation::Shared::accountOptions($session); - - return $style->userStyle(WebGUI::Asset::Template->new($session,$templateId)->process($vars)); + my $session = shift; + my $uid = $session->form->get("uid"); + my $instance = WebGUI::Content::Account->createInstance($session,"inbox"); + return $instance->displayContent($instance->callMethod("sendMessage",[],$uid)); } -#------------------------------------------------------------------- - -=head2 www_sendPrivateMessageSave ( ) - -DEPRECATED: Use WebGUI::Account::Inbox - -Post process the form, check for required fields, handle inviting users who are already -members (determined by email address) and send the email. - -=cut - -sub www_sendPrivateMessageSave { - my $session = shift; - return $session->privilege->insufficient() unless ($session->user->isRegistered); - - my $i18n = WebGUI::International->new($session); - my $form = $session->form; - my $user = $session->user; - my $style = $session->style; - - my $uid = $form->get("uid"); - my $userTo = WebGUI::User->new($session,$uid); - - if($uid eq "") { - my $output = sprintf qq|

    %s

    \n

    %s

    %s|, - $i18n->get('private message error'), - $i18n->get('private message no user'), - $session->url->getBackToSiteURL(), - $i18n->get('493', 'WebGUI'); - return $style->userStyle($output); - } elsif($uid eq $user->userId) { - my $output = sprintf qq|

    %s

    \n

    %s

    %s|, - $i18n->get('private message error'), - $i18n->get('private message no self error'), - $session->url->getBackToSiteURL(), - $i18n->get('493', 'WebGUI'); - return $style->userStyle($output); - } - - my $isReply = 0; - if($form->get("messageId")) { - my $message = WebGUI::Inbox->new($session)->getMessage($form->get("messageId")); - # Ensure that the user sending the message was sent by the user being replied to - # and that the user reponding is the user the message was sent to - if($message->get("sentBy") eq $uid && $message->get("userId") eq $user->userId) { - $isReply = 1; - $message->setStatus("replied"); - } - } - - my $message = WebGUI::Inbox->new($session)->addPrivateMessage({ - message => $form->get("message"), - subject => $form->get("subject"), - userId => $uid, - status => 'unread', - sentBy => $user->userId - },$isReply); - - unless(defined $message) { - my $output = sprintf qq|

    %s

    \n

    %s

    %s|, - $i18n->get('private message error'), - $i18n->get('private message blocked error'), - $session->url->getBackToSiteURL(), - $i18n->get('493', 'WebGUI'); - return $style->userStyle($output); - } - - - my $output = sprintf qq!

    %s

    %s!, - $i18n->get('private message sent'), - $session->url->getBackToSiteURL(), - $i18n->get('493', 'WebGUI'); - return $session->style->userStyle($output); - -} - - #------------------------------------------------------------------- =head2 www_viewInbox ( ) -DEPRECATED: Use WebGUI::Account::Inbox - -Templated display all messages for the current user. +DEPRECATED: See WebGUI::Account::Inbox::view =cut sub www_viewInbox { my $session = shift; - return $session->privilege->insufficient() unless ($session->user->isRegistered); - - my $i18n = WebGUI::International->new($session); - my $vars = {}; - my @msg = (); - my $rpp = 50; - - #Deal with page number - my $pn = $session->form->get("pn") || 1; - my $pn_url = ""; - $pn_url = ";pn=$pn"; - - #Deal with sort order - my $sortBy = $session->form->get("sortBy"); - my $sort_url = ""; - $sort_url = ";sortBy=$sortBy" if($sortBy); - - #Cache the base url - my $inboxUrl = $session->url->page('op=viewInbox'); - - $vars->{ title } = $i18n->get(159); - $vars->{'subject_label' } = $i18n->get(351); - $vars->{'subject_url' } = $inboxUrl.$pn_url.";sortBy=subject"; - - $vars->{'status_label' } = $i18n->get(553); - $vars->{'status_url' } = $inboxUrl.$pn_url.";sortBy=status"; - - $vars->{'from_label' } = $i18n->get("private message from label"); - $vars->{'from_url' } = $inboxUrl.$pn_url.";sortBy=sentBy"; - - $vars->{'dateStamp_label'} = $i18n->get(352); - $vars->{'dateStamp_url' } = $inboxUrl.$pn_url.";sortBy=dateStamp"; - - my $adminUser = WebGUI::User->new($session,3)->username; - my $messages = WebGUI::Inbox->new($session)->getMessagesForUser($session->user,$rpp,$pn,$sortBy); - foreach my $message (@$messages) { - next if($message->get('status') eq 'deleted'); - - my $hash = {}; - $hash->{ message_url } = $session->url->page('op=viewInboxMessage;messageId='.$message->getId); - $hash->{ subject } = $message->get("subject"); - $hash->{ status_class } = $message->get("status"); - $hash->{ status } = _status($session)->{$hash->{ status_class }}; - - #Get the username of the person who sent the message - my $sentBy = $message->get("sentBy"); - #Assume it's the admin user for speed purposes - admin user is cached above the loop - my $from = $adminUser; - #If it wasn't the admin user, get the username of the person who sent it - if($sentBy ne "3") { - my $u = WebGUI::User->new($session,$sentBy); - #If the user that sent the message is valid, get the username - #This case would happen if the user was deleted after sending a private message - if($u->isRegistered) { - $from = $u->username; - } - } - - $hash->{ from } = $from; - $hash->{ dateStamp } = $session->datetime->epochToHuman($message->get("dateStamp")); - push(@msg,$hash); - } - my $msgCount = scalar(@{$messages}); - - #Pagination has to exist on every page regardless if there are more messages or not. - if($pn > 1 ) { - $vars->{'prev_url' } = $inboxUrl.';pn='.($pn-1).$sort_url; - $vars->{'prev_label' } = $i18n->get("private message prev label"); - } - if (scalar(@msg) >= $rpp) { - $vars->{'next_url' } = $inboxUrl.';pn='.($pn+1).$sort_url; - $vars->{'next_label' } = $i18n->get("private message next label"); - } - - $vars->{'messages' } = \@msg; - $vars->{'noresults' } = $i18n->get(353) unless ($msgCount > 0); - $vars->{'accountOptions'} = WebGUI::Operation::Shared::accountOptions($session); - my $templateId = $session->setting->get("viewInboxTemplateId"); - return $session->style->userStyle(WebGUI::Asset::Template->new($session,$templateId)->process($vars)); -} - -#------------------------------------------------------------------- - -=head2 www_deletePrivateMessage ( ) - -DEPRECATED: Use WebGUI::Account::Inbox - -Mark a private message in the inbox as deleted. - -=cut - -sub www_deletePrivateMessage { - my $session = shift; - return $session->privilege->insufficient() unless ($session->user->isRegistered); - - #Get the message - my $message = WebGUI::Inbox->new($session)->getMessage($session->form->param("messageId")); - if(defined $message) { - # set the message status to 'deleted' - $message->setStatus("deleted"); - } - return www_viewInbox($session); + my $instance = WebGUI::Content::Account->createInstance($session,"inbox"); + return $instance->displayContent($instance->callMethod("view")); } #------------------------------------------------------------------- @@ -370,68 +154,8 @@ Templated display of a single message for the user. sub www_viewInboxMessage { my $session = shift; - return $session->privilege->insufficient() unless ($session->user->isRegistered); - - #Get the message - my $message = WebGUI::Inbox->new($session)->getMessage($session->form->param("messageId")); - - #Make sure users can only read their own messages - my $userId = $message->get("userId"); - my $groupId = $message->get("groupId"); - return $session->privilege->insufficient() unless ( - $session->user->userId eq $userId - || (defined $groupId && $session->user->isInGroup($groupId)) - ); - - my $i18n = WebGUI::International->new($session); - my $vars = {}; - $vars->{ title } = $i18n->get("private message reply title"); - $vars->{ from_label } = $i18n->get("private message from label"); - $vars->{ date_label } = $i18n->get("private message date label"); - - - if (defined $message) { - my $origStatus = $message->get("status"); - $message->setStatus("read") if($origStatus eq "unread"); - $vars->{'message_subject' } = $message->get("subject"); - $vars->{'dateStamp'} =$session->datetime->epochToHuman($message->get("dateStamp")); - $vars->{'status' } = _status($session)->{$message->get("status")}; - $vars->{ message } = $message->get("message"); - $vars->{ delete_text } = $i18n->get("private message delete text"); - $vars->{ delete_url } = '?op=deletePrivateMessage;messageId=' . $message->getId; - unless ($vars->{message} =~ /\{message} =~ s/(http\S*)/\$1\<\/a\>/g; - } - unless ($vars->{message} =~ /\
    {message} =~ /\
    {message} =~ /\

    {message} =~ s/\n/\
    \n/g; - } - - #Get the username of the person who sent the message - my $sentBy = $message->get("sentBy"); - #Assume it's the admin user who sent the message - my $from = WebGUI::User->new($session,3)->username; - #If the user actually exists, get the username - if($sentBy ne "1" && $sentBy ne "3") { - $from = WebGUI::User->new($session,$sentBy)->username; - } - - $vars->{ from } = $from; - - - #If the person didn't send the message to themselves (for admin only) and the user still exsists (check visitor case) - if($sentBy ne $session->user->userId && - $sentBy ne "1" && - $origStatus ne "pending" && - $origStatus ne "completed") { - my $u = WebGUI::User->new($session,$sentBy); - $vars->{'canReply'} = "true"; - _appendPrivateMessageForm($session,$vars,$u,$message); - } - - } - $vars->{'accountOptions'} = WebGUI::Operation::Shared::accountOptions($session); - my $templateId = $session->setting->get("viewInboxMessageTemplateId"); - return $session->style->userStyle(WebGUI::Asset::Template->new($session,$templateId)->process($vars)); + my $instance = WebGUI::Content::Account->createInstance($session,"inbox"); + return $instance->displayContent($instance->callMethod("viewMessage")); } 1; diff --git a/lib/WebGUI/Operation/Profile.pm b/lib/WebGUI/Operation/Profile.pm index 4abf01362..eae334075 100644 --- a/lib/WebGUI/Operation/Profile.pm +++ b/lib/WebGUI/Operation/Profile.pm @@ -24,6 +24,7 @@ use WebGUI::ProfileField; use WebGUI::ProfileCategory; use WebGUI::Operation::Shared; use WebGUI::Operation::Friends; +use WebGUI::Account::Profile; =head1 NAME @@ -92,12 +93,9 @@ email address to check for duplication sub isDuplicateEmail { my $session = shift; my $email = shift; - my ($otherEmail) - = $session->db->quickArray( - 'select count(*) from userProfileData where email = ? and userId <> ?', - [$email, $session->user->userId] - ); - return ($otherEmail > 0); + + my $field = WebGUI::ProfileField->new($session,'email'); + return $field->isDuplicate($email); } #------------------------------------------------------------------- @@ -107,7 +105,7 @@ sub isDuplicateEmail { Saves profile data to a user's profile. Does not validate any of the data. DEPRECATED - This method is deprecated, and should not be used in new code. Use -the saveProfileFields method from WebGUI::Account::Profile instead +the updateProfileFields method in WebGUI::User =head3 session @@ -127,8 +125,7 @@ sub saveProfileFields { my $session = shift; my $u = shift; my $profile = shift; - - WebGUI::Account::Profile->saveProfileFields($session,$u,$profile); + $u->updateProfileFields($profile); } #------------------------------------------------------------------- @@ -139,7 +136,7 @@ Validates profile data from the session form variables. Returns processed data, and errors. DEPRECATED - This method is deprecated, and should not be used in new code. Use -the validateProfileData method from WebGUI::Account::Profile instead +the validateProfileDataFromForm method from WebGUI::User instead There are two levels of validation: @@ -159,48 +156,38 @@ warning if it is a duplicate. =cut sub validateProfileData { - my $session = shift; - my $opts = shift || {}; - my $regOnly = $opts->{regOnly}; - my %data = (); - my $error = ""; - my $warning = ""; - my $i18n = WebGUI::International->new($session); - my $fields = $regOnly ? WebGUI::ProfileField->getRegistrationFields($session) + my $session = shift; + my $opts = shift || {}; + my $regOnly = $opts->{regOnly}; + + my $error = ""; + my $warning = ""; + my $fields = $regOnly ? WebGUI::ProfileField->getRegistrationFields($session) : WebGUI::ProfileField->getEditableFields($session); - foreach my $field (@$fields) { - my $fieldValue = $field->formProcess; - if (ref $fieldValue eq "ARRAY") { - $data{$field->getId} = $$fieldValue[0]; - } else { - $data{$field->getId} = $fieldValue; - } - if ($field->isRequired && $data{$field->getId} eq "") { - $error .= '

  • '.$field->getLabel.' '.$i18n->get(451).'
  • '; - } elsif ($field->getId eq "email" && isDuplicateEmail($session,$data{$field->getId}) && WebGUI::ProfileField->new($session, "email")->isRequired() ) { - $warning .= '
  • '.$i18n->get(1072).'
  • '; - } - if ($field->getId eq "language" && $fieldValue ne "") { - unless (exists $i18n->getLanguages()->{$fieldValue}) { - $error .= '
  • '.$field->getLabel.' '.$i18n->get(451).'
  • '; - } - } - } - return (\%data, $error, $warning); + + my $retHash = $session->user->validateProfileDataFromForm($fields); + + use Data::Dumper; + print Dumper($retHash)."\n\n\n"; + + my $warnings = $retHash->{warnings}; + my $errors = $retHash->{errors}; + + my $format = "
  • %s
  • "; + my $warning = ""; + my $error = ""; + map { $warning .= sprintf($format,$_) }@{$warnings}; + map { $error .= sprintf($format,$_) }@{$errors}; + + return ($retHash->{profile},$error,$warning); } #------------------------------------------------------------------- =head2 www_editProfile ( session ) -Provide a form where user profile data can be entered or edited. The subroutine -makes a large set of template variables which are passed to a template for presentation -and styling. The default template is PBtmpl0000000000000051 and is not user -selectable. - -DEPRECATED - Use WebGUI::Account::Profile::www_edit - -Calls www_editProfileSave on submission. +DEPRECATED - This method is deprecated, and should not be used in new code. +Use WebGUI::Account::Profile::www_edit =head3 session @@ -209,91 +196,18 @@ A reference to the current session. =cut sub www_editProfile { - my $session = shift; - return WebGUI::Operation::Auth::www_auth($session,"init") if($session->user->isVisitor); - my $i18n = WebGUI::International->new($session); - my $vars = {}; - $vars->{displayTitle} .= $i18n->get(338); - $vars->{'profile.message'} = $_[0] if($_[0]); - $vars->{'profile.form.header'} = "\n\n".WebGUI::Form::formHeader($session,{}); - $vars->{'profile.form.footer'} = WebGUI::Form::formFooter($session,); - - $vars->{'profile.form.hidden'} = WebGUI::Form::hidden($session,{"name"=>"op","value"=>"editProfileSave"}); - $vars->{'profile.form.hidden'} .= WebGUI::Form::hidden($session,{"name"=>"uid","value"=>$session->user->userId}); - my @array = (); - foreach my $category (@{WebGUI::ProfileCategory->getCategories($session)}) { - next unless $category->isEditable; - my @temp = (); - foreach my $field (@{$category->getFields}) { - next unless ($field->isEditable); - next if $field->getId =~ /contentPositions/; - push(@temp, { - 'profile.form.element' => $field->formField, - 'profile.form.element.label' => $field->getLabel, - 'profile.form.element.subtext' => $field->isRequired ? "*" : undef, - 'profile.form.element.extras' => $field->getExtras, - }); - } - push(@array, { - 'profile.form.category' => $category->getLabel, - 'profile.form.category.loop' => \@temp - }); - } - $vars->{'profile.form.elements'} = \@array; - $vars->{'profile.form.submit'} = WebGUI::Form::submit($session,{}); - $vars->{'profile.form.cancel'} = WebGUI::Form::button($session,{ - value => $i18n->get('cancel'), - extras=>q|onclick="history.go(-1);" class="backwardButton"|, - }); - $vars->{'profile.accountOptions'} = WebGUI::Operation::Shared::accountOptions($session); - return $session->style->userStyle(WebGUI::Asset::Template->new($session, $session->setting->get('editUserProfileTemplate'))->process($vars)); + my $session = shift; + my $instance = WebGUI::Content::Account->createInstance($session,"profile"); + return $instance->displayContent($instance->callMethod("edit")); } -#------------------------------------------------------------------- - -=head2 www_editProfileSave ( session ) - -Validates all data submitted by www_editProfile. If errors or warnings are present, -they are concatenated and sent back to www_editProfile for display and to let the user -correct their mistakes. - -If no mistakes are present, saves the data to the user's profile, updates the session user -object. - -Returns the user to WebGUI::Operation::Auth::www_auth when done. - - -DEPRECATED: Use WebGUI::Account::Profile::www_editSave - -=head3 session - -A reference to the current session. - -=cut - -sub www_editProfileSave { - my $session = shift; - my ($profile, $error, $warning); - return WebGUI::Operation::Auth::www_auth($session, "init") if ($session->user->isVisitor); - ($profile, $error, $warning) = validateProfileData($session); - $error .= $warning; - return www_editProfile($session, '
      '.$error.'
    ') if($error ne ""); - foreach my $fieldName (keys %{$profile}) { - $session->user->profileField($fieldName,$profile->{$fieldName}); - } - return WebGUI::Operation::Auth::www_auth($session); -} #------------------------------------------------------------------- =head2 www_viewProfile ( session ) -View the profile data for a user by the userId specified by the form variable C. -Validates that the user requesting the profile data is allowed to see it. -Similarly to www_editProfile, this method is templated. The default template -is PBtmpl0000000000000052. The template is not user selectable. - -DEPRECATED: Use WebGUI::Account::Profile::www_view +DEPRECATED: This method is deprecated, and should not be used in new code. +Use WebGUI::Account::Profile::www_view =head3 session @@ -302,46 +216,10 @@ A reference to the current session. =cut sub www_viewProfile { - my $session = shift; - my $u = WebGUI::User->new($session,$session->form->process("uid")); - my $i18n = WebGUI::International->new($session); - my $vars = {}; - $vars->{displayTitle} = $i18n->get(347).' '.$u->username; - - return $session->privilege->notMember() if($u->username eq ""); - - return $session->style->userStyle($vars->{displayTitle}.'. '.$i18n->get(862)) if($u->profileField("publicProfile") < 1 && ($session->user->userId ne $session->form->process("uid") || $session->user->isAdmin)); - return $session->privilege->insufficient() if(!$session->user->isRegistered); - - my @array = (); - foreach my $category (@{WebGUI::ProfileCategory->getCategories($session)}) { - next unless ($category->get("visible")); - push(@array, {'profile.category' => $category->getLabel}); - foreach my $field (@{$category->getFields}) { - next unless ($field->get("visible")); - next if ($field->get("fieldName") eq "email" && !$u->profileField("publicEmail")); - push @array, { - 'profile.label' => $field->getLabel, - 'profile.value' => $field->formField(undef,2,$u), - 'profile.extras' => $field->getExtras, - }; - } - } - $vars->{'profile.elements'} = \@array; - - if ($session->user->userId eq $session->form->process("uid")) { - $vars->{'profile.accountOptions'} = WebGUI::Operation::Shared::accountOptions($session); - } - else { - ## TODO: Make this more legible code, maybe refactor into a method - push @{$vars->{'profile.accountOptions'}}, { - 'options.display' => '
    userId).'">'.$i18n->get('add to friends list', 'Friends').'', - }, { - 'options.display' => ''.$i18n->get('send private message').'', - }; - } - - return $session->style->userStyle(WebGUI::Asset::Template->new($session, $session->setting->get('viewUserProfileTemplate'))->process($vars)); + my $session = shift; + my $uid = $session->form->process("uid"); + my $instance = WebGUI::Content::Account->createInstance($session,"profile"); + return $instance->displayContent($instance->callMethod("view",[],$uid)); } diff --git a/lib/WebGUI/Operation/Settings.pm b/lib/WebGUI/Operation/Settings.pm index 1c4e83f00..83bc16eb5 100644 --- a/lib/WebGUI/Operation/Settings.pm +++ b/lib/WebGUI/Operation/Settings.pm @@ -226,34 +226,7 @@ sub definition { namespace=>"AdminConsole", defaultValue=>$setting->get("AdminConsoleTemplate") }); - # messaging settings - push(@fields, { - tab=>"messaging", - fieldType=>"template", - name=>"viewInboxTemplateId", - label=>$i18n->get('view inbox template'), - hoverHelp=>$i18n->get('view inbox template description'), - namespace=>"Inbox", - defaultValue=>$setting->get("viewInboxTemplateId"), - }); - push(@fields, { - tab=>"messaging", - fieldType=>"template", - name=>"viewInboxMessageTemplateId", - label=>$i18n->get('view inbox message template'), - hoverHelp=>$i18n->get('view inbox message template description'), - namespace=>"Inbox/Message", - defaultValue=>$setting->get("viewInboxMessageTemplateId"), - }); - push(@fields, { - tab=>"messaging", - fieldType=>"template", - name=>"sendPrivateMessageTemplateId", - label=>$i18n->get('send private message template'), - hoverHelp=>$i18n->get('send private message template description'), - namespace=>"Inbox/SendPrivateMessage", - defaultValue=>$setting->get("sendPrivateMessageTemplateId"), - }); + # messaging settings push(@fields, { tab=>"messaging", fieldType=>"text", @@ -444,15 +417,6 @@ sub definition { namespace=>"userInvite/Email", defaultValue=>$setting->get("userInvitationsEmailTemplateId"), }); - push(@fields, { - tab => "user", - fieldType => "template", - defaultValue => "managefriends_________", - namespace => "friends/manage", - name => "manageFriendsTemplateId", - label => $i18n->get("manage friends template", "Friends"), - hoverHelp => $i18n->get("manage friends template help", "Friends"), - }); push @fields, { tab => "user", name => "showMessageOnLogin", @@ -485,24 +449,7 @@ sub definition { hoverHelp => $i18n->get( 'showMessageOnLoginBody description' ), defaultValue => $setting->get('showMessageOnLoginBody'), }; - push @fields, { - tab => "user", - name => 'viewUserProfileTemplate', - fieldType => 'template', - namespace => 'Operation/Profile/View', - label => $i18n->get( 'user profile view template' ), - hoverHelp => $i18n->get( 'user profile view template description' ), - defaultValue => $setting->get('viewUserProfileTemplate'), - }; - push @fields, { - tab => "user", - name => 'editUserProfileTemplate', - fieldType => 'template', - namespace => 'Operation/Profile/Edit', - label => $i18n->get( 'user profile edit template' ), - hoverHelp => $i18n->get( 'user profile edit template description' ), - defaultValue => $setting->get('editUserProfileTemplate'), - }; + # auth settings my $options; foreach (@{$session->config->get("authMethods")}) { @@ -638,14 +585,18 @@ sub www_editSettings { #Create the instance my $className = $account->{className}; my $instance = eval { WebGUI::Pluggable::instanciate($className,"new",[ $session ]) }; - - if ( my $e = WebGUI::Error->caught ) { + if ( $@ ) { $session->log->warn("Could not instantiate account pluggin $className...skipping"); next; } #Get the content of the settings form from the instance - my $settingsForm = $instance->editSettingsForm; + my $settingsForm = eval { $instance->editSettingsForm }; + if( $@ ) { + $session->log->warn("Error calling editSettingsForm in $className...skipping : ".$@); + next; + } + #If editUserSettingsForm is empty, skip it next if $settingsForm eq ""; @@ -710,7 +661,12 @@ sub www_saveSettings { next; } #Save the settings - $instance->editSettingsFormSave; + eval { $instance->editSettingsFormSave }; + + if( my $e = WebGUI::Error->caught ) { + $session->log->warn("Error calling editSettingsFormSave in $className...skipping : ".$e->error); + next; + } } diff --git a/lib/WebGUI/Operation/Shared.pm b/lib/WebGUI/Operation/Shared.pm index f2354d022..8b11d46b5 100644 --- a/lib/WebGUI/Operation/Shared.pm +++ b/lib/WebGUI/Operation/Shared.pm @@ -27,71 +27,18 @@ Shared routines for WebGUI Operations. TODO: DOCUMENT ME +DEPRECATED - USE WebGUI::Account::User->appendAccountOptions + =cut #------------------------------------------------------------------- sub accountOptions { my $session = shift; - my $i18n = WebGUI::International->new($session); - my @array; - my $op = $session->form->process("op"); - if ($session->user->isInGroup(12)) { - my %hash; - if ($session->var->isAdminOn) { - $hash{'options.display'} .= ''.$i18n->get(12).''; - } else { - $hash{'options.display'} .= ''.$i18n->get(63).''; - } - push(@array,\%hash); - } - unless ($op eq "displayAccount"){ - my %hash; - $hash{'options.display'} = ''.$i18n->get(342).''; - push(@array,\%hash); - } - unless ($op eq "editProfile"){ - my %hash; - $hash{'options.display'} = ''.$i18n->get(341).''; - push(@array,\%hash); - } - unless ($op eq "viewProfile"){ - my %hash; - $hash{'options.display'} = ''.$i18n->get(343).''; - push(@array,\%hash); - } - unless ($op eq "viewInbox"){ - my %hash; - $hash{'options.display'} = ''.$i18n->get(354).''; - push(@array,\%hash); - } - push(@array, {'options.display' => ''.$i18n->get('my purchases', 'Shop').''}); - - if ($session->setting->get('userInvitationsEnabled')) { - push @array, { - 'options.display' => sprintf('%s', $session->url->page('op=inviteUser'), $i18n->get('invite a friend')), - }; - } - unless ($op eq "manageFriends") { - push @array, { - 'options.display' => sprintf('%s', $session->url->page('op=manageFriends'), $i18n->get('see my friends', 'Friends')), - }; - } - my %logout; - $logout{'options.display'} = ''.$i18n->get(64).''; - push(@array,\%logout); - if ($session->setting->get("selfDeactivation") && !$session->user->isAdmin){ - my %hash; - $hash{'options.display'} = ''.$i18n->get(65).''; - push(@array,\%hash); - } - { ##Return to site link - my %hash; - $hash{'options.display'} = ''.$i18n->get(493).''; - push(@array,\%hash); - } - - return \@array; + my $vars = {}; + WebGUI::Account->appendAccountLinks($session,$vars); + + return $vars->{'account.options'}; } diff --git a/lib/WebGUI/ProfileField.pm b/lib/WebGUI/ProfileField.pm index ec4a493d2..690b0cd61 100644 --- a/lib/WebGUI/ProfileField.pm +++ b/lib/WebGUI/ProfileField.pm @@ -484,15 +484,13 @@ value to check for duplicates against =cut sub isDuplicate { - my $self = shift; - my $session = $self->session; - - my $fieldId = $self->getId; - my $value = shift; - - my $sql = qq{select count(*) from userProfileData where $fieldId = ? and userId <> ?}; - my ($duplicate) = $session->db->quickArray($sql,[$value, $session->user->userId]); + my $self = shift; + my $session = $self->session; + my $fieldId = $self->getId; + my $value = shift; + my $sql = qq{select count(*) from userProfileData where $fieldId = ? and userId <> ?}; + my $duplicate = $session->db->quickScalar($sql,[$value, $session->user->userId]); return ($duplicate > 0); } diff --git a/lib/WebGUI/Shop/Transaction.pm b/lib/WebGUI/Shop/Transaction.pm index f9599cacd..6f977ac15 100644 --- a/lib/WebGUI/Shop/Transaction.pm +++ b/lib/WebGUI/Shop/Transaction.pm @@ -519,7 +519,12 @@ Displays the default thank you page. sub thankYou { my ($self) = @_; my $i18n = WebGUI::International->new($self->session,'Shop'); - return $self->www_viewMy($self->session, $self, $i18n->get('thank you message')); + #return $self->www_viewMy($self->session, $self, $i18n->get('thank you message')); + + #Otherwise wrap the template into the account layout + my $args = [$self,$i18n->get('thank you message')]; + my $instance = WebGUI::Content::Account->createInstance($self->session,"shop"); + return $instance->displayContent($instance->callMethod("viewTransaction",$args)); } @@ -821,6 +826,8 @@ STOP Display a quick list of the user's transactions, with links for more detailed information about each one in the list. +DEPRECATED - Use WebGUI::Account::Shop + =cut sub www_manageMy { diff --git a/lib/WebGUI/Storage.pm b/lib/WebGUI/Storage.pm index 0f07d3b35..228a0b066 100644 --- a/lib/WebGUI/Storage.pm +++ b/lib/WebGUI/Storage.pm @@ -226,13 +226,10 @@ sub addFileFromFormPost { require Apache2::Upload; my $filename; my $attachmentCount = 1; - $self->session->log->warn("trying to uplaod: ".$formVariableName); foreach my $upload ($self->session->request->upload($formVariableName)) { - $self->session->errorHandler->warn("Trying to get " . $upload->filename); + $self->session->errorHandler->info("Trying to get " . $upload->filename); return $filename if $attachmentCount > $attachmentLimit; my $tempFilename = $upload->filename(); - $self->session->log->warn("templFile is: ".$tempFilename); - next unless $tempFilename; next unless $upload->size > 0; next if ($upload->size > 1024 * $self->session->setting->get("maxAttachmentSize")); diff --git a/lib/WebGUI/User.pm b/lib/WebGUI/User.pm index 57c63ab34..64a6fd55b 100644 --- a/lib/WebGUI/User.pm +++ b/lib/WebGUI/User.pm @@ -129,7 +129,7 @@ sub acceptsPrivateMessages { return $sentBy->isInGroup($friendsGroup->getId); } - return 1; + return 0; } #------------------------------------------------------------------- @@ -145,16 +145,19 @@ WebGUI::User object to check to see if user will accept requests from. =cut sub acceptsFriendsRequests { - my $self = shift; - my $user = shift; + my $self = shift; + my $session = $self->session; + my $user = shift; return 0 unless ($user && ref $user eq "WebGUI::User"); #Sanity checks return 0 if($self->isVisitor); #Visitors can't have friends return 0 if($self->userId eq $user->userId); #Can't be your own friend (why would you want to be?) - my $friends = WebGUI::Friends->new($self->session,$self); - return 0 if ($friends->isFriend($user->userId)); #Already a friend - return 0 if ($friends->isInvited($user->userId)); #Invitation already sent + my $me = WebGUI::Friends->new($session,$self); + my $friend = WebGUI::Friends->new($session,$user); + + return 0 if ($me->isFriend($user->userId)); #Already a friend + return 0 if ($me->isInvited($user->userId) || $friend->isInvited($self->userId)); #Invitation sent by one or the other return $self->profileField('ableToBeFriend'); #Return profile setting } @@ -802,6 +805,37 @@ sub profileField { return $self->{_profile}{$fieldName}; } +#------------------------------------------------------------------- + +=head2 profileIsViewable ( user ) + +Returns whether or not the user's profile is viewable by the user passed in + +=head3 user + +The user to test to see if the profile is viewable for. If no user is passed in, +the current user in session will be tested + +=cut + +sub profileIsViewable { + my $self = shift; + my $user = shift || $self->session->user; + my $userId = $user->userId; + + return 0 if ($self->isVisitor); #Can't view visitor's profile + return 1 if ($self->userId eq $userId); #Users can always view their own profile + + my $profileSetting = $self->profileField('publicProfile'); + + return 0 if ($profileSetting eq "none"); + return 1 if ($profileSetting eq "all"); + + my $friendsGroup = $self->friends; + return $user->isInGroup($friendsGroup->getId); +} + + #------------------------------------------------------------------- =head2 referringAffiliate ( [ value ] ) @@ -890,6 +924,28 @@ sub uncache { $cache->delete; } + +#------------------------------------------------------------------- + +=head2 updateProfileFields ( profile ) + +Saves profile data to a user's profile. Does not validate any of the data. + +=head3 profile + +Hash ref of key/value pairs of data in the users's profile to update. + +=cut + +sub updateProfileFields { + my $self = shift; + my $profile = shift; + + foreach my $fieldName (keys %{$profile}) { + $self->profileField($fieldName,$profile->{$fieldName}); + } +} + #------------------------------------------------------------------- =head2 username ( [ value ] ) @@ -929,6 +985,78 @@ sub userId { #------------------------------------------------------------------- +=head2 validateProfileDataFromForm ( fields ) + +Validates profile data from the session form variables. Returns an data structure which contains the following + +{ + profile => Hash reference containing all of the profile fields and their values + errors => Array reference of error messages to be displayed + errorCategory => Category in which the first error was thrown + warnings => Array reference of warnings to be displayed + errorFields => Array reference of the fieldIds that threw an error + warningFields => Array reference of the fieldIds that threw a warning +} + +=head3 fields + +An array reference of profile field Ids to validate. + +=cut + +sub validateProfileDataFromForm { + my $self = shift; + my $session = $self->session; + my $fields = shift; + + my $i18n = my $i18n = WebGUI::International->new($session); + + my $data = {}; + my $errors = []; + my $warnings = []; + my $errorCat = undef; + my $errorFields = []; + my $warnFields = []; + + foreach my $field (@{$fields}) { + my $fieldId = $field->getId; + my $fieldLabel = $field->getLabel; + my $fieldValue = $field->formProcess; + my $isValid = $field->isValid($fieldValue); + + $data->{$fieldId} = (ref $fieldValue eq "ARRAY") ? $fieldValue->[0] : $fieldValue; + + if(!$isValid) { + $errorCat = $field->get("profileCategoryId") unless (defined $errorCat); + push (@{$errors}, sprintf($i18n->get("required error"),$fieldLabel)); + push(@{$errorFields},$fieldId); + } + #The language field is special and must be always be valid or WebGUI will croak + elsif($fieldId eq "language" && !(exists $i18n->getLanguages()->{$data->{$fieldId}})) { + $errorCat = $field->get("profileCategoryId") unless (defined $errorCat); + push (@{$errors}, sprintf($i18n->get("language not available error"),$data->{$fieldId})); + push(@{$errorFields},$fieldId); + } + #Duplicate emails throw warnings + elsif($fieldId eq "email" && $field->isDuplicate($fieldValue)) { + $errorCat = $field->get("profileCategoryId") unless (defined $errorCat); + push (@{$warnings},$i18n->get(1072)); + push(@{$warnFields},$fieldId); + } + } + + return { + profile => $data, + errors => $errors, + warnings => $warnings, + errorCategory => $errorCat, + errorFields => $errorFields, + warningFields => $warnFields, + }; +} + +#------------------------------------------------------------------- + =head2 validUserId ( userId ) Returns true if the userId exists in the users table. diff --git a/lib/WebGUI/i18n/English/Account_Friends.pm b/lib/WebGUI/i18n/English/Account_Friends.pm index 83a41ffba..3e757b109 100644 --- a/lib/WebGUI/i18n/English/Account_Friends.pm +++ b/lib/WebGUI/i18n/English/Account_Friends.pm @@ -9,6 +9,244 @@ our $I18N = { context => q{Tab label for Friends Account pluggin}, }, + 'friends style template label' => { + message => q|Style Template|, + lastUpdated => 1119068809 + }, + + 'friends style template hoverHelp' => { + message => q|Select a style template from the list to enclose friends in.|, + lastUpdated => 1119068809 + }, + + 'friends layout template label' => { + message => q|Edit Layout Template|, + lastUpdated => 1119068809 + }, + + 'friends layout template hoverHelp' => { + message => q{Choose a layout from the list to display the various account pluggins that are editable by the current user as well as the contents of the one currently chosen}, + lastUpdated => 1119068809 + }, + + 'friends view template label' => { + message => q|View Template|, + lastUpdated => 1119068809 + }, + + 'friends view template hoverHelp' => { + message => q|Choose the main template for viewing friends|, + lastUpdated => 1119068809 + }, + + 'friends edit template label' => { + message => q|Edit Template|, + lastUpdated => 1119068809 + }, + + 'friends edit template hoverHelp' => { + message => q|Choose the template for editing friends|, + lastUpdated => 1119068809 + }, + + 'friends send request template label' => { + message => q|Send Friends Request Template|, + lastUpdated => 1119068809 + }, + + 'friends send request template hoverHelp' => { + message => q|Choose the template for sending friends requests|, + lastUpdated => 1119068809 + }, + + 'friends confirm template label' => { + message => q|Friends Request Confirm Template|, + lastUpdated => 1119068809 + }, + + 'friends confirm template hoverHelp' => { + message => q|Choose the template for displaying confirmation that a friends request has been sent|, + lastUpdated => 1119068809 + }, + + 'friends remove confirm template label' => { + message => q|Friends Removal Confirm Template|, + lastUpdated => 1119068809 + }, + + 'friends remove confirm template hoverHelp' => { + message => q|Choose the template for displaying confirmation that you wish to remove a friend|, + lastUpdated => 1119068809 + }, + + 'friends error template label' => { + message => q|Error Template|, + lastUpdated => 1119068809 + }, + + 'friends error template hoverHelp' => { + message => q|Choose the template for displaying friends errors|, + lastUpdated => 1119068809 + }, + + 'back label' => { + message => q{back to site}, + lastUpdated => 1119068809 + }, + + 'edit my profile' => { + message => q|edit my profile|, + lastUpdated => 1068703399 + }, + + 'profile as others label' => { + message => q{view my profile as others see it}, + lastUpdated => 1119068809 + }, + + 'error label' => { + message => q{Error}, + lastUpdated => 1225724810, + }, + + 'member since' => { + message => q{Member Since }, + lastUpdated => 1119068809 + }, + + 'add to network label' => { + message => q{Add to Network}, + lastUpdated => 1119068809 + }, + + 'back to profile label' => { + message => q{back to profile}, + lastUpdated => 1225724810, + }, + + 'adding user message' => { + message => q{You are adding %s to your network.}, + lastUpdated => 1225724810, + }, + + 'sending to message' => { + message => q{The following message will be sent along with your invitation:}, + lastUpdated => 1225724810, + }, + + 'default friend comments' => { + message => q{%s, +I'd like you to be a part of my friends network. + +Thanks, +%s}, + lastUpdated => 1225724810, + }, + + 'send invite button label' => { + message => q{Send Invitation}, + lastUpdated => 1225724810, + }, + + 'cancel button label' => { + message => q{Cancel}, + lastUpdated => 1225724810, + }, + + 'error user is already friend' => { + message => q{This user is already a member of your friends network}, + lastUpdated => 1181493546, + }, + + 'error user is already invited' => { + message => q{You have already sent an invitation for this user to join your friends network}, + lastUpdated => 1181493546, + }, + + 'does not want to be a friend' => { + message => q{This user prefers not to be added as a friend.}, + lastUpdated => 1186264488, + }, + + '' => { + message => q{}, + lastUpdated => 1225724810, + }, + + 'back to user profile' => { + message => q{back to users profile}, + lastUpdated => 1225724810, + }, + + 'message sent label' => { + message => q{Friends Request Sent}, + lastUpdated => 1181019679, + }, + + 'add to friends confirmation' => { + message => q{An email has been sent to %s for your request to be added to your friends network.}, + lastUpdated => 1186030776, + }, + + 'send private message label' => { + message => q{Send Private Message}, + lastUpdated => 1186030776, + }, + + 'send private message label' => { + message => q{Send Private Message}, + lastUpdated => 1186030776, + }, + + 'remove from friends label' => { + message => q{Remove From Friends}, + lastUpdated => 1186030776, + }, + + 'no friend selected' =>{ + message => q{You have not selected friend to be removed from your friends list}, + lastUpdated => 1186030776, + }, + + 'not a friend error' =>{ + message => q{The user you have selected to remove is not in your friends list.}, + lastUpdated => 1186030776, + }, + + 'remove confirm label' =>{ + message => q{Remove Friend Confirmation}, + lastUpdated => 1186030776, + }, + + 'remove confirm message' =>{ + message => q{Are you sure you want remove %s from your friends list?}, + lastUpdated => 1186030776, + }, + + 'remove confirm yes' =>{ + message => q{yes, remove this user}, + lastUpdated => 1186030776, + }, + + 'remove confirm no' =>{ + message => q{no, I made a mistake}, + lastUpdated => 1186030776, + }, + + 'friend removed' =>{ + message => q{%s was removed from your friends list}, + lastUpdated => 1186030776, + }, + + 'no access' =>{ + message => q{You do not have permission to view this user's friends list}, + lastUpdated => 1186030776, + }, + + 'friends is off' =>{ + message => q{You do not have friends enabled. In order to see this page you must edit your profile and enable the friends setting.}, + lastUpdated => 1186030776, + }, }; diff --git a/lib/WebGUI/i18n/English/Account_Inbox.pm b/lib/WebGUI/i18n/English/Account_Inbox.pm index 39d2732c4..5de408122 100644 --- a/lib/WebGUI/i18n/English/Account_Inbox.pm +++ b/lib/WebGUI/i18n/English/Account_Inbox.pm @@ -79,13 +79,23 @@ our $I18N = { lastUpdated => 1119068809 }, - 'invitation error message template label' => { - message => q|Inbox Error Message Template|, + 'invitation confirm message template label' => { + message => q|Invitation Confirmation Message Template|, lastUpdated => 1119068809 }, - 'invitation error message template hoverHelp' => { - message => q|Choose the template for viewing inbox errors|, + 'invitation confirm message template hoverHelp' => { + message => q|Choose the template for viewing invitation confirmations|, + lastUpdated => 1119068809 + }, + + 'inbox view invitation template label' => { + message => q|View Invitation Template|, + lastUpdated => 1119068809 + }, + + 'inbox view invitation template hoverHelp' => { + message => q|Choose the template for viewing an invitation|, lastUpdated => 1119068809 }, @@ -279,6 +289,72 @@ our $I18N = { lastUpdated => 1181019679, }, + 'error label' => { + message => q{Error}, + lastUpdated => 1225724810, + }, + + 'invitation label' => { + message => q{Invitation}, + lastUpdated => 1225724810, + }, + + 'invitation count' => { + message => q{invitations}, + lastUpdated => 1225724810, + }, + + 'invitation message' => { + message => q{%s has invited you to join their friends newtork}, + lastUpdated => 1225724810, + }, + + 'no invitations' => { + message => q{You have no outstanding friends invitations}, + lastUpdated => 1225724810, + }, + + 'accept button label' => { + message => q{Accept}, + lastUpdated => 1225724810, + }, + + 'deny button label' => { + message => q{Deny}, + lastUpdated => 1225724810, + }, + + 'invitation confirm label' => { + message => q{Invitation Notices Sent}, + lastUpdated => 1225724810, + }, + + 'invitation confirm message' => { + message => q{The following users were notified:}, + lastUpdated => 1225724810, + }, + + 'invitations back label' => { + message => q{back to invitations}, + lastUpdated => 1225724810, + }, + + 'invitation does not exist' => { + message => q{The invitation you are trying to view has already been approved or denied.}, + lastUpdated => 1119068809 + }, + + 'no access to invitation' => { + message => q{You do not have permission to view this invitation.}, + lastUpdated => 1119068809 + }, + + 'inviter no longer exists' => { + message => q{The user who sent this invitation is no longer a member of the site.}, + lastUpdated => 1119068809 + }, + + }; 1; diff --git a/lib/WebGUI/i18n/English/Account_Profile.pm b/lib/WebGUI/i18n/English/Account_Profile.pm index 27153da32..22f952d89 100644 --- a/lib/WebGUI/i18n/English/Account_Profile.pm +++ b/lib/WebGUI/i18n/English/Account_Profile.pm @@ -59,20 +59,16 @@ our $I18N = { lastUpdated => 1119068809 }, - 'required error' => { - message => q|%s is required.|, - lastUpdated => 1031514049 - }, + 'profile error template label' => { + message => q|Error Template|, + lastUpdated => 1119068809 + }, - 'language not installed error' => { - message => q|%s is not installed. Please select another language|, - lastUpdated => 1031514049 - }, + 'profile error template hoverHelp' => { + message => q|Choose the template to use for displaying profile errors to the user|, + lastUpdated => 1119068809 + }, - 'email already in use error' => { - message => q|The email address is already in use. Please use a different email address.|, - lastUpdated => 1068703399 - }, 'visitor profile restricted' => { message => q|The visitor profile is restricted|, @@ -110,9 +106,56 @@ our $I18N = { }, 'back label' => { - message => q{go back}, + message => q{back to site}, lastUpdated => 1119068809 - } + }, + + 'profile not public error' => { + message => q|This user's profile is not public.|, + lastUpdated => 1043881275 + }, + + 'friends only' => { + message => q|Your profile is viewable to Friends|, + lastUpdated => 1043881275 + }, + + 'private profile' => { + message => q|Your profile is Private|, + lastUpdated => 1043881275 + }, + + 'public profile' => { + message => q|Your profile is Public|, + lastUpdated => 1043881275 + }, + + 'private label' => { + message => q|Private|, + lastUpdated => 1043881275 + }, + + 'public label' => { + message => q|Public|, + lastUpdated => 1043881275 + }, + + 'friends only label' => { + message => q|Friends Only|, + lastUpdated => 1043881275 + }, + + 'error label' => { + message => q{Error}, + lastUpdated => 1225724810, + }, + + 'back to profile label' => { + message => q{back to profile}, + lastUpdated => 1225724810, + }, + + }; 1; diff --git a/lib/WebGUI/i18n/English/Account_Shop.pm b/lib/WebGUI/i18n/English/Account_Shop.pm new file mode 100644 index 000000000..d1671d31b --- /dev/null +++ b/lib/WebGUI/i18n/English/Account_Shop.pm @@ -0,0 +1,40 @@ +package WebGUI::i18n::English::Account_Shop; +use strict; + +our $I18N = { + + 'title' => { + message => q{Shop}, + lastUpdated => 1225724810, + context => q{Tab label for User Account pluggin}, + }, + + 'shop style template label' => { + message => q|Style Template|, + lastUpdated => 1119068809 + }, + + 'shop style template hoverHelp' => { + message => q|Select a style template from the list to enclose the shop tab in.|, + lastUpdated => 1119068809 + }, + + 'shop layout template label' => { + message => q|Layout Template|, + lastUpdated => 1119068809 + }, + + 'shop layout template hoverHelp' => { + message => q{Choose a layout template in which to enclose the content from the various methods within the shop tab}, + lastUpdated => 1119068809 + }, + + 'manage purchases label' => { + message => q{Manage Purchases}, + lastUpdated => 1119068809 + }, + + +}; + +1; diff --git a/lib/WebGUI/i18n/English/Account_User.pm b/lib/WebGUI/i18n/English/Account_User.pm index c18edc6ea..b3163d192 100644 --- a/lib/WebGUI/i18n/English/Account_User.pm +++ b/lib/WebGUI/i18n/English/Account_User.pm @@ -4,11 +4,36 @@ use strict; our $I18N = { 'title' => { - message => q{User}, + message => q{Account}, lastUpdated => 1225724810, context => q{Tab label for User Account pluggin}, }, + 'user style template label' => { + message => q|Style Template|, + lastUpdated => 1119068809 + }, + + 'user style template hoverHelp' => { + message => q|Select a style template from the list to enclose the account tab in.|, + lastUpdated => 1119068809 + }, + + 'user layout template label' => { + message => q|Layout Template|, + lastUpdated => 1119068809 + }, + + 'user layout template hoverHelp' => { + message => q{Choose a layout template in which to enclose the content from the various methods within the account tab}, + lastUpdated => 1119068809 + }, + + 'templates in auth method message' => { + message => q{The display templates for this module can be found in the settings
    for the authentications modules you have installed on your site.
    }, + lastUpdated => 1119068809 + }, + }; diff --git a/lib/WebGUI/i18n/English/WebGUI.pm b/lib/WebGUI/i18n/English/WebGUI.pm index 68abf64aa..c934cffe3 100644 --- a/lib/WebGUI/i18n/English/WebGUI.pm +++ b/lib/WebGUI/i18n/English/WebGUI.pm @@ -254,6 +254,16 @@ our $I18N = { lastUpdated => 1031514049 }, + 'required error' => { + message => q{%s is required.}, + lastUpdated => 1031514049 + }, + + 'language not available error' => { + message => q|%s is not available. Please select another language|, + lastUpdated => 1031514049 + }, + '454' => { message => q|Last Updated|, lastUpdated => 1031514049 @@ -330,7 +340,7 @@ our $I18N = { }, '861' => { - message => q|Make profile public?|, + message => q|Profile Privacy Setting|, lastUpdated => 1043879954 }, diff --git a/www/extras/account/account.css b/www/extras/account/account.css new file mode 100644 index 000000000..d75c73806 --- /dev/null +++ b/www/extras/account/account.css @@ -0,0 +1,724 @@ + +/* general */ + + body { + margin:0; + padding:0; + font: 11px Verdana; + } + a { + cursor: pointer; + } + button { + cursor: pointer; + } + img { + border: none; + } + .button { + float:right; + padding-right:10px; + } + .centered { + text-align: center; + } + .account_message { + width: 600px; + height: 300px; + border: solid #BECEF8 1px; + margin-left: 50px; + margin-bottom: 20px; + overflow:-moz-scrollbars-vertical; + overflow-x:hidden; + overflow-y:scroll; + background-color: white; + text-align: left; + } + .profileMember { + text-align:right; + margin-right:20px; + font-size:9px; + } + .member { + font: 9px Verdana, Arial, Helvetica, sans-serif; + color:#000000; + text-align:center; + } + .photostyle { + border:solid #9BB4F4 2px; + margin-bottom:5px; + margin-top:5px + } + #rightalign { + float: right; + } + /*.send { + padding-right: 75px; + }*/ + + .Profile_registration { + + } + .Profile_registration td { + font-size:9pt; + font-family:arial; + } + .Profile_registration .tabs a { + text-decoration:none; + background-color:#FEEBC7; + margin-right:10px; + padding:0px 10px 1px 10px; + color:#FDC55B; + font-weight:bold; + border:solid #FDBA42 1px; + } + .Profile_registration .tabs a.active { + background:#FDBA42; + color:black; + } + .Profile_registration .header { + font-size:10px; + font-weight:bold; + text-align:left; + color:#fff; + background-color:#818997; + border-top:solid #FE9515 3px; + text-align:right; + } + .Profile_registration .header a { + color:white; + text-decoration:none; + } + .Profile_registration .help a { + font-weight:bold; + text-decoration:none; + } + + .Profile_registration .inputText { + font-size:10px; + margin-right:1px; + } + .Profile_registration .label { + font-weight:bold; + font-size:9pt; + text-align:right; + white-space:nowrap; + width:1%; + } + .Profile_registration .labelLeft { + font-weight:bold; + font-size:9pt; + text-align:right; + white-space:nowrap; + width:1%; + text-align: left; + vertical-align: top; + } + .Profile_registration .smallLabel { + font-size:8px; + text-align:center; + } + .Profile_registration .smallText { + font-size:9px; + } + .Profile_registration .yourselfBG { + border:solid #CEDBF8 1px; + background-color:#EEF2FD; + color:black; + padding: 2px; + } + /*.Profile_registration .yourselfBG a { + font-weight:bold; + color:#0054ff; + text-decoration:none; + }*/ + .Profile_registration .bar { + background-color:#DDE6FB; + border:solid #BECEF8 1px; + text-align:center; + color:#0B2259; + font-size:14px; + font-weight:bold; + } + + .Profile_registration .bar a { + color:#0B2259; + font-size:10px; + font-weight:bold; + } + +/* profile errors */ + +#profileErrors { + background-color: #ff0000; + font-weight: bold; + color: #ffffff; + text-align: center; +} + +.profilefield_required_off { +} +.profilefield_required { + background-color: #ffffbb; +} +.profilefield_error { + background-color: #FF9494; +} + +/* bio, addtonetwork, network */ + + .bordered { + border-bottom: dashed #BECEF8 2px; + padding-bottom: 10px; + } + .friendpic { + border: solid #BECEF8 1px; + } + .invitemsg { + width: 600px; + height: 150px; + } + ol.Profile_interests { + font-size:15px; + font-weight:bold; + color:#0B2259; + list-style-type:none; + margin:0px; + padding:0px; + padding:5px 5px; + } + ol.Profile_interests li { + margin-bottom:15px; + } + ol.Profile_interests span { + font-weight:normal; + font-size:12px; + color:black; + } + .pBio { + border-bottom:solid #DDE6FB 1px; + margin:0px; + margin-bottom:5px; + padding-bottom:5px; + } + .pBio div { + background-color:#DDE6FB; + padding:2px 5px; + margin-bottom:2px; + } + .program { + font-size: 9px; + } + +/* edit box */ + + .editBox { + font-size:9px; + font-weight:bold; + background:white url(images/edit_box_bg.jpg) no-repeat bottom left; + border:solid #8DABF1 2px; + padding:5px; + width:590px; + -moz-box-sizing:border-box; + font-family:verdana; + z-index:100; + position:absolute; + top:100px; + left:100px; + display:block; + } + .editBox input, .editBox select { + font-size:9px; + } + +/* inbox */ + +.Profile_registration .inboxTitle { + background-color:#DDE6FB; + border:solid #BECEF8 1px; + text-align:center; + font-size:10px; + font-weight:bold; + color:#0B2259; + text-decoration: underline; +} + +/* inbox threads */ + + .evenThread { + background-color: #e1e8fb; + border-bottom: 1px solid #bfcef9; + padding: 4px; + text-align:center; + } + .oddThread { + background-color: #eef2fd; + border-bottom: 1px solid #bfcef9; + padding: 4px; + text-align: center; + } +/* inbox forms */ + +.inbox_from { + color: black; + text-decoration: none; + font-weight: normal; +} + +.inbox_subject { + width: 530px; +} + +.inbox_messageTo { + width: 530px; + height: 50px; + border: solid #BECEF8 1px; + overflow:-moz-scrollbars-vertical; + overflow-x:hidden; + overflow-y:scroll; + background-color: white; +} + +/* inbox contacts */ + .datacells { + border-bottom: dashed #BECEF8 1px; + } + .inbox_contactsTbl { + font-size:9pt; + font-family:arial; + background-color:#EEF2FD; + } + #contacts { + height: 275px; + overflow: auto; + } + +/* pagination */ +.Profile_pagination { + text-align:right; + font-size:10px; +} +.Profile_pagination a { + font-weight:bold; + font-size:10px; + border:solid #BECEF8 1px; + padding:1px 5px; + text-decoration:none; + background-color:#EEF2FD; +} + +.Profile_pagination a:hover { + background-color:#FE9515; + color:white; +} + +.Profile_pagination .prevNext { + border: none; + background-color: transparent; + color: black; +} + +.Profile_pagination .prevNext:hover { + border: none; + background-color: transparent; + color: black; +} + +.Profile_pagination .active { + font-weight:bold; + font-size:10px; + border:solid #BECEF8 1px; + padding:1px 5px; + text-decoration:none; + background-color:#FE9515; + color:white; +} + +/* TABS - outer */ + +.bottombutton { + border: none; + float:right; + padding-right:2px; + padding-top: 2px; + position: relative; +} +.content { + padding:10px; + +} +.subContent { + border: solid #ffa700 6px; +} +.topbutton { + border: none; + float:right; + clear:both; + padding-right:2px; + padding-top: 2px; + position: relative; +} + +ul.topTabs, +ul.topTabs li { + margin:0px; + padding:0px; + list-style-type:none; + position:relative;zoom:1; + width:auto; + + Xposition:relative; +} +ul.topTabs li { + display:block; + float:left; + margin-right: 5px; +} +ul.topTabs li b { + display:block; + position:relative; + top:-1px; + border-top:solid #ffa700 1px; + background-color: #faee9a; + padding:4px 8px; +} +ul.topTabs a { + display:block; + color:#ffa700; + font-size:12px; + font-family: Arial, Helvetica, sans-serif; + text-decoration:none; + background-color:#faee9a; + border-left: solid #ffa700 1px; + border-right: solid #ffa700 1px; +} +ul.topTabs a:hover, +ul.topTabs a:hover b, +ul.topTabs a.selected, +ul.topTabs a.selected b { + background-color:#ffa700; + color:#fff; +} + +/* TABS - YUI */ + +.cleardiv { + clear: both; + margin: 0px 0px 0px 0px; + padding: 0px; +} + +.view { + border: none; + font: bold 10px Verdana; + color: #0b2258; + text-decoration:none; + position: absolute; + right: 4px; + top:4px; +} + +.profile_displayView { + -x-system-font:none; + border:medium none; + color:#0B2258; + display:inline; + float:right; + font-family:Verdana; + font-size:10px; + font-size-adjust:none; + font-stretch:normal; + font-style:normal; + font-variant:normal; + font-weight:bold; + line-height:normal; + padding-right:8px; + padding-top:3px; +} + +.profile_displaySubContent { + border: solid #ffa700 6px; + border-top: solid #ffa700 18px; +} + +/* view profile */ + +.profile_fieldLabel { +background: #DDE6FB; +border: 1px solid white; +} +.profile_fieldData { +margin-left: 5px; +} + + /* +Copyright (c) 2008, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 2.6.0 +*/ +/* .yui-navset defaults to .yui-navset-top */ +.yui-skin-sam .yui-navset .yui-nav, +.yui-skin-sam .yui-navset .yui-navset-top .yui-nav { /* protect nested tabviews from other orientations */ + border:solid #eef2fd; /* color between tab list and content */ + border-width:0 0 5px; + Xposition:relative; + zoom:1; +} + +.yui-skin-sam .yui-navset .yui-nav li, +.yui-skin-sam .yui-navset .yui-navset-top .yui-nav li { + margin:0 0.3em 0 0; /* space between tabs */ + padding:5px 0 0; /* gecko: make room for overflow */ + zoom:1; +} + +.yui-skin-sam .yui-navset .yui-nav .selected, +.yui-skin-sam .yui-navset .yui-navset-top .yui-nav .selected { + margin:0 0.3em -1px 0; /* for overlap */ +} + +.yui-skin-sam .yui-navset .yui-nav a, +.yui-skin-sam .yui-navset .yui-navset-top .yui-nav a { + background:#9bb4f4; /* tab background */ + border:solid #eef2fd; + border-width:0 1px; + color:#eef2fd; + position:relative; + text-decoration:none; + font-size:12px; + font-family: Arial, Helvetica, sans-serif; + font-weight: bold; +} + +.yui-skin-sam .yui-navset .yui-nav a em, +.yui-skin-sam .yui-navset .yui-navset-top .yui-nav a em { + border:solid #eef2fd; + border-width:1px 0 0; + cursor:hand; + padding:0.25em .75em; + left:0; right: 0; bottom: 0; /* protect from other orientations */ + top:-1px; /* for 1px rounded corners */ + position:relative; +} + +.yui-skin-sam .yui-navset .yui-nav .selected a, +.yui-skin-sam .yui-navset .yui-nav .selected a:focus, /* no focus effect for selected */ +.yui-skin-sam .yui-navset .yui-nav .selected a:hover { /* no hover effect for selected */ + background:#eef2fd; /* selected tab background */ + color:#0a2359; + font-size:12px; + font-family: Arial, Helvetica, sans-serif; + text-decoration:none; + font-weight: bold; +} + +.yui-skin-sam .yui-navset .yui-nav a:hover, +.yui-skin-sam .yui-navset .yui-nav a:focus { + background:#eef2fd; /* selected tab background */ + color:#0a2359; + outline:0; + font-size:12px; + font-family: Arial, Helvetica, sans-serif; + text-decoration:none; + font-weight: bold; + +} + +.yui-skin-sam .yui-navset .yui-nav .selected a, +.yui-skin-sam .yui-navset .yui-nav .selected a em { + border-color:#eef2fd; /* selected tab border color */ +} + +.yui-skin-sam .yui-navset .yui-content { + background:#edf5ff; /* content background color */ +} + +.yui-skin-sam .yui-navset .yui-content, +.yui-skin-sam .yui-navset .yui-navset-top .yui-content { + border:5px solid #eef2fd; /* content border */ + padding:0.75em 1em; /* content padding */ +} + +/* left and right orientations */ +.yui-skin-sam .yui-navset-left .yui-nav, +.yui-skin-sam .yui-navset .yui-navset-left .yui-nav, +.yui-skin-sam .yui-navset .yui-navset-right .yui-nav, +.yui-skin-sam .yui-navset-right .yui-nav { + border-width:0 5px 0 0; + Xposition:absolute; /* from tabview-core; have to reiterate for skin-sam due to pos:rel on skin-sam yui-nav */ + top:0; bottom:0; /* stretch to fill content height */ +} + +.yui-skin-sam .yui-navset .yui-navset-right .yui-nav, +.yui-skin-sam .yui-navset-right .yui-nav { + border-width:0 0 0 5px; +} + +.yui-skin-sam .yui-navset-left .yui-nav li, +.yui-skin-sam .yui-navset .yui-navset-left .yui-nav li, +.yui-skin-sam .yui-navset-right .yui-nav li { + margin:0 0 0.3em; /* space between tabs */ + padding:0 0 0 1px; /* gecko: make room for overflow */ +} + +.yui-skin-sam .yui-navset-right .yui-nav li { + padding:0 1px 0 0; /* gecko: make room for overflow */ +} + +.yui-skin-sam .yui-navset-left .yui-nav .selected, +.yui-skin-sam .yui-navset .yui-navset-left .yui-nav .selected { + margin:0 -1px 0.16em 0; +} + +.yui-skin-sam .yui-navset-right .yui-nav .selected { + margin:0 0 0.16em -1px; +} + +.yui-skin-sam .yui-navset-left .yui-nav a, +.yui-skin-sam .yui-navset-right .yui-nav a { + border-width:1px 0; +} + +.yui-skin-sam .yui-navset-left .yui-nav a em, +.yui-skin-sam .yui-navset .yui-navset-left .yui-nav a em, +.yui-skin-sam .yui-navset-right .yui-nav a em { + border-width:0 0 0 1px; + padding:0.2em .75em; + top:auto; + left:-1px; /* for 1px rounded corners */ +} + +.yui-skin-sam .yui-navset-right .yui-nav a em { + border-width:0 1px 0 0; + left:auto; + right:-1px; /* for 1px rounded corners */ +} + +.yui-skin-sam .yui-navset-left .yui-nav a, +.yui-skin-sam .yui-navset-left .yui-nav .selected a, +.yui-skin-sam .yui-navset-left .yui-nav a:hover, +.yui-skin-sam .yui-navset-right .yui-nav a, +.yui-skin-sam .yui-navset-right .yui-nav .selected a, +.yui-skin-sam .yui-navset-right .yui-nav a:hover, +.yui-skin-sam .yui-navset-bottom .yui-nav a, +.yui-skin-sam .yui-navset-bottom .yui-nav .selected a, +.yui-skin-sam .yui-navset-bottom .yui-nav a:hover { + background-image:none; /* no left-right or bottom-top gradient */ +} + +.yui-skin-sam .yui-navset-left .yui-content { + border:1px solid #eef2fd; /* content border */ +} + +/* bottom orientation */ +.yui-skin-sam .yui-navset-bottom .yui-nav, +.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav { + border-width:5px 0 0; /* color between tab list and content */ +} + +.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav .selected, +.yui-skin-sam .yui-navset-bottom .yui-nav .selected { + margin:-1px 0.3em 0 0; /* for overlap */ +} + +.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav li, +.yui-skin-sam .yui-navset-bottom .yui-nav li { + padding:0 0 1px 0; /* gecko: make room for overflow */ + vertical-align:top; +} + +.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav li a, +.yui-skin-sam .yui-navset-bottom .yui-nav li a { +} + +.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav a em, +.yui-skin-sam .yui-navset-bottom .yui-nav a em { + border-width:0 0 1px; + top:auto; + bottom:-1px; /* for 1px rounded corners */ +} + +.yui-skin-sam .yui-navset-bottom .yui-content, +.yui-skin-sam .yui-navset .yui-navset-bottom .yui-content { + border:1px solid #eef2fd; /* content border */ +} + + +.yui-skin-sam { + background-color: #ffa700; + padding: 10px 5 5 5px; + display:block; +} + +/* +Copyright (c) 2008, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 2.6.0 +*/ +.yui-navset .yui-nav li,.yui-navset .yui-navset-top .yui-nav li,.yui-navset .yui-navset-bottom .yui-nav li{margin:0 0.5em 0 0;} + +.yui-navset-left .yui-nav li,.yui-navset-right .yui-nav li{margin:0 0 0.5em;} + +.yui-navset .yui-content .yui-hidden{display:none;} + +.yui-navset .yui-navset-left .yui-nav,.yui-navset .yui-navset-right .yui-nav,.yui-navset-left .yui-nav,.yui-navset-right .yui-nav{width:6em;} + +.yui-navset-top .yui-nav,.yui-navset-bottom .yui-nav{width:auto;}.yui-navset .yui-navset-left,.yui-navset-left{padding:0 0 0 6em;} + +.yui-navset-right {padding:0 6em 0 0;} + +.yui-navset-top,.yui-navset-bottom{padding:auto;} + +.yui-nav,.yui-nav li{margin:0;padding:0;list-style:none;} + +.yui-navset li em{font-style:normal;}.yui-navset{position:relative;zoom:1;} + +.yui-navset .yui-content{zoom:1;} + +.yui-navset .yui-nav li,.yui-navset .yui-navset-top .yui-nav li,.yui-navset .yui-navset-bottom .yui-nav li{display:inline-block;display:-moz-inline-stack;*display:inline;vertical-align:bottom;cursor:pointer;zoom:1;} + +.yui-navset-left .yui-nav li,.yui-navset-right .yui-nav li{display:block;} + +.yui-navset .yui-nav a{position:relative;} + +.yui-navset .yui-nav li a,.yui-navset-top .yui-nav li a,.yui-navset-bottom .yui-nav li a{display:block;display:inline-block;vertical-align:bottom;zoom:1;} + +.yui-navset-left .yui-nav li a,.yui-navset-right .yui-nav li a{display:block;} + +.yui-navset-bottom .yui-nav li a{vertical-align:text-top;} + +.yui-navset .yui-nav li a em,.yui-navset-top .yui-nav li a em,.yui-navset-bottom .yui-nav li a em{display:block;} + +.yui-navset .yui-navset-left .yui-nav,.yui-navset .yui-navset-right .yui-nav,.yui-navset-left .yui-nav,.yui-navset-right .yui-nav{position:absolute;z-index:1;} + +.yui-navset-top .yui-nav,.yui-navset-bottom .yui-nav{position:static;} + +.yui-navset .yui-navset-left .yui-nav,.yui-navset-left .yui-nav{left:0;right:auto;} + +.yui-navset .yui-navset-right .yui-nav,.yui-navset-right .yui-nav{right:0;left:auto;} + +.yui-skin-sam .yui-navset .yui-nav .selected a em{padding:0.35em 0.75em;} + +.yui-skin-sam .yui-navset-left .yui-nav,.yui-skin-sam .yui-navset .yui-navset-left .yui-nav,.yui-skin-sam .yui-navset .yui-navset-right .yui-nav,.yui-skin-sam .yui-navset-right .yui-nav{border-width:0 5px 0 0;Xposition:absolute;top:0;bottom:0;} + +.yui-skin-sam .yui-navset .yui-navset-right .yui-nav,.yui-skin-sam .yui-navset-right .yui-nav{border-width:0 0 0 5px;} + +.yui-skin-sam .yui-navset-left .yui-nav li,.yui-skin-sam .yui-navset .yui-navset-left .yui-nav li,.yui-skin-sam .yui-navset-right .yui-nav li{margin:0 0 0.16em;padding:0 0 0 1px;} + +.yui-skin-sam .yui-navset-right .yui-nav li{padding:0 1px 0 0;} + +.yui-skin-sam .yui-navset-left .yui-nav a,.yui-skin-sam .yui-navset-right .yui-nav a{border-width:1px 0;} + +.yui-skin-sam .yui-navset-left .yui-nav a em,.yui-skin-sam .yui-navset .yui-navset-left .yui-nav a em,.yui-skin-sam .yui-navset-right .yui-nav a em{border-width:0 0 0 1px;padding:0.2em .75em;top:auto;left:-1px;} + +.yui-skin-sam .yui-navset-right .yui-nav a em{border-width:0 1px 0 0;left:auto;right:-1px;} + +.yui-skin-sam .yui-navset-left .yui-nav a,.yui-skin-sam .yui-navset-left .yui-nav .selected a,.yui-skin-sam .yui-navset-left .yui-nav a:hover,.yui-skin-sam .yui-navset-right .yui-nav a,.yui-skin-sam .yui-navset-right .yui-nav .selected a,.yui-skin-sam .yui-navset-right .yui-nav a:hover,.yui-skin-sam .yui-navset-bottom .yui-nav a,.yui-skin-sam .yui-navset-bottom .yui-nav .selected a,.yui-skin-sam .yui-navset-bottom .yui-nav a:hover{background-image:none;} + +.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav .selected,.yui-skin-sam .yui-navset-bottom .yui-nav .selected{margin:-1px 0.16em 0 0;} + +.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav li,.yui-skin-sam .yui-navset-bottom .yui-nav li{padding:0 0 1px 0;vertical-align:top;} + + diff --git a/www/extras/account/images/new.png b/www/extras/account/images/new.png new file mode 100644 index 0000000000000000000000000000000000000000..45d7f067655e815caedbff0accf14d685c0ff16c GIT binary patch literal 452 zcmV;#0XzPQP)@qr@y7eVu5YK!j_>Bbly>^dZ_LIb(`R%sMbMzs)}d8YywQe z3}ec_nD473NxU*haQ^VO*1;XvYZ+qzeIx`h-wdoJ4|}aRjwv}H98%$)1ZF*0!&>sN zH$8w0x-I0Ock!!PYSOGNxf~Eh5pOAl-iLd9hL6rk&ShYZYphvv>{Y7?vKYL*Li;yl zI4$gqIj*^SZ^f}!$*ke7HOUU|5m8t1i=dxuJdX1?vL-5@vNan z{FDjg05M+{US(~tmOQdVxd*<#`5jn-JnZG0*#GQyy|QgXISwk#CRC#VMR~balZMH3 u3Ns$Vj7EruLzpl`LOFX&|Nb|A3ormeM$bB?>xCl#0000;<*x*Red8x|aF=Frvfh!AjOXk(U@kYKpz#KI*Y=itMTaEP&kiA!gNhl7(V RH;><{n3J2H9&BK+1^_N`K7jxL literal 0 HcmV?d00001 diff --git a/www/extras/account/images/no_photo.gif b/www/extras/account/images/no_photo.gif new file mode 100644 index 0000000000000000000000000000000000000000..cd34a822f2fccfc638a9edbd7540ede72e5b699c GIT binary patch literal 390 zcmV;10eSvMNk%w1VKM+R0K@)#UE+_WAn!>hAQ^+UWfK z{^{)V_W1hs_WJ(*|MvI#+TiTV)8xm{;`sUd*WK#gDJuo z(%I<7&*A_7|HRGUA^8LV00000EC2ui05SkF000I5U?+}bX`X1Ru56ora4gSsZQppV z?|fem6~iRrE7}NwjA!Wy7@si>fJq%djhF{@>w#Q*6|NZZ)h)#6NBJf|yVdJi#7+0c zV{JORagQnWVh(*U41j2Z9|wkF9fOLCTNi^9kXwy?T9r(QQ<_VNf0_!2XPy&-1&^K^ zeWjiraB&c?OACDiv`u{yxg3MJM18ZKwur9;h##Sgg2@4z2FV{6nhDY$29TrIACOku z%XHi@oq*$siRjrqLRUvkqzY* kQaRvchXf1%B+^;X&c=Xj8W%O7FoOc6kfJIBdfSn;10^3#$Yh6@MUDDD0~B3Gh2@r>hsT7J(f^PHK^ydrYhWc zDga~VSo@#_Rt_CVPjR$0)zP(7dj2I@qlVhL2chMB#k4xqYvG|{p;QC9V?d%E=#2VZ zzB(}Zr>dXt=@2Mf3$ry#2$7A)<47ie{ACGqqY1Ra;z0@1=>%f;7Ru#vHtf1CGHGD{ z5=`JHP(v*}^oDf@c&_=0R4Rqy^Y>=fsG*h~dM%+>5gzbZ@fWeTi^z;5v2*_3JUIxg z=ZdhWl159=i}{T!b@!qgBr^JPd_<6I*3xUXAaw@;*}=k08n^m5n#mk%&02cRAqI)9 zGhlW&`A*bK)~E^QjYE|BHt${l69X`DD^f!(V{?d7O6=*+GTsk(3cmui^w1mTW310N z|Aq9>Yk8iRTiQGwiACGc*>0gL7BOQ-)Iv1UX5Q$y5*0__wI=XVbgwDPUcv-Dl%9D0M6(>s{jB1 literal 0 HcmV?d00001 diff --git a/www/extras/account/images/save_changes.gif b/www/extras/account/images/save_changes.gif new file mode 100644 index 0000000000000000000000000000000000000000..897b100d48de61aa1c07977f5401bce03eea5952 GIT binary patch literal 1589 zcmV-52Fm$INk%w1VO{_g0Oo%HX=!PQh=|qK;pph-)YQ~TS%OnyiQ(blnxeORhNGIA znv#-|^6~Y;$JMm7w8zKC_V)I{#m_=hesy(q;^gZ1`1tbj^J;gO($(DB+S=UR-iMN` zpr*Rc&dz>`rt$OegN>;C`S-QE$wo#+{{H--p`psn)ig$Rt+T`A;o;`y=I-w7^7Qes zxW>P~zwq$zd&_eMrZWo2b)Xk52$H{1DXvoRN?CkE}-{IQa*|4_4mY%fc41ejE#u{3jj4|l$Dm3XImp$TYe)~n4zMhmRo0_XCtPc zr&_9&H2@0(iV98(9Tr}@yuH3&U|>~gU}R||zsbtWyGvdqWKz&dOVC_ZTuWd|yH6bp zP6~(t6F@gy=;`X~>0nD-Vqjb(V(j+!_~>BqB-!;`#jc6@hfax-8w3CZFr)wr3Nj1Vo}lL9k|Yf&`?aB#0n7PXY{4ejwQJV~p+Fd@(d>@&n2kzz7nE*o`4c0uRHR zh(I7BfsQg^!u&YB!9(;g4V*&{)7&`>4H*bHn4scM1^^v0Xo%3|0tOiH;p31X0mp>{ zG^W4@fddE{94DO6g$yYaSYQ_*7-*mbUCK(XrM<19ZZnHA03FL!2t(c&_#n&m|(_^K%g)M4Q7DQ1rTPOpdSuA_@ILS z0T-B|!jnUEv4;;-Rw;o2X80h%6j}OU0tz%F$-@b1sBpmvD)7*S8fKu-g$hFI7^MjY zoN$B+CIFGb0U7`iz#V@)5C9N)z@WkaIczWm4mfW-1G+2F zy21q#tgwP-@t$DszAIp`0fP~IF#rtTbnu4;0k|;08X`!5!VChK6)_EcP{3gS9C0v< z0|FR3NPz`1ctF?4(kAi73<%IL17Ih6Ai*0n7%+njGgE3c0xk?JPy!5uXt2QJ5Zs_V7uR1O0viCK^A0-K-_sA0_~Z*8K0rEb zumSAqoWF|_5J;_nSA}R$!UQD{FvC6Wzyn4<V84w*aAi(`fpa(>#zy%7J z001UP!3qK(3lyY-9W2N}3vRH3APiv#KM2AJD8L2fQG}xiP=p7#@P$QSLJ{u3ggV^e n0d;sG40XuE9{TWyKm=k7A5er2Xy6NuNTL##$iyc8ArJsNbY1vd literal 0 HcmV?d00001 diff --git a/www/extras/account/inbox.js b/www/extras/account/inbox.js new file mode 100644 index 000000000..16823857a --- /dev/null +++ b/www/extras/account/inbox.js @@ -0,0 +1,64 @@ +YAHOO.util.Event.onDOMReady(function() { + if(YAHOO.util.Dom.inDocument("friends")) { + + var isUserCheckBox = function ( element ) { + if(element.name == "friend") return true; + return false; + } + + var removeUser = function (evt, obj) { + YAHOO.util.Event.stopEvent(evt); + var userId = obj.userId; + var checkBox = YAHOO.util.Dom.get("friend_"+userId+"_id"); + checkBox.checked = false; + updateUsers(evt,obj.dialog); + } + + var updateUsers = function ( evt , dialog ) { + YAHOO.util.Event.stopEvent(evt); + var toElement = YAHOO.util.Dom.get("messageTo"); + toElement.innerHTML = ""; // Clear the current stuff + YAHOO.util.Dom.removeClass(toElement,"inbox_messageTo"); + + var checkBoxes = YAHOO.util.Dom.getElementsBy(isUserCheckBox,"INPUT","contacts"); + for (var i = 0; i < checkBoxes.length; i++) { + if(checkBoxes[i].checked) { + var friendName = YAHOO.util.Dom.get("friend_"+checkBoxes[i].value+"_name").innerHTML; + var firstPart = document.createTextNode(friendName + " ( "); + var link = document.createElement("A"); + link.setAttribute('href', '#'); + link.innerHTML = removeText; + YAHOO.util.Event.addListener(link,"click",removeUser,{ userId: checkBoxes[i].value, dialog: dialog }); + var lastPart = document.createTextNode(" ); "); + toElement.appendChild(firstPart); + toElement.appendChild(link); + toElement.appendChild(lastPart); + } + } + YAHOO.util.Dom.addClass(toElement,"inbox_messageTo"); + dialog.hide(); + } + + var showUsers = function (evt, dialog) { + YAHOO.util.Event.stopEvent(evt); + dialog.show(); + } + + // Instantiate the Dialog + var dialog1 = new YAHOO.widget.Dialog("friends", { + width : "340px", + fixedcenter : true, + visible : false, + constraintoviewport : false + }); + + // Render the Dialog + dialog1.render(); + + YAHOO.util.Event.addListener("show_friends", "click", showUsers, dialog1); + YAHOO.util.Event.addListener("cancel_top", "click", dialog1.hide, dialog1, true); + YAHOO.util.Event.addListener("cancel_bottom", "click", dialog1.hide, dialog1, true); + YAHOO.util.Event.addListener("update_top", "click", updateUsers, dialog1); + YAHOO.util.Event.addListener("update_bottom", "click", updateUsers, dialog1); + } +}); \ No newline at end of file From 6cd5071f1681ade5b204e45a43c6b7224a6f15f8 Mon Sep 17 00:00:00 2001 From: Frank Dillon Date: Sat, 15 Nov 2008 03:05:50 +0000 Subject: [PATCH 7/8] deleted my version of the upgrade script - need to add to 7.6.4 --- docs/upgrades/upgrade_7.6.1-7.6.2.pl | 447 --------------------------- 1 file changed, 447 deletions(-) delete mode 100644 docs/upgrades/upgrade_7.6.1-7.6.2.pl diff --git a/docs/upgrades/upgrade_7.6.1-7.6.2.pl b/docs/upgrades/upgrade_7.6.1-7.6.2.pl deleted file mode 100644 index 6f564de79..000000000 --- a/docs/upgrades/upgrade_7.6.1-7.6.2.pl +++ /dev/null @@ -1,447 +0,0 @@ -#------------------------------------------------------------------- -# WebGUI is Copyright 2001-2008 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 -#------------------------------------------------------------------- - -our ($webguiRoot); - -BEGIN { - $webguiRoot = "../.."; - unshift (@INC, $webguiRoot."/lib"); -} - -use strict; -use Getopt::Long; -use WebGUI::Session; -use WebGUI::Storage; -use WebGUI::Asset; -use WebGUI::Utility; -use Tie::IxHash; - - -my $toVersion = '7.6.2'; -my $quiet; # this line required - - -my $session = start(); # this line required - -# upgrade functions go here -repairManageWorkflows($session); -addPreTextToThingyFields($session); -updateAddressBook($session); -changeDefaultPaginationInSearch($session); -upgradeToYui26($session); -addUsersOnlineMacro($session); -addProfileExtrasField($session); -addWorkflowToDataform( $session ); -installDataTableAsset( $session ); -installAjaxI18N( $session ); -fixFriendsGroups( $session ); -upgradeAccount( $session ); -finish($session); # this line required - -#---------------------------------------------------------------------------- -sub fixFriendsGroups { - my $session = shift; - my $users = $session->db->buildArrayRef("select userId from users where friendsGroup is not null && friendsGroup != ''"); - foreach my $userId (@{$users}) { - #purge the admin group - WebGUI::User->new($session,$userId)->friends->deleteGroups([3]); - } -} - -#---------------------------------------------------------------------------- -sub upgradeAccount { - my $session = shift; - my $config = $session->config; - my $setting = $session->setting; - - print "\tUpgrading WebGUI Account System... " unless $quiet; - #Add account properties to config file - $session->config->delete("account"); #Delete account if it exists - $session->config->set("account",[ - { - identifier => "profile", - title => "^International(title,Account_Profile);", - className => "WebGUI::Account::Profile" - }, - { - identifier => "inbox", - title => "^International(title,Account_Inbox);", - className => "WebGUI::Account::Inbox" - }, - { - identifier => "friends", - title => "^International(title,Account_Friends);", - className => "WebGUI::Account::Friends" - }, - { - identifier => "shop", - title => "^International(title,Account_Shop);", - className => "WebGUI::Account::Shop" - }, - { - identifier => "user", - title => "^International(title,Account_User);", - className => "WebGUI::Account::User" - }, - ]); - $session->config->set("profileModuleIdentifier","profile"); - #Add the content handler to the config file if it's not there - my $oldHandlers = $session->config->get( "contentHandlers" ); - unless (isIn("WebGUI::Content::Account",@{$oldHandlers})) { - my @newHandlers; - for my $handler ( @{ $oldHandlers } ) { - if ( $handler eq "WebGUI::Content::Operation" ) { - push @newHandlers, "WebGUI::Content::Account"; - } - push @newHandlers, $handler; - } - $session->config->set( "contentHandlers", \@newHandlers ); - } - - #Add the settings for the profile module - $setting->add("profileStyleTemplateId",""); #Use the userStyle by default - $setting->add("profileLayoutTemplateId","N716tpSna0iIQTKxS4gTWA"); - $setting->add("profileEditLayoutTemplateId","FJbUTvZ2nUTn65LpW6gjsA"); - $setting->add("profileEditTemplateId","75CmQgpcCSkdsL-oawdn3Q"); - $setting->add("profileViewTempalteId","2CS-BErrjMmESOtGT90qOg"); - $setting->add("profileErrorTempalteId","MBmWlA_YEA2I6D29OMGtRg"); - - #Add the settings for the inbox module - $setting->add("inboxStyleTemplateId",""); #Use the userStyle by default - $setting->add("inboxLayoutTempalteId","N716tpSna0iIQTKxS4gTWA"); - $setting->add("inboxViewTemplateId","c8xrwVuu5QE0XtF9DiVzLw"); - $setting->add("inboxViewMessageTemplateId","0n4HtbXaWa_XJHkFjetnLQ"); - $setting->add("inboxSendMessageTemplateId","6uQEULvXFgCYlRWnYzZsuA"); - $setting->add("inboxErrorTemplateId","ErEzulFiEKDkaCDVmxUavw"); - $setting->add("inboxMessageConfirmationTemplateId","DUoxlTBXhVS-Zl3CFDpt9g"); - #Invitations - $setting->add("inboxManageInvitationsTemplateId","1Q4Je3hKCJzeo0ZBB5YB8g"); - $setting->add("inboxViewInvitationTemplateId","VBkY05f-E3WJS50WpdKd1Q"); - $setting->add("inboxInvitationConfirmTemplateId","5A8Hd9zXvByTDy4x-H28qw"); - - #Add the settings for the friends module - $setting->add("friendsStyleTemplateId",""); #Use the userStyle by default - $setting->add("friendsLayoutTempalteId","N716tpSna0iIQTKxS4gTWA"); - $setting->add("friendsViewTemplateId","1Yn_zE_dSiNuaBGNLPbxtw"); - $setting->add("friendsEditTemplateId","AZFU33p0jpPJ-E6qLSWZng"); - $setting->add("friendsSendRequestTemplateId","AGJBGviWGAwjnwziiPjvDg"); - $setting->add("friendsErrorTemplateId","7Ijdd8SW32lVgg2H8R-Aqw"); - $setting->add("friendsConfirmTemplateId","K8F0j_cq_jgo8dvWY_26Ag"); - $setting->add("friendsRemoveConfirmTemplateId","G5V6neXIDiFXN05oL-U3AQ"); - - #Add the settings for the user module - $setting->add("userAccountStyleTemplateId",""); #Use the userStyle by default - $setting->add("userAccountLayoutTemplateId","9ThW278DWLV0-Svf68ljFQ"); - - #Add the settings for the shop module - $setting->add("shopStyleTemplateId",""); #Use the userStyle by default - $setting->add("shopLayoutTemplateId","aUDsJ-vB9RgP-AYvPOy8FQ"); - - #Add inbox changes - $session->db->write(q{ - create table inbox_messageState ( - messageId char(22) binary not null, - userId char(22) binary not null, - isRead tinyint(4) not null default 0, - repliedTo tinyint(4) not null default 0, - deleted tinyint(4) not null default 0, - primary key (messageId, userId) - ) - }); - - #Update the inbox - my $sth = $session->db->read("select messageId, groupId, userId, status from inbox"); - while(my ($messageId,$groupId,$userId,$status) = $sth->array) { - my $repliedTo = $status eq "replied"; - my $isRead = ($status ne "unread" && $status ne "pending")?1:0; - my $deleted = 0; - - if($status eq "deleted") { - #Purge deleted messages - $session->db->write("delete from inbox where messageId=?",[$messageId]); - next; - } - - if($groupId) { - my $g = WebGUI::Group->new($session,$groupId); - my $users = $g->getAllUsers; - foreach my $userId (@{$users}) { - $session->db->write( - q{ REPLACE INTO inbox_messageState (messageId,userId,isRead,repliedTo,deleted) VALUES (?,?,?,?,?) }, - [$messageId,$userId,$isRead,$repliedTo,$deleted] - ); - } - } - - if($userId) { - $session->db->write( - q{ REPLACE INTO inbox_messageState (messageId,userId,isRead,repliedTo,deleted) VALUES (?,?,?,?,?) }, - [$messageId,$userId,$isRead,$repliedTo,$deleted] - ); - } - - if($status ne "completed" && $status ne "pending") { - $session->db->write( - q{ UPDATE inbox SET status='active' WHERE messageId=? }, - [$messageId] - ); - } - } - - #Add the profile field changes - $session->db->write(q{alter table userProfileCategory add column shortLabel char(255) default NULL after label}); - $session->db->write(q{update userProfileCategory set shortLabel='WebGUI::International::get("misc info short","WebGUI");' where profileCategoryId='1'}); - $session->db->write(q{update userProfileCategory set shortLabel='WebGUI::International::get("contact info short","WebGUI");' where profileCategoryId='2'}); - $session->db->write(q{update userProfileCategory set shortLabel='WebGUI::International::get("personal info short","WebGUI");' where profileCategoryId='3'}); - $session->db->write(q{update userProfileCategory set shortLabel='WebGUI::International::get("preferences short","WebGUI");' where profileCategoryId='4'}); - $session->db->write(q{update userProfileCategory set shortLabel='WebGUI::International::get("home info short","WebGUI");' where profileCategoryId='5'}); - $session->db->write(q{update userProfileCategory set shortLabel='WebGUI::International::get("work info short","WebGUI");' where profileCategoryId='6'}); - $session->db->write(q{update userProfileCategory set shortLabel='WebGUI::International::get("demographic info short","WebGUI");' where profileCategoryId='7'}); - - $session->db->write(q{alter table userProfileData modify publicProfile char(10) default 'none'}); - $session->db->write(q{update userProfileData set publicProfile='none' where publicProfile='0' || publicProfile is NULL || publicProfile=''}); - $session->db->write(q{update userProfileData set publicProfile='all' where publicProfile='1'}); - $session->db->write(q{REPLACE INTO `userProfileField` VALUES ('publicProfile','WebGUI::International::get(861)',1,0,'RadioList','{ all=>WebGUI::International::get(\'public label\',\'Account_Profile\'), friends=>WebGUI::International::get(\'friends only label\',\'Account_Profile\'), none=>WebGUI::International::get(\'private label\',\'Account_Profile\')}','[\"none\"]',8,'4',1,1,0,0,0,'')}) - - - #Clean up old templates and settings - my $oldtemplates = { - editUserProfileTemplate => 'Operation/Profile/Edit', - viewUserProfileTemplate => 'Operation/Profile/View', - manageFriendsTemplateId => 'friends/manage', - sendPrivateMessageTemplateId => 'Inbox/SendPrivateMessage', - viewInboxTemplateId => 'Inbox', - viewInboxMessageTemplateId => 'Inbox/Message', - }; - - foreach my $setting (keys %{$oldtemplates}) { - #Remove the setting - $session->db->write("delete from settings where name=?",[$setting]); - #Remove all the templates with the related namespace - my $assets = $session->db->buildArrayRef("select distinct assetId from template where namespace=?",[$oldtemplates->{$setting}]); - #Purge the template - foreach my $assetId (@{$assets}) { - WebGUI::Asset->newByDynamicClass($session,$assetId)->purge; - } - } - - print "DONE!\n" unless $quiet; -} - -#---------------------------------------------------------------------------- -# installDataTableAsset -# Install the asset by creating the DB table and adding it to the config file -sub installDataTableAsset { - my $session = shift; - print "\tInstalling the DataTable asset... " unless $quiet; - - $session->db->write( <<'ENDSQL' ); - CREATE TABLE DataTable ( - assetId VARCHAR(22) BINARY NOT NULL, - revisionDate BIGINT NOT NULL, - data LONGTEXT, - templateId VARCHAR(22) BINARY, - PRIMARY KEY ( assetId, revisionDate ) - ) -ENDSQL - - my $assets = $session->config->get( "assets" ); - $assets->{ "WebGUI::Asset::Wobject::DataTable" } = { category => "basic" }; - $session->config->set( "assets", $assets ); - - print "DONE!\n" unless $quiet; -} - -#---------------------------------------------------------------------------- -# installDataTableAsset -# Install the content handler by adding it to the config file -sub installAjaxI18N { - my $session = shift; - print "\tInstalling the AjaxI18N content handler... " unless $quiet; - - my $oldHandlers = $session->config->get( "contentHandlers" ); - my @newHandlers; - for my $handler ( @{ $oldHandlers } ) { - if ( $handler eq "WebGUI::Content::Operation" ) { - push @newHandlers, "WebGUI::Content::AjaxI18N"; - } - push @newHandlers, $handler; - } - $session->config->set( "contentHandlers", \@newHandlers ); - - print "DONE!\n" unless $quiet; -} - -#---------------------------------------------------------------------------- -sub upgradeToYui26 { - my $session = shift; - print "\tUpgrading to YUI 2.6... " unless $quiet; - $session->db->write("update template set template=replace(template, 'resize-beta.js', 'resize-min.js'), headBlock=replace(headBlock, 'resize-beta.js', 'resize-min.js')"); - $session->db->write("update template set template=replace(template, 'resize-beta-min.js', 'resize-min.js'), headBlock=replace(headBlock, 'resize-beta-min.js', 'resize-min.js')"); - $session->db->write("update template set template=replace(template, 'datasource-beta.js', 'datasource-min.js'), headBlock=replace(headBlock, 'datasource-beta.js', 'datasource-min.js')"); - $session->db->write("update template set template=replace(template, 'datasource-beta-min.js', 'datasource-min.js'), headBlock=replace(headBlock, 'datasource-beta-min.js', 'datasource-min.js')"); - $session->db->write("update template set template=replace(template, 'datatable-beta.js', 'datatable-min.js'), headBlock=replace(headBlock, 'datatable-beta.js', 'datatable-min.js')"); - $session->db->write("update template set template=replace(template, 'datatable-beta-min.js', 'datatable-min.js'), headBlock=replace(headBlock, 'datatable-beta-min.js', 'datatable-min.js')"); - print "DONE!\n" unless $quiet; -} - -#---------------------------------------------------------------------------- -sub changeDefaultPaginationInSearch { - my $session = shift; - print "\tAllow content managers to change the default pagination in the search asset... " unless $quiet; - $session->db->write("ALTER TABLE `search` ADD COLUMN `paginateAfter` INTEGER NOT NULL DEFAULT 25"); - print "DONE!\n" unless $quiet; -} - -#---------------------------------------------------------------------------- -sub addUsersOnlineMacro { - my $session = shift; - print "\tMaking the UsersOnline macro available... " unless $quiet; - $session->config->addToHash("macros","UsersOnline","UsersOnline"); - print "DONE!\n" unless $quiet; -} - -#---------------------------------------------------------------------------- -sub updateAddressBook { - my $session = shift; - print "\tAdding organization and email to address book... " unless $quiet; - my $db = $session->db; - $db->write("alter table address add column organization char(255)"); - $db->write("alter table address add column email char(255)"); - print "DONE!\n" unless $quiet; -} - -#---------------------------------------------------------------------------- -sub repairManageWorkflows { - my $session = shift; - print "\tCorrecting the Manage Workflow link in configuration file... " unless $quiet; - # and here's our code - my $ac = $session->config->get('adminConsole'); - if (exists $ac->{'workflow'}) { - $ac->{'workflow'}->{'url'} = "^PageUrl(\"\",op=manageWorkflows);"; - $session->config->set('adminConsole', $ac); - } - print "DONE!\n" unless $quiet; -} - -#---------------------------------------------------------------------------- -sub addPreTextToThingyFields { - my $session = shift; - print "\tAdding a pre-text property to Thingy fields... " unless $quiet; - $session->db->write('ALTER TABLE `Thingy_fields` ADD pretext varchar(255)'); - print "DONE!\n" unless $quiet; -} - -#---------------------------------------------------------------------------- -sub addProfileExtrasField { - my $session = shift; - print "\tAdding the Extras field for profile fields... " unless $quiet; - my $db = $session->db; - $db->write('alter table userProfileField add extras text default NULL'); - print "DONE!\n" unless $quiet; -} - -#---------------------------------------------------------------------------- -# Add the workflow property to DataForm -sub addWorkflowToDataform { - my $session = shift; - print "\tAdding Workflow to DataForm... " unless $quiet; - - my $sth = $session->db->read('DESCRIBE `DataForm`'); - while (my ($col) = $sth->array) { - if ( $col eq 'workflowIdAddEntry' ) { - print "Already done, skipping.\n" unless $quiet; - return; - } - } - - $session->db->write( "ALTER TABLE DataForm ADD COLUMN workflowIdAddEntry CHAR(22) BINARY" ); - print "DONE!\n" unless $quiet; -} - -# -------------- DO NOT EDIT BELOW THIS LINE -------------------------------- - -#---------------------------------------------------------------------------- -# Add a package to the import node -sub addPackage { - my $session = shift; - my $file = shift; - - # Make a storage location for the package - my $storage = WebGUI::Storage->createTemp( $session ); - $storage->addFileFromFilesystem( $file ); - - # Import the package into the import node - my $package = WebGUI::Asset->getImportNode($session)->importPackage( $storage ); - - # Make the package not a package anymore - $package->update({ isPackage => 0 }); - - # Set the default flag for templates added - my $assetIds - = $package->getLineage( ['self','descendants'], { - includeOnlyClasses => [ 'WebGUI::Asset::Template' ], - } ); - for my $assetId ( @{ $assetIds } ) { - my $asset = WebGUI::Asset->newByDynamicClass( $session, $assetId ); - if ( !$asset ) { - print "Couldn't instantiate asset with ID '$assetId'. Please check package '$file' for corruption.\n"; - next; - } - $asset->update( { isDefault => 1 } ); - } - - return; -} - -#------------------------------------------------- -sub start { - my $configFile; - $|=1; #disable output buffering - GetOptions( - 'configFile=s'=>\$configFile, - 'quiet'=>\$quiet - ); - my $session = WebGUI::Session->open($webguiRoot,$configFile); - $session->user({userId=>3}); - my $versionTag = WebGUI::VersionTag->getWorking($session); - $versionTag->set({name=>"Upgrade to ".$toVersion}); - return $session; -} - -#------------------------------------------------- -sub finish { - my $session = shift; - updateTemplates($session); - my $versionTag = WebGUI::VersionTag->getWorking($session); - $versionTag->commit; - $session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".$session->datetime->time().")"); - $session->close(); -} - -#------------------------------------------------- -sub updateTemplates { - my $session = shift; - return undef unless (-d "packages-".$toVersion); - print "\tUpdating packages.\n" unless ($quiet); - opendir(DIR,"packages-".$toVersion); - my @files = readdir(DIR); - closedir(DIR); - my $newFolder = undef; - $session->db->write( "UPDATE asset SET parentId='infinityandbeyond' WHERE assetId='pbversion0000000000001'" ); - foreach my $file (@files) { - next unless ($file =~ /\.wgpkg$/); - # Fix the filename to include a path - $file = "packages-" . $toVersion . "/" . $file; - addPackage( $session, $file ); - } -} - -#vim:ft=perl From 6ebff9b50d3e117fa500c715326047bb43412a22 Mon Sep 17 00:00:00 2001 From: Frank Dillon Date: Sat, 15 Nov 2008 03:06:29 +0000 Subject: [PATCH 8/8] current version in head --- docs/upgrades/upgrade_7.6.1-7.6.2.pl | 278 +++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 docs/upgrades/upgrade_7.6.1-7.6.2.pl diff --git a/docs/upgrades/upgrade_7.6.1-7.6.2.pl b/docs/upgrades/upgrade_7.6.1-7.6.2.pl new file mode 100644 index 000000000..012697856 --- /dev/null +++ b/docs/upgrades/upgrade_7.6.1-7.6.2.pl @@ -0,0 +1,278 @@ +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2008 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 +#------------------------------------------------------------------- + +our ($webguiRoot); + +BEGIN { + $webguiRoot = "../.."; + unshift (@INC, $webguiRoot."/lib"); +} + +use strict; +use Getopt::Long; +use WebGUI::Session; +use WebGUI::Storage; +use WebGUI::Asset; + + +my $toVersion = '7.6.2'; +my $quiet; # this line required + + +my $session = start(); # this line required + +# upgrade functions go here +repairManageWorkflows($session); +addPreTextToThingyFields($session); +updateAddressBook($session); +changeDefaultPaginationInSearch($session); +upgradeToYui26($session); +addUsersOnlineMacro($session); +addProfileExtrasField($session); +addWorkflowToDataform( $session ); +installDataTableAsset( $session ); +installAjaxI18N( $session ); +installSiteIndex( $session ); +finish($session); # this line required + +#---------------------------------------------------------------------------- +# installDataTableAsset +# Install the asset by creating the DB table and adding it to the config file +sub installDataTableAsset { + my $session = shift; + print "\tInstalling the DataTable asset... " unless $quiet; + + $session->db->write( <<'ENDSQL' ); + CREATE TABLE DataTable ( + assetId VARCHAR(22) BINARY NOT NULL, + revisionDate BIGINT NOT NULL, + data LONGTEXT, + templateId VARCHAR(22) BINARY, + PRIMARY KEY ( assetId, revisionDate ) + ) +ENDSQL + + my $assets = $session->config->get( "assets" ); + $assets->{ "WebGUI::Asset::Wobject::DataTable" } = { category => "basic" }; + $session->config->set( "assets", $assets ); + + print "DONE!\n" unless $quiet; +} + +#---------------------------------------------------------------------------- +# installDataTableAsset +# Install the content handler by adding it to the config file +sub installAjaxI18N { + my $session = shift; + print "\tInstalling the AjaxI18N content handler... " unless $quiet; + + my @newHandlers; + my $oldHandlers = $session->config->get( "contentHandlers" ); + for my $handler ( @{ $oldHandlers } ) { + if ( $handler eq "WebGUI::Content::Operation" ) { + push @newHandlers, "WebGUI::Content::AjaxI18N"; + } + elsif ( $handler eq "WebGUI::Content::AjaxI18N" ) { + next; + } + push @newHandlers, $handler; + } + $session->config->set( "contentHandlers", \@newHandlers ); + + print "DONE!\n" unless $quiet; +} + +#---------------------------------------------------------------------------- +# installSiteIndex +# Install the content handler by adding it to the config file +sub installSiteIndex { + my $session = shift; + print "\tInstalling the SiteIndex content handler... " unless $quiet; + + my $oldHandlers = $session->config->get( "contentHandlers" ); + my @newHandlers; + for my $handler ( @{ $oldHandlers } ) { + if ( $handler eq "WebGUI::Content::Asset" ) { + push @newHandlers, "WebGUI::Content::SiteIndex"; + } + push @newHandlers, $handler; + } + $session->config->set( "contentHandlers", \@newHandlers ); + + print "DONE!\n" unless $quiet; +} + + +#---------------------------------------------------------------------------- +sub upgradeToYui26 { + my $session = shift; + print "\tUpgrading to YUI 2.6... " unless $quiet; + $session->db->write("update template set template=replace(template, 'resize-beta.js', 'resize-min.js'), headBlock=replace(headBlock, 'resize-beta.js', 'resize-min.js')"); + $session->db->write("update template set template=replace(template, 'resize-beta-min.js', 'resize-min.js'), headBlock=replace(headBlock, 'resize-beta-min.js', 'resize-min.js')"); + $session->db->write("update template set template=replace(template, 'datasource-beta.js', 'datasource-min.js'), headBlock=replace(headBlock, 'datasource-beta.js', 'datasource-min.js')"); + $session->db->write("update template set template=replace(template, 'datasource-beta-min.js', 'datasource-min.js'), headBlock=replace(headBlock, 'datasource-beta-min.js', 'datasource-min.js')"); + $session->db->write("update template set template=replace(template, 'datatable-beta.js', 'datatable-min.js'), headBlock=replace(headBlock, 'datatable-beta.js', 'datatable-min.js')"); + $session->db->write("update template set template=replace(template, 'datatable-beta-min.js', 'datatable-min.js'), headBlock=replace(headBlock, 'datatable-beta-min.js', 'datatable-min.js')"); + print "DONE!\n" unless $quiet; +} + +#---------------------------------------------------------------------------- +sub changeDefaultPaginationInSearch { + my $session = shift; + print "\tAllow content managers to change the default pagination in the search asset... " unless $quiet; + $session->db->write("ALTER TABLE `search` ADD COLUMN `paginateAfter` INTEGER NOT NULL DEFAULT 25"); + print "DONE!\n" unless $quiet; +} + +#---------------------------------------------------------------------------- +sub addUsersOnlineMacro { + my $session = shift; + print "\tMaking the UsersOnline macro available... " unless $quiet; + $session->config->addToHash("macros","UsersOnline","UsersOnline"); + print "DONE!\n" unless $quiet; +} + +#---------------------------------------------------------------------------- +sub updateAddressBook { + my $session = shift; + print "\tAdding organization and email to address book... " unless $quiet; + my $db = $session->db; + $db->write("alter table address add column organization char(255)"); + $db->write("alter table address add column email char(255)"); + print "DONE!\n" unless $quiet; +} + +#---------------------------------------------------------------------------- +sub repairManageWorkflows { + my $session = shift; + print "\tCorrecting the Manage Workflow link in configuration file... " unless $quiet; + # and here's our code + my $ac = $session->config->get('adminConsole'); + if (exists $ac->{'workflow'}) { + $ac->{'workflow'}->{'url'} = "^PageUrl(\"\",op=manageWorkflows);"; + $session->config->set('adminConsole', $ac); + } + print "DONE!\n" unless $quiet; +} + +#---------------------------------------------------------------------------- +sub addPreTextToThingyFields { + my $session = shift; + print "\tAdding a pre-text property to Thingy fields... " unless $quiet; + $session->db->write('ALTER TABLE `Thingy_fields` ADD pretext varchar(255)'); + print "DONE!\n" unless $quiet; +} + +#---------------------------------------------------------------------------- +sub addProfileExtrasField { + my $session = shift; + print "\tAdding the Extras field for profile fields... " unless $quiet; + my $db = $session->db; + $db->write('alter table userProfileField add extras text default NULL'); + print "DONE!\n" unless $quiet; +} + +#---------------------------------------------------------------------------- +# Add the workflow property to DataForm +sub addWorkflowToDataform { + my $session = shift; + print "\tAdding Workflow to DataForm... " unless $quiet; + + my $sth = $session->db->read('DESCRIBE `DataForm`'); + while (my ($col) = $sth->array) { + if ( $col eq 'workflowIdAddEntry' ) { + print "Already done, skipping.\n" unless $quiet; + return; + } + } + + $session->db->write( "ALTER TABLE DataForm ADD COLUMN workflowIdAddEntry CHAR(22) BINARY" ); + print "DONE!\n" unless $quiet; +} + +# -------------- DO NOT EDIT BELOW THIS LINE -------------------------------- + +#---------------------------------------------------------------------------- +# Add a package to the import node +sub addPackage { + my $session = shift; + my $file = shift; + + # Make a storage location for the package + my $storage = WebGUI::Storage->createTemp( $session ); + $storage->addFileFromFilesystem( $file ); + + # Import the package into the import node + my $package = WebGUI::Asset->getImportNode($session)->importPackage( $storage ); + + # Make the package not a package anymore + $package->update({ isPackage => 0 }); + + # Set the default flag for templates added + my $assetIds + = $package->getLineage( ['self','descendants'], { + includeOnlyClasses => [ 'WebGUI::Asset::Template' ], + } ); + for my $assetId ( @{ $assetIds } ) { + my $asset = WebGUI::Asset->newByDynamicClass( $session, $assetId ); + if ( !$asset ) { + print "Couldn't instantiate asset with ID '$assetId'. Please check package '$file' for corruption.\n"; + next; + } + $asset->update( { isDefault => 1 } ); + } + + return; +} + +#------------------------------------------------- +sub start { + my $configFile; + $|=1; #disable output buffering + GetOptions( + 'configFile=s'=>\$configFile, + 'quiet'=>\$quiet + ); + my $session = WebGUI::Session->open($webguiRoot,$configFile); + $session->user({userId=>3}); + my $versionTag = WebGUI::VersionTag->getWorking($session); + $versionTag->set({name=>"Upgrade to ".$toVersion}); + return $session; +} + +#------------------------------------------------- +sub finish { + my $session = shift; + updateTemplates($session); + my $versionTag = WebGUI::VersionTag->getWorking($session); + $versionTag->commit; + $session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".$session->datetime->time().")"); + $session->close(); +} + +#------------------------------------------------- +sub updateTemplates { + my $session = shift; + return undef unless (-d "packages-".$toVersion); + print "\tUpdating packages.\n" unless ($quiet); + opendir(DIR,"packages-".$toVersion); + my @files = readdir(DIR); + closedir(DIR); + my $newFolder = undef; + $session->db->write( "UPDATE asset SET parentId='infinityandbeyond' WHERE assetId='pbversion0000000000001'" ); + foreach my $file (@files) { + next unless ($file =~ /\.wgpkg$/); + # Fix the filename to include a path + $file = "packages-" . $toVersion . "/" . $file; + addPackage( $session, $file ); + } +} + +#vim:ft=perl