From 606d4c12e938f426ecaad46325e8ef4fac35941b Mon Sep 17 00:00:00 2001 From: Yung Han Khoe Date: Wed, 9 Apr 2008 12:48:20 +0000 Subject: [PATCH 01/16] Creating a branch for the Userlist wobject From 3c176de33a9ba0872bbf3bdd5f176ff3bee42a73 Mon Sep 17 00:00:00 2001 From: Yung Han Khoe Date: Fri, 16 May 2008 15:29:52 +0000 Subject: [PATCH 02/16] Initial import --- lib/WebGUI/Asset/Wobject/UserList.pm | 419 +++++++++++++++++++++++++++ 1 file changed, 419 insertions(+) create mode 100644 lib/WebGUI/Asset/Wobject/UserList.pm diff --git a/lib/WebGUI/Asset/Wobject/UserList.pm b/lib/WebGUI/Asset/Wobject/UserList.pm new file mode 100644 index 000000000..f6e2b9aff --- /dev/null +++ b/lib/WebGUI/Asset/Wobject/UserList.pm @@ -0,0 +1,419 @@ +package WebGUI::Asset::Wobject::UserList; + +#$VERSION = "2.0.0"; + +use strict; +use warnings; +use HTML::Entities; +use Tie::CPHash; +use Tie::IxHash; +use WebGUI::Utility; +use WebGUI::Asset::Wobject; +use WebGUI::Operation::Shared; +use WebGUI::International; + +our @ISA = qw(WebGUI::Asset::Wobject); + +=head1 LEGAL + +Copyright 2004-2008 United Knowledge + +See the doc/license-UserList.txt file for licensing information. + +http://www.unitedknowledge.nl +developmentinfo@unitedknowledge.nl + +=head1 NAME + +Package WebGUI::Asset::Wobject::UserList + +=head1 DESCRIPTION + +This wobject gives a list of webgui users. +The username is always shown. +The userId is only shown in Admin mode. +The wobject also checks the publicProfile and publicEmail setting for each user. + +=head1 SYNOPSIS + +my $wobject = WebGUI::Wobject::UserList->new(\%properties); + +$text = $wobject->name; + +$html = $wobject->www_edit; +$html = $wobject->www_view; + +=cut + +#------------------------------------------------------------------- + +=head2 getAlphabetSearchLoop ( ) + +Returns an array ref that contains tmpl_vars for the Alphabet Search. + +=cut + +sub getAlphabetSearchLoop { + my $self = shift; + my $fieldName = shift; + my $alphabet = shift; + my (@alphabet, @alphabetLoop); + $alphabet ||= "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z"; + @alphabet = split(/,/,$alphabet); + foreach my $letter (@alphabet){ + my $htmlEncodedLetter = encode_entities($letter); + #print "adding letter ".$letter.",htmlEncodedLetter: $htmlEncodedLetter
"; + my $searchURL = "?searchExact_".$fieldName."=".$letter."%25"; + my $hasResults = $self->session->db->quickScalar("select if (" + ."(select count(*) from userProfileData where lastName like '".$letter."%')<>0, 1, 0)"); + push @alphabetLoop, { + label => $htmlEncodedLetter || $letter, + hasResults => $hasResults, + searchURL => $searchURL, + } + } + return \@alphabetLoop; +} + +#------------------------------------------------------------------- + +=head2 definition ( properties ) + +Defines wobject properties for UserList instances. + +=head3 properties + +A hash reference containing the properties of this wobject. + +=cut + +sub definition { + my $class = shift; + my $session = shift; + my $definition = shift; + my %properties; + my $i18n = WebGUI::International->new($session, 'Asset_UserList'); + tie %properties, 'Tie::IxHash'; + %properties = ( + templateId =>{ + fieldType=>"template", + defaultValue=>'UserListTmpl0000001', + namespace=>'UserList', + tab=>"display", + }, + + showGroupId=>{ + fieldType=>"group", + defaultValue=>"", + label=>$i18n->get("Group to show"), + tab=>"display", + }, + hideGroupId=>{ + fieldType=>"group", + defaultValue=>"", + label=>$i18n->get("Group to hide"), + tab=>"display", + }, + usersPerPage=>{ + fieldType=>"integer", + defaultValue=>"25", + tab=>"display", + label=>'Users per Page', + }, + alphabet=>{ + fieldType=>"text", + defaultValue=>"", + tab=>"display", + label=>'Alphabet', + }, + ); + + push(@{$definition}, { + assetName=>"UserList", + icon=>'userlist.gif', + autoGenerateForms=>1, + tableName=>'UserList', + className=>'WebGUI::Asset::Wobject::UserList', + properties=>\%properties + }); + return $class->SUPER::definition($session, $definition); +} + +#------------------------------------------------------------------- + +=head2 getEditForm ( ) + +Returns a tab form containing the properties of this wobject. + +=cut + +sub getEditForm { + my $self = shift; + my $tabform = $self->SUPER::getEditForm(); + + my $i18n = WebGUI::International->new($self->session, "Asset_UserList"); + + return $tabform; +} + +#------------------------------------------------------------------- + +=head2 isInGroup ( [ groupId ] ) + +Returns a boolean (0|1) value signifying that the user has the required privileges. Always returns true for Admins. +The UserList Wobject has its own isInGroup method for performance reasons, instead of using the WebGUI::User API. +To use the API a User object would have to be created for every user. This in turn would mean to unnessecary hits on the +database. + +=head3 groupId + +The group that you wish to verify against the user. Defaults to group with Id 3 (the Admin group). + +=cut + +sub isInGroup { + my (@data, $groupId); + my ($self, $gid, $uid, $secondRun) = @_; + $gid = 3 unless (defined $gid); + ### The following several checks are to increase performance. If this section were removed, everything would continue to work as normal. + #my $eh = $self->session->errorHandler; + #$eh->warn("Group Id is: $gid for ".$tgroup->name); + return 1 if ($gid eq '7'); # everyone is in the everyone group + return 1 if ($gid eq '1' && $uid eq '1'); # visitors are in the visitors group + return 1 if ($gid eq '2' && $uid ne '1'); # if you're not a visitor, then you're a registered user + ### Get data for auxillary checks. + my $isInGroup = $self->session->stow->get("isInGroup"); + ### Look to see if we've already looked up this group. + return $isInGroup->{$uid}{$gid} if exists $isInGroup->{$uid}{$gid}; + ### Lookup the actual groupings. + my $group = WebGUI::Group->new($self->session,$gid); + # Cope with non-existant groups. Default to the admin group if the groupId is invalid. + $group = WebGUI::Group->new($self->session, 3) unless $group; + ### Check for groups of groups. + my $users = $group->getAllUsers(); + foreach my $user (@{$users}) { + $isInGroup->{$user}{$gid} = 1; + if ($uid eq $user) { + $self->session->stow->set("isInGroup",$isInGroup); + return 1; + } + } + $isInGroup->{$uid}{$gid} = 0; + $self->session->stow->set("isInGroup",$isInGroup); + return 0; +} + +#------------------------------------------------------------------- + +=head2 prepareView ( ) + +See WebGUI::Asset::prepareView() for details. + +=cut + +sub prepareView { + my $self = shift; + $self->SUPER::prepareView(); + my $templateId = $self->get("templateId"); + if ($self->session->form->process("overrideTemplateId") ne "") { + $templateId = $self->session->form->process("overrideTemplateId"); + } + my $template = WebGUI::Asset::Template->new($self->session, $templateId); + $template->prepare; + $self->{_viewTemplate} = $template; +} + +#------------------------------------------------------------------- + +=head2 view ( ) + +=cut + +sub view { + + my $self = shift; + my $i18n = WebGUI::International->new($self->session, "Asset_UserList"); + my (%var, @users, @profileField_loop, @profileFields,@profileFieldNames); + my ($defaultPublicProfile, $defaultPublicEmail, $user, $sth, $sql, $profileField); + my $error = $self->session->errorHandler; + my $start_time = time(); + +# $error->info("time :".(time() - $start_time)); + + $sth = $self->session->db->read("SELECT field.fieldName, field.label, field.sequenceNumber " + ."FROM userProfileField as field " + ."left join userProfileCategory as category USING(profileCategoryId) " + ."ORDER BY category.sequenceNumber, field.sequenceNumber"); + while ($profileField = $sth->hashRef){ + my $label = WebGUI::Operation::Shared::secureEval($self->session,$profileField->{label}); + push(@profileFields, { + "fieldName"=>$profileField->{fieldName}, + "label"=>$label, + "sequenceNumber"=>$profileField->{sequenceNumber}, + }); + push(@profileFieldNames, $profileField->{fieldName}); + $var{'profileField_'.$profileField->{fieldName}.'_label'} = $label; + } + +# $error->info("selected profile fields, time :".(time() - $start_time)); + $sql = "select distinct users.userId, users.userName, userProfileData.publicProfile, userProfileData.publicEmail "; + + foreach my $profileField (@profileFields){ + $sql .= ", userProfileData.$profileField->{fieldName}"; + } + $sql .= " from users"; + $sql .= " left join userProfileData using(userId) where users.userId != '1'"; + +# $error->info("creating constraint, time :".(time() - $start_time)); + my $constraint; + if ($self->session->form->process('search')){ + $constraint = "(".join(' or ', map {'userProfileData.'.$_->{fieldName}.' like "%'.$self->session->form->process('search').'%"'} @profileFields).")"; + }elsif ($self->session->form->process('searchExact')){ + $constraint = "(".join(' or ', map {'userProfileData.'.$_->{fieldName}.' like "'.$self->session->form->process('searchExact').'"'} @profileFields).")"; + }else{ + my @profileSearchFields = (); + my @profileSearchExactFields = (); + foreach my $profileField (@profileFields){ + if ($self->session->form->process('search_'.$profileField->{fieldName})){ + push(@profileSearchFields,$profileField); + } + if ($self->session->form->process('searchExact_'.$profileField->{fieldName})){ + push(@profileSearchExactFields,$profileField); + } + } + my $searchType = $self->session->form->process('searchType') || 'or'; + if (scalar(@profileSearchFields) > 0){ + $constraint = "(".join(' '.$searchType.' ', map {'userProfileData.'.$_->{fieldName}.' like "%' + .$self->session->form->process('search_'.$_->{fieldName}).'%"'} @profileSearchFields).")"; + foreach my $profileSearchField (@profileSearchFields){ + } + } + if (scalar(@profileSearchExactFields) > 0){ + $constraint = "(".join(' '.$searchType.' ', map {'userProfileData.'.$_->{fieldName}.' like"' + .$self->session->form->process('searchExact_'.$_->{fieldName}).'"'} @profileSearchExactFields).")"; + } + } + $sql .= " and ".$constraint if ($constraint); + +# $error->info("created constraint, time :".(time() - $start_time)); + + my $formOrderBy = $self->session->form->process('orderBy'); + my $orderBy = 'userName'; + my $orderType = $self->session->form->process('orderType') || 'asc'; + + my @orderByUserProperties = ('dateCreated', 'lastUpdated', 'karma', 'userId'); + if ($formOrderBy){ + if(isIn($formOrderBy,@profileFieldNames)){ + $orderBy = $formOrderBy; + }elsif(isIn($formOrderBy,@orderByUserProperties)){ + $orderBy = 'users.'.$formOrderBy; + } + } + $sql .= " order by ".$orderBy." ".$orderType; + + ($defaultPublicProfile) = $self->session->db->quickArray("SELECT dataDefault FROM userProfileField WHERE fieldName='publicProfile'"); + ($defaultPublicEmail) = $self->session->db->quickArray("SELECT dataDefault FROM userProfileField WHERE fieldName='publicEmail'"); + + my $paginatePage = $self->session->form->param('pn') || 1; + my $currentUrl = $self->getUrl(); + foreach ($self->session->form->param) { + unless ($_ eq "pn" || $_ eq "op" || $_ eq "func" || $_ =~ /identifier/i || $_ =~ /password/i) { + $currentUrl = $self->session->url->append($currentUrl, $self->session->url->escape($_) + .'='.$self->session->url->escape($self->session->form->process($_))); + } + } + + my $p = WebGUI::Paginator->new($self->session,$currentUrl,$self->getValue("usersPerPage"), undef, $paginatePage); + +# $error->info("reading from database, time :".(time() - $start_time)); + $sth = $self->session->db->read($sql); +# $error->info("users read from database, time :".(time() - $start_time)); + my @visibleUsers; + while (my $user = $sth->hashRef){ + my $showGroupId = $self->get("showGroupId"); + if ($showGroupId eq '0' || ($showGroupId && $self->isInGroup($showGroupId,$user->{userId}))){ + unless ($self->get("hideGroupId") ne '0' && $self->isInGroup($self->get("hideGroupId"),$user->{userId})){ + push(@visibleUsers,$user); + } + } + } +# $error->info("applied group constraints, time :".(time() - $start_time)); + $p->setDataByArrayRef(\@visibleUsers); + my $users = $p->getPageData($paginatePage); +# $error->info("set data by page, time :".(time() - $start_time)); + foreach my $user (@$users){ + if ($user->{publicProfile} eq "1" || ($user->{publicProfile} eq "" && $defaultPublicProfile eq "1")){ + my (@profileFieldValues); + my %userProperties; + my $emailNotPublic; + $emailNotPublic = 1 if ($user->{publicEmail} eq "0" || ($user->{publicEmail} eq "" && $defaultPublicEmail ne "1")); + foreach my $profileField (@profileFields){ + if ($profileField->{fieldName} eq "email" && $emailNotPublic){ + push (@profileFieldValues, { + "profile.emailNotPublic"=>1, + }); + }else{ + push (@profileFieldValues, { + "profile.value"=>$user->{$profileField->{fieldName}}, + }); + $userProperties{$profileField->{fieldName}.'_value'} = $user->{$profileField->{fieldName}}; + my $profileFieldName = $profileField->{fieldName}; + $profileFieldName =~ s/ /_/g; + $userProperties{"user.profile.".$profileFieldName.".value"} = $user->{$profileField->{fieldName}}; + } + } + $userProperties{"user.profile.emailNotPublic"} = $emailNotPublic; + $userProperties{"user.id"} = $user->{userId}; + $userProperties{"user.name"} = $user->{userName}; + $userProperties{"user.profile_loop"} = \@profileFieldValues; + push(@users,\%userProperties); + }else{ + push(@users, { + "user.id"=>$user->{userId}, + "user.name"=>$user->{userName}, + }); + } + } +# $error->info("created tmpl vars for users, time :".(time() - $start_time)); + foreach my $profileField (@profileFields){ + push (@profileField_loop, { + "profileField.label"=>WebGUI::Operation::Shared::secureEval($self->session,$profileField->{label}), + }); + } + $var{"numberOfProfileFields"} = scalar(@profileFields); + $var{"profileNotPublic.message"} = $i18n->get("Profile not public"); + $var{"emailNotPublic.message"} = $i18n->get("Email not public"); + $var{profileField_loop} = \@profileField_loop; + $var{user_loop} = \@users; + $p->appendTemplateVars(\%var); + + $var{searchFormHeader} = WebGUI::Form::formHeader($self->session,{action => $self->getUrl}); + $var{'searchFormTypeOr'} = WebGUI::Form::hidden($self->session, {name=>'searchType', value=>'or'}); + $var{'searchFormTypeAnd'} = WebGUI::Form::hidden($self->session, {name=>'searchType', value=>'and'}); + $var{'searchFormTypeSelect'} = WebGUI::Form::selectBox($self->session,{ + name=>'searchType', + value=>'or', + options=> { + 'or' => 'or', + 'and' => 'and', + } + }); + + $var{'searchFormQuery.label'} = $i18n->get('query'); + $var{'searchFormQuery.form'} = WebGUI::Form::text($self->session,{ + name=>'search', + value=>$self->session->form->process("search"), + }); + + $var{searchFormSubmit} = WebGUI::Form::submit($self->session,{value => "Search"}); + $var{searchFormFooter} = WebGUI::Form::formFooter($self->session); + $var{alphabetSearchLoop} = $self->getAlphabetSearchLoop("lastName",$self->get("alphabet")); + +# $error->info("global tmpl_vars created, time :".(time() - $start_time)); + my $out = $self->processTemplate(\%var,$self->get("templateId")); + $out = $self->processStyle($out) if ($self->session->form->process("func") eq "list"); +# $error->info("done, going to return output, time :".(time() - $start_time)); + return $out; +} + +1; From 846dc2cc60720508432d1041c53f1acba0537ebe Mon Sep 17 00:00:00 2001 From: Yung Han Khoe Date: Fri, 16 May 2008 16:18:18 +0000 Subject: [PATCH 03/16] Some templating changes --- lib/WebGUI/Asset/Wobject/UserList.pm | 64 +++++++++++++++++----------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/lib/WebGUI/Asset/Wobject/UserList.pm b/lib/WebGUI/Asset/Wobject/UserList.pm index f6e2b9aff..96da17edf 100644 --- a/lib/WebGUI/Asset/Wobject/UserList.pm +++ b/lib/WebGUI/Asset/Wobject/UserList.pm @@ -125,6 +125,12 @@ sub definition { defaultValue=>"", tab=>"display", label=>'Alphabet', + }, + showOnlyVisibleAsNamed=>{ + fieldType=>"yesNo", + defaultValue=>"0", + tab=>"display", + label=>'Show only visible fields as named tmpl_vars.', }, ); @@ -240,19 +246,22 @@ sub view { # $error->info("time :".(time() - $start_time)); - $sth = $self->session->db->read("SELECT field.fieldName, field.label, field.sequenceNumber " + $sth = $self->session->db->read("SELECT field.fieldName, field.label, field.sequenceNumber, field.visible " ."FROM userProfileField as field " ."left join userProfileCategory as category USING(profileCategoryId) " ."ORDER BY category.sequenceNumber, field.sequenceNumber"); while ($profileField = $sth->hashRef){ my $label = WebGUI::Operation::Shared::secureEval($self->session,$profileField->{label}); - push(@profileFields, { - "fieldName"=>$profileField->{fieldName}, - "label"=>$label, - "sequenceNumber"=>$profileField->{sequenceNumber}, - }); + push(@profileFields, { + "fieldName"=>$profileField->{fieldName}, + "label"=>$label, + "sequenceNumber"=>$profileField->{sequenceNumber}, + "visible"=>$profileField->{visible}, + }); push(@profileFieldNames, $profileField->{fieldName}); - $var{'profileField_'.$profileField->{fieldName}.'_label'} = $label; + unless($self->get("showOnlyVisibleAsNamed") && $profileField->{visible} != 1){ + $var{'profileField_'.$profileField->{fieldName}.'_label'} = $label; + } } # $error->info("selected profile fields, time :".(time() - $start_time)); @@ -350,39 +359,42 @@ sub view { foreach my $profileField (@profileFields){ if ($profileField->{fieldName} eq "email" && $emailNotPublic){ push (@profileFieldValues, { - "profile.emailNotPublic"=>1, + "profile_emailNotPublic"=>1, }); }else{ push (@profileFieldValues, { - "profile.value"=>$user->{$profileField->{fieldName}}, + "profile_value"=>$user->{$profileField->{fieldName}}, }); - $userProperties{$profileField->{fieldName}.'_value'} = $user->{$profileField->{fieldName}}; - my $profileFieldName = $profileField->{fieldName}; + my $profileFieldName = $profileField->{fieldName}; $profileFieldName =~ s/ /_/g; - $userProperties{"user.profile.".$profileFieldName.".value"} = $user->{$profileField->{fieldName}}; + $profileFieldName =~ s/\./_/g; + unless($self->get("showOnlyVisibleAsNamed") && $profileField->{visible} != 1){ + $userProperties{'user_profile_'.$profileFieldName.'_value'} = $user->{$profileField->{fieldName}}; + } + #$userProperties{"user.profile.".$profileFieldName.".value"} = $user->{$profileField->{fieldName}}; } } - $userProperties{"user.profile.emailNotPublic"} = $emailNotPublic; - $userProperties{"user.id"} = $user->{userId}; - $userProperties{"user.name"} = $user->{userName}; - $userProperties{"user.profile_loop"} = \@profileFieldValues; + $userProperties{"user_profile_emailNotPublic"} = $emailNotPublic; + $userProperties{"user_id"} = $user->{userId}; + $userProperties{"user_name"} = $user->{userName}; + $userProperties{"user_profile_loop"} = \@profileFieldValues; push(@users,\%userProperties); }else{ push(@users, { - "user.id"=>$user->{userId}, - "user.name"=>$user->{userName}, + "user_id"=>$user->{userId}, + "user_name"=>$user->{userName}, }); } } # $error->info("created tmpl vars for users, time :".(time() - $start_time)); foreach my $profileField (@profileFields){ push (@profileField_loop, { - "profileField.label"=>WebGUI::Operation::Shared::secureEval($self->session,$profileField->{label}), + "profileField_label"=>WebGUI::Operation::Shared::secureEval($self->session,$profileField->{label}), }); } $var{"numberOfProfileFields"} = scalar(@profileFields); - $var{"profileNotPublic.message"} = $i18n->get("Profile not public"); - $var{"emailNotPublic.message"} = $i18n->get("Email not public"); + $var{"profileNotPublic_message"} = $i18n->get("Profile not public"); + $var{"emailNotPublic_message"} = $i18n->get("Email not public"); $var{profileField_loop} = \@profileField_loop; $var{user_loop} = \@users; $p->appendTemplateVars(\%var); @@ -394,13 +406,13 @@ sub view { name=>'searchType', value=>'or', options=> { - 'or' => 'or', - 'and' => 'and', - } + 'or' => 'or', + 'and' => 'and', + } }); - $var{'searchFormQuery.label'} = $i18n->get('query'); - $var{'searchFormQuery.form'} = WebGUI::Form::text($self->session,{ + $var{'searchFormQuery_label'} = $i18n->get('query'); + $var{'searchFormQuery_form'} = WebGUI::Form::text($self->session,{ name=>'search', value=>$self->session->form->process("search"), }); From 4b120aed1043e3dd8cb0ee5f76789cc6087bc8fa Mon Sep 17 00:00:00 2001 From: Yung Han Khoe Date: Fri, 16 May 2008 21:23:56 +0000 Subject: [PATCH 04/16] Updated internationalization and hoverhelp --- lib/WebGUI/Asset/Wobject/UserList.pm | 37 ++++---- lib/WebGUI/i18n/English/Asset_UserList.pm | 111 ++++++++++++++++++++++ 2 files changed, 132 insertions(+), 16 deletions(-) create mode 100644 lib/WebGUI/i18n/English/Asset_UserList.pm diff --git a/lib/WebGUI/Asset/Wobject/UserList.pm b/lib/WebGUI/Asset/Wobject/UserList.pm index 96da17edf..3a775be04 100644 --- a/lib/WebGUI/Asset/Wobject/UserList.pm +++ b/lib/WebGUI/Asset/Wobject/UserList.pm @@ -104,38 +104,43 @@ sub definition { showGroupId=>{ fieldType=>"group", - defaultValue=>"", - label=>$i18n->get("Group to show"), + defaultValue=>"7", + label=>$i18n->get("Group to show label"), + hoverHelp=>$i18n->get('Group to show description'), tab=>"display", }, hideGroupId=>{ fieldType=>"group", - defaultValue=>"", - label=>$i18n->get("Group to hide"), - tab=>"display", + defaultValue=>"3", + label=>$i18n->get("Group to hide label"), + hoverHelp=>$i18n->get('Group to hide description'), + tab=>"display", }, usersPerPage=>{ fieldType=>"integer", defaultValue=>"25", tab=>"display", - label=>'Users per Page', + hoverHelp=>$i18n->get('Users per page description'), + label=>$i18n->get("Users per page label"), }, alphabet=>{ fieldType=>"text", defaultValue=>"", tab=>"display", - label=>'Alphabet', + label=>$i18n->get("alphabet label"), + hoverHelp=>$i18n->get('alphabet description'), }, showOnlyVisibleAsNamed=>{ fieldType=>"yesNo", defaultValue=>"0", tab=>"display", - label=>'Show only visible fields as named tmpl_vars.', + label=>$i18n->get("showOnlyVisibleAsNamed label"), + hoverHelp=>$i18n->get('showOnlyVisibleAsNamed description'), }, ); push(@{$definition}, { - assetName=>"UserList", + assetName=>$i18n->get('assetName'), icon=>'userlist.gif', autoGenerateForms=>1, tableName=>'UserList', @@ -392,9 +397,9 @@ sub view { "profileField_label"=>WebGUI::Operation::Shared::secureEval($self->session,$profileField->{label}), }); } - $var{"numberOfProfileFields"} = scalar(@profileFields); - $var{"profileNotPublic_message"} = $i18n->get("Profile not public"); - $var{"emailNotPublic_message"} = $i18n->get("Email not public"); + $var{numberOfProfileFields} = scalar(@profileFields); + $var{profileNotPublic_message} = $i18n->get('Profile not public message'); + $var{emailNotPublic_message} = $i18n->get('Email not public message'); $var{profileField_loop} = \@profileField_loop; $var{user_loop} = \@users; $p->appendTemplateVars(\%var); @@ -406,18 +411,18 @@ sub view { name=>'searchType', value=>'or', options=> { - 'or' => 'or', - 'and' => 'and', + 'or' => $i18n->get('or label'), + 'and' => $i18n->get('and label'), } }); - $var{'searchFormQuery_label'} = $i18n->get('query'); + $var{'searchFormQuery_label'} = $i18n->get('query label'); $var{'searchFormQuery_form'} = WebGUI::Form::text($self->session,{ name=>'search', value=>$self->session->form->process("search"), }); - $var{searchFormSubmit} = WebGUI::Form::submit($self->session,{value => "Search"}); + $var{searchFormSubmit} = WebGUI::Form::submit($self->session,{value => $i18n->get('submit search label')}); $var{searchFormFooter} = WebGUI::Form::formFooter($self->session); $var{alphabetSearchLoop} = $self->getAlphabetSearchLoop("lastName",$self->get("alphabet")); diff --git a/lib/WebGUI/i18n/English/Asset_UserList.pm b/lib/WebGUI/i18n/English/Asset_UserList.pm new file mode 100644 index 000000000..a9edfdc44 --- /dev/null +++ b/lib/WebGUI/i18n/English/Asset_UserList.pm @@ -0,0 +1,111 @@ +package WebGUI::i18n::English::Asset_UserList; + +our $I18N = { + 'assetName' => { + message => q|User List|, + lastUpdated => 1081514049, + }, + + 'UserList Add/Edit' => { + message => q|User List Add/Edit|, + lastUpdated => 1081514049 + }, + + 'UserList Template' => { + message => q|User List Template|, + lastUpdated => 1081514049 + }, + + 'Edit/Add UserList' => { + message => q|Edit/Add User List|, + lastUpdated => 1081514049 + }, + + 'Group to show label' => { + message => q|Group to show|, + lastUpdated => 1081514049 + }, + + 'Group to show description' => { + message => q|Only users in this group will be shown in the user list. The default value is +'Everyone'.|, + lastUpdated => 1081514049 + }, + + 'Group to hide label' => { + message => q|Group to hide|, + lastUpdated => 1081514049 + }, + + 'Group to hide description' => { + message => q|Select a group to hide from the user list. The default value is 'Admins'.|, + lastUpdated => 1081514049 + }, + + 'Users per page label' => { + message => q|Users per page|, + lastUpdated => 1081514049 + }, + + 'Users per page description' => { + message => q|The number of users per page|, + lastUpdated => 1081514049 + }, + + 'showOnlyVisibleAsNamed label' => { + message => q|Show only visible fields as named tmpl_vars|, + lastUpdated => 1081514049 + }, + + 'showOnlyVisibleAsNamed description' => { + message => q|If set to Yes then only fields that are set to 'visible' in the user profile settings +will be available as named tmpl_vars|, + lastUpdated => 1081514049 + }, + + 'alphabet label' => { + message => q|Alphabet|, + lastUpdated => 1081514049 + }, + + 'alphabet description' => { + message => q|The alphabet that is used for the alphabet search. Has to be a string of comma +seperated values|, + lastUpdated => 1081514049 + }, + + 'Profile not public message' => { + message => q|Profile not public|, + lastUpdated => 1081514049 + }, + + 'Email not public message' => { + message => q|Email not public|, + lastUpdated => 1081514049 + }, + + 'query label' => { + message => q|Query|, + lastUpdated => 1081514049 + }, + + 'submit search label' => { + message => q|Search|, + lastUpdated => 1081514049 + }, + + 'or label' => { + message => q|Or|, + lastUpdated => 1081514049 + }, + + 'and label' => { + message => q|And|, + lastUpdated => 1081514049 + }, + + +}; + +1; + From 9968a25729f77d5df08da1336e9635cc51d8ae31 Mon Sep 17 00:00:00 2001 From: Yung Han Khoe Date: Mon, 19 May 2008 18:24:27 +0000 Subject: [PATCH 05/16] Added Help, code cleanup, some template changes --- lib/WebGUI/Asset/Wobject/UserList.pm | 155 ++++++++++------------ lib/WebGUI/Help/Asset_UserList.pm | 81 +++++++++++ lib/WebGUI/i18n/English/Asset_UserList.pm | 145 ++++++++++++++++++++ 3 files changed, 295 insertions(+), 86 deletions(-) create mode 100644 lib/WebGUI/Help/Asset_UserList.pm diff --git a/lib/WebGUI/Asset/Wobject/UserList.pm b/lib/WebGUI/Asset/Wobject/UserList.pm index 3a775be04..e9716312e 100644 --- a/lib/WebGUI/Asset/Wobject/UserList.pm +++ b/lib/WebGUI/Asset/Wobject/UserList.pm @@ -67,9 +67,9 @@ sub getAlphabetSearchLoop { my $hasResults = $self->session->db->quickScalar("select if (" ."(select count(*) from userProfileData where lastName like '".$letter."%')<>0, 1, 0)"); push @alphabetLoop, { - label => $htmlEncodedLetter || $letter, - hasResults => $hasResults, - searchURL => $searchURL, + alphabetSearch_loop_label => $htmlEncodedLetter || $letter, + alphabetSearch_loop_hasResults => $hasResults, + alphabetSearch_loop_searchURL => $searchURL, } } return \@alphabetLoop; @@ -88,56 +88,56 @@ A hash reference containing the properties of this wobject. =cut sub definition { - my $class = shift; - my $session = shift; - my $definition = shift; - my %properties; - my $i18n = WebGUI::International->new($session, 'Asset_UserList'); - tie %properties, 'Tie::IxHash'; - %properties = ( - templateId =>{ - fieldType=>"template", - defaultValue=>'UserListTmpl0000001', - namespace=>'UserList', - tab=>"display", - }, + my $class = shift; + my $session = shift; + my $definition = shift; + my %properties; + my $i18n = WebGUI::International->new($session, 'Asset_UserList'); + tie %properties, 'Tie::IxHash'; + %properties = ( + templateId =>{ + fieldType=>"template", + defaultValue=>'UserListTmpl0000001', + namespace=>'UserList', + tab=>"display", + }, - showGroupId=>{ - fieldType=>"group", - defaultValue=>"7", - label=>$i18n->get("Group to show label"), - hoverHelp=>$i18n->get('Group to show description'), - tab=>"display", - }, - hideGroupId=>{ - fieldType=>"group", - defaultValue=>"3", - label=>$i18n->get("Group to hide label"), - hoverHelp=>$i18n->get('Group to hide description'), - tab=>"display", - }, - usersPerPage=>{ - fieldType=>"integer", - defaultValue=>"25", - tab=>"display", - hoverHelp=>$i18n->get('Users per page description'), - label=>$i18n->get("Users per page label"), - }, - alphabet=>{ - fieldType=>"text", - defaultValue=>"", - tab=>"display", - label=>$i18n->get("alphabet label"), - hoverHelp=>$i18n->get('alphabet description'), - }, - showOnlyVisibleAsNamed=>{ - fieldType=>"yesNo", - defaultValue=>"0", - tab=>"display", - label=>$i18n->get("showOnlyVisibleAsNamed label"), - hoverHelp=>$i18n->get('showOnlyVisibleAsNamed description'), - }, - ); + showGroupId=>{ + fieldType=>"group", + defaultValue=>"7", + label=>$i18n->get("Group to show label"), + hoverHelp=>$i18n->get('Group to show description'), + tab=>"display", + }, + hideGroupId=>{ + fieldType=>"group", + defaultValue=>"3", + label=>$i18n->get("Group to hide label"), + hoverHelp=>$i18n->get('Group to hide description'), + tab=>"display", + }, + usersPerPage=>{ + fieldType=>"integer", + defaultValue=>"25", + tab=>"display", + hoverHelp=>$i18n->get('Users per page description'), + label=>$i18n->get("Users per page label"), + }, + alphabet=>{ + fieldType=>"text", + defaultValue=>"", + tab=>"display", + label=>$i18n->get("alphabet label"), + hoverHelp=>$i18n->get('alphabet description'), + }, + showOnlyVisibleAsNamed=>{ + fieldType=>"yesNo", + defaultValue=>"0", + tab=>"display", + label=>$i18n->get("showOnlyVisibleAsNamed label"), + hoverHelp=>$i18n->get('showOnlyVisibleAsNamed description'), + }, + ); push(@{$definition}, { assetName=>$i18n->get('assetName'), @@ -152,23 +152,6 @@ sub definition { #------------------------------------------------------------------- -=head2 getEditForm ( ) - -Returns a tab form containing the properties of this wobject. - -=cut - -sub getEditForm { - my $self = shift; - my $tabform = $self->SUPER::getEditForm(); - - my $i18n = WebGUI::International->new($self->session, "Asset_UserList"); - - return $tabform; -} - -#------------------------------------------------------------------- - =head2 isInGroup ( [ groupId ] ) Returns a boolean (0|1) value signifying that the user has the required privileges. Always returns true for Admins. @@ -187,8 +170,6 @@ sub isInGroup { my ($self, $gid, $uid, $secondRun) = @_; $gid = 3 unless (defined $gid); ### The following several checks are to increase performance. If this section were removed, everything would continue to work as normal. - #my $eh = $self->session->errorHandler; - #$eh->warn("Group Id is: $gid for ".$tgroup->name); return 1 if ($gid eq '7'); # everyone is in the everyone group return 1 if ($gid eq '1' && $uid eq '1'); # visitors are in the visitors group return 1 if ($gid eq '2' && $uid ne '1'); # if you're not a visitor, then you're a registered user @@ -223,15 +204,17 @@ See WebGUI::Asset::prepareView() for details. =cut sub prepareView { - my $self = shift; - $self->SUPER::prepareView(); - my $templateId = $self->get("templateId"); - if ($self->session->form->process("overrideTemplateId") ne "") { - $templateId = $self->session->form->process("overrideTemplateId"); - } - my $template = WebGUI::Asset::Template->new($self->session, $templateId); - $template->prepare; - $self->{_viewTemplate} = $template; + my $self = shift; + $self->SUPER::prepareView(); + my $templateId = $self->get("templateId"); + if ($self->session->form->process("overrideTemplateId") ne "") { + $templateId = $self->session->form->process("overrideTemplateId"); + } + my $template = WebGUI::Asset::Template->new($self->session, $templateId); + $template->prepare; + $self->{_viewTemplate} = $template; + + return undef; } #------------------------------------------------------------------- @@ -405,9 +388,9 @@ sub view { $p->appendTemplateVars(\%var); $var{searchFormHeader} = WebGUI::Form::formHeader($self->session,{action => $self->getUrl}); - $var{'searchFormTypeOr'} = WebGUI::Form::hidden($self->session, {name=>'searchType', value=>'or'}); - $var{'searchFormTypeAnd'} = WebGUI::Form::hidden($self->session, {name=>'searchType', value=>'and'}); - $var{'searchFormTypeSelect'} = WebGUI::Form::selectBox($self->session,{ + $var{searchFormTypeOr} = WebGUI::Form::hidden($self->session, {name=>'searchType', value=>'or'}); + $var{searchFormTypeAnd} = WebGUI::Form::hidden($self->session, {name=>'searchType', value=>'and'}); + $var{searchFormTypeSelect} = WebGUI::Form::selectBox($self->session,{ name=>'searchType', value=>'or', options=> { @@ -416,15 +399,15 @@ sub view { } }); - $var{'searchFormQuery_label'} = $i18n->get('query label'); - $var{'searchFormQuery_form'} = WebGUI::Form::text($self->session,{ + $var{searchFormQuery_label} = $i18n->get('query label'); + $var{searchFormQuery_form} = WebGUI::Form::text($self->session,{ name=>'search', value=>$self->session->form->process("search"), }); $var{searchFormSubmit} = WebGUI::Form::submit($self->session,{value => $i18n->get('submit search label')}); $var{searchFormFooter} = WebGUI::Form::formFooter($self->session); - $var{alphabetSearchLoop} = $self->getAlphabetSearchLoop("lastName",$self->get("alphabet")); + $var{alphabetSearch_loop} = $self->getAlphabetSearchLoop("lastName",$self->get("alphabet")); # $error->info("global tmpl_vars created, time :".(time() - $start_time)); my $out = $self->processTemplate(\%var,$self->get("templateId")); diff --git a/lib/WebGUI/Help/Asset_UserList.pm b/lib/WebGUI/Help/Asset_UserList.pm new file mode 100644 index 000000000..6a4bf956f --- /dev/null +++ b/lib/WebGUI/Help/Asset_UserList.pm @@ -0,0 +1,81 @@ +package WebGUI::Help::Asset_UserList; + +our $HELP = { + 'userlist template' => { + title => 'UserList Template', + body => 'UserList Template Help Body', + isa => [ + { namespace => "Asset_UserList", + tag => "userlist asset template variables" + }, + { namespace => "Asset_Template", + tag => "template variables" + }, + { namespace => "Asset", + tag => "asset template" + }, + { tag => 'pagination template variables', + namespace => 'WebGUI' + }, + ], + variables => [ + { 'name' => 'searchFormHeader' }, + { 'name' => 'searchFormSubmit' }, + { 'name' => 'searchFormFooter' }, + { 'name' => 'searchFormTypeOr' }, + { 'name' => 'searchFormTypeAnd' }, + { 'name' => 'searchFormTypeSelect' }, + { 'name' => 'searchFormQuery_form' }, + { 'name' => 'numberOfProfileFields' }, + { 'name' => 'profileField_loop', + 'variables' => [ + { 'name' => 'profileField_label' }, + ], + }, + { 'name' => 'alphabetSearch_loop', + 'variables' => [ + { 'name' => 'alphabetSearch_loop_label' }, + { 'name' => 'alphabetSearch_loop_hasResults' }, + { 'name' => 'alphabetSearch_loop_searchURL' }, + ], + }, + { 'name' => 'user_loop', + 'variables' => [ + { 'name' => 'user_name' }, + { 'name' => 'user_id' }, + { 'name' => 'user_profile_PROFILEFIELDNAME_value' }, + { 'name' => 'user_profile_emailNotPublic' }, + { 'name' => 'user_profile_loop', + 'variables' => [ + { 'name' => 'profile_emailNotPublic' }, + { 'name' => 'profile_value' }, + ], + }, + ], + }, + ], + related => [] + }, + + 'userlist asset template variables' => { + private => 1, + title => 'UserList Template', + body => 'UserList Template Help Body', + isa => [ + { namespace => "Asset_Wobject", + tag => "wobject template variables", + }, + ], + variables => [ + { 'name' => 'alphabet' }, + { 'name' => 'showGroupId' }, + { 'name' => 'hideGroupId' }, + { 'name' => 'usersPerPage' }, + { 'name' => 'templateId' }, + { 'name' => 'showOnlyVisibleAsNamed' }, + ], + related => [] + }, +}; + +1; diff --git a/lib/WebGUI/i18n/English/Asset_UserList.pm b/lib/WebGUI/i18n/English/Asset_UserList.pm index a9edfdc44..1c4483533 100644 --- a/lib/WebGUI/i18n/English/Asset_UserList.pm +++ b/lib/WebGUI/i18n/English/Asset_UserList.pm @@ -21,6 +21,16 @@ our $I18N = { lastUpdated => 1081514049 }, + 'templateId' => { + message => q|The ID of the template used to display the UserList Asset.|, + lastUpdated => 1168897708, + }, + + 'showGroupId' => { + message => q|Only users that are in this group will be shown.|, + lastUpdated => 1081514049 + }, + 'Group to show label' => { message => q|Group to show|, lastUpdated => 1081514049 @@ -32,6 +42,11 @@ our $I18N = { lastUpdated => 1081514049 }, + 'hideGroupId' => { + message => q|Users in this group will be hidden.|, + lastUpdated => 1081514049 + }, + 'Group to hide label' => { message => q|Group to hide|, lastUpdated => 1081514049 @@ -42,6 +57,11 @@ our $I18N = { lastUpdated => 1081514049 }, + 'usersPerPage' => { + message => q|The number of users per page|, + lastUpdated => 1081514049 + }, + 'Users per page label' => { message => q|Users per page|, lastUpdated => 1081514049 @@ -52,6 +72,12 @@ our $I18N = { lastUpdated => 1081514049 }, + 'showOnlyVisibleAsNamed' => { + message => q|Boolean. If true then only fields that are set to 'visible' in the user profile settings +will be available as named tmpl_vars|, + lastUpdated => 1081514049 + }, + 'showOnlyVisibleAsNamed label' => { message => q|Show only visible fields as named tmpl_vars|, lastUpdated => 1081514049 @@ -63,6 +89,12 @@ will be available as named tmpl_vars|, lastUpdated => 1081514049 }, + 'alphabet' => { + message => q|The alphabet that is used for the alphabet search. This is a string of comma +seperated values|, + lastUpdated => 1081514049 + }, + 'alphabet label' => { message => q|Alphabet|, lastUpdated => 1081514049 @@ -105,6 +137,119 @@ seperated values|, }, + 'searchFormHeader' => { + message => q|The header tag for the search form.|, + lastUpdated => 1081514049 + }, + + 'searchFormSubmit' => { + message => q|The submit form element for the search form|, + lastUpdated => 1081514049 + }, + + 'searchFormFooter' => { + message => q|The footer tag for the search form|, + lastUpdated => 1081514049 + }, + + 'searchFormTypeOr' => { + message => q|A hidden form element to set the search type to 'or'.|, + lastUpdated => 1081514049 + }, + + 'searchFormTypeAnd' => { + message => q|A hidden form element to set the search type to 'and'.|, + lastUpdated => 1081514049 + }, + + 'searchFormTypeSelect' => { + message => q|A select box to let the user select the search type.|, + lastUpdated => 1081514049 + }, + + 'searchFormQuery_form' => { + message => q|A text input for the search query.|, + lastUpdated => 1081514049 + }, + + 'numberOfProfileFields' => { + message => q|The number of profile fields.|, + lastUpdated => 1081514049 + }, + + 'alphabetSearch_loop' => { + message => q|A loop that contains elements to create an alphabetical search.|, + lastUpdated => 1081514049 + }, + + 'alphabetSearch_loop_label' => { + message => q|The label for this alphabet search query. Usually one letter of the alphabet.|, + lastUpdated => 1081514049 + }, + + 'alphabetSearch_loop_hasResults' => { + message => q|A conditional that is true if there are any results for this alphabet query.|, + lastUpdated => 1081514049 + }, + + 'alphabetSearch_loop_searchURL' => { + message => q|The url to do an alphabet search on this query.|, + lastUpdated => 1081514049 + }, + + 'user_loop' => { + message => q|A loop containing the users that are listed by the UserList.|, + lastUpdated => 1081514049 + }, + + 'user_name' => { + message => q|The username of the user.|, + lastUpdated => 1081514049 + }, + + 'user_id' => { + message => q|The userId of the user|, + lastUpdated => 1081514049 + }, + + 'user_profile_PROFILEFIELDNAME_value' => { + message => q|The value of the profile field with the name PROFILEFIELDNAME in the users user +profile. Example <tmpl_var user_profile_firstName_value>|, + lastUpdated => 1081514049 + }, + + 'user_profile_emailNotPublic' => { + message => q|A conditional that is true if the users email address is not public.|, + lastUpdated => 1081514049 + }, + + 'user_profile_loop' => { + message => q|A loop containing the users profile fields.|, + lastUpdated => 1081514049 + }, + + 'profile_emailNotPublic' => { + message => q|A conditional that is true if the users email address is not public. It will only be +true for the 'email' profile field.|, + lastUpdated => 1081514049 + }, + + 'profile_value' => { + message => q|The value of the profile field for this user.|, + lastUpdated => 1081514049 + }, + + 'profileField_loop' => { + message => q|A loop contining profile fields|, + lastUpdated => 1081514049 + }, + + 'profileField_label' => { + message => q|The label for a profile field|, + lastUpdated => 1081514049 + }, + + }; 1; From bc88cb31836c8938903aa6abd225582464b3a760 Mon Sep 17 00:00:00 2001 From: Yung Han Khoe Date: Mon, 19 May 2008 19:51:58 +0000 Subject: [PATCH 06/16] Adding basic UserList tests --- t/Asset/Wobject/UserList.t | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 t/Asset/Wobject/UserList.t diff --git a/t/Asset/Wobject/UserList.t b/t/Asset/Wobject/UserList.t new file mode 100644 index 000000000..f903d5a7e --- /dev/null +++ b/t/Asset/Wobject/UserList.t @@ -0,0 +1,52 @@ +#------------------------------------------------------------------- +# 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 +#------------------------------------------------------------------- + +use FindBin; +use strict; +use File::Spec; +use lib "$FindBin::Bin/../../lib"; + +##The goal of this test is to test the creation of UserList Wobjects. + +use WebGUI::Test; +use WebGUI::Session; +use Test::More tests => 5; # increment this value for each test you create +use WebGUI::Asset::Wobject::UserList; + +my $session = WebGUI::Test->session; + +# Do our work in the import node +my $node = WebGUI::Asset->getImportNode($session); + +my $versionTag = WebGUI::VersionTag->getWorking($session); +$versionTag->set({name=>"UserList Test"}); +my $userList = $node->addChild({className=>'WebGUI::Asset::Wobject::UserList'}); + +# Test for a sane object type +isa_ok($userList, 'WebGUI::Asset::Wobject::UserList'); + +# Test to see if we can set new values +my $newUserListSettings = { + usersPerPage => 124, + showGroupId => 7, + hideGroupId => 3, + alphabet => 'a,b,c', +}; +$userList->update($newUserListSettings); + +foreach my $newSetting (keys %{$newUserListSettings}) { + is ($userList->get($newSetting), $newUserListSettings->{$newSetting}, "updated $newSetting is ".$newUserListSettings->{$newSetting}); +} + +END { + # Clean up after thy self + $versionTag->rollback(); +} + From 160ae78f61682b9dd5e37882fae6ee776d0e29a2 Mon Sep 17 00:00:00 2001 From: Yung Han Khoe Date: Mon, 19 May 2008 20:59:14 +0000 Subject: [PATCH 07/16] Added UserList sort options --- lib/WebGUI/Asset/Wobject/UserList.pm | 44 +++++++++++++++++------ lib/WebGUI/i18n/English/Asset_UserList.pm | 31 ++++++++++++++++ 2 files changed, 64 insertions(+), 11 deletions(-) diff --git a/lib/WebGUI/Asset/Wobject/UserList.pm b/lib/WebGUI/Asset/Wobject/UserList.pm index e9716312e..60a1a62c4 100644 --- a/lib/WebGUI/Asset/Wobject/UserList.pm +++ b/lib/WebGUI/Asset/Wobject/UserList.pm @@ -93,6 +93,16 @@ sub definition { my $definition = shift; my %properties; my $i18n = WebGUI::International->new($session, 'Asset_UserList'); + + my %sortByOptions; + tie %sortByOptions, 'Tie::IxHash'; + my $fields = $session->db->read("SELECT field.fieldName, field.label FROM userProfileField as field " + ."left join userProfileCategory as cat USING(profileCategoryId) ORDER BY cat.sequenceNumber, field.sequenceNumber"); + while (my $field = $fields->hashRef){ + my $label = WebGUI::Operation::Shared::secureEval($session,$field->{label}); + $sortByOptions{$field->{fieldName}} = $label; + } + tie %properties, 'Tie::IxHash'; %properties = ( templateId =>{ @@ -137,6 +147,23 @@ sub definition { label=>$i18n->get("showOnlyVisibleAsNamed label"), hoverHelp=>$i18n->get('showOnlyVisibleAsNamed description'), }, + sortOrder =>{ + fieldType=>"selectBox", + defaultValue=>'asc', + tab=>'display', + options=>{ asc => $i18n->get('ascending'), + desc => $i18n->get('descending') }, + label=>$i18n->get('sort order'), + hoverHelp=>$i18n->get('sort order description'), + }, + sortBy =>{ + fieldType=>"selectBox", + defaultValue=>'lastName', + tab=>'display', + options=>\%sortByOptions, + label=>$i18n->get('sort by'), + hoverHelp=>$i18n->get('sort by description'), + }, ); push(@{$definition}, { @@ -294,18 +321,13 @@ sub view { # $error->info("created constraint, time :".(time() - $start_time)); - my $formOrderBy = $self->session->form->process('orderBy'); - my $orderBy = 'userName'; - my $orderType = $self->session->form->process('orderType') || 'asc'; + my $orderBy = $self->session->form->process('orderBy') || $self->get('sortBy') || 'users.username'; + my $orderType = $self->session->form->process('orderType') || $self->get('sortOrder') || 'asc'; - my @orderByUserProperties = ('dateCreated', 'lastUpdated', 'karma', 'userId'); - if ($formOrderBy){ - if(isIn($formOrderBy,@profileFieldNames)){ - $orderBy = $formOrderBy; - }elsif(isIn($formOrderBy,@orderByUserProperties)){ - $orderBy = 'users.'.$formOrderBy; - } - } + my @orderByUserProperties = ('dateCreated', 'lastUpdated', 'karma', 'userId'); + if(isIn($orderBy,@orderByUserProperties)){ + $orderBy = 'users.'.$orderBy; + } $sql .= " order by ".$orderBy." ".$orderType; ($defaultPublicProfile) = $self->session->db->quickArray("SELECT dataDefault FROM userProfileField WHERE fieldName='publicProfile'"); diff --git a/lib/WebGUI/i18n/English/Asset_UserList.pm b/lib/WebGUI/i18n/English/Asset_UserList.pm index 1c4483533..a795676e1 100644 --- a/lib/WebGUI/i18n/English/Asset_UserList.pm +++ b/lib/WebGUI/i18n/English/Asset_UserList.pm @@ -249,6 +249,37 @@ true for the 'email' profile field.|, lastUpdated => 1081514049 }, + 'sort by' => { + message => q|Sort By|, + lastUpdated => 1109698614, + }, + + 'sort order' => { + message => q|Sort Order|, + lastUpdated => 1109698614, + }, + + 'sort by description' => { + message => q|By default, all users are displayed in a sorted order. Use this +field to choose by what field they are sorted.|, + lastUpdated => 1119070429, + }, + + 'sort order description' => { + message => q|Sort in ascending or descending order.|, + lastUpdated => 1119070429, + }, + + 'ascending' => { + message => q|Ascending|, + lastUpdated => 1113673328, + }, + + 'descending' => { + message => q|Descending|, + lastUpdated => 1113673330, + }, + }; From a49c94cde83b6279cd2d9b780fb0f7c91fc637d7 Mon Sep 17 00:00:00 2001 From: Yung Han Khoe Date: Tue, 20 May 2008 11:49:34 +0000 Subject: [PATCH 08/16] More UserList sort options --- lib/WebGUI/Asset/Wobject/UserList.pm | 22 +++++++++++++++++---- lib/WebGUI/Help/Asset_UserList.pm | 3 +++ lib/WebGUI/i18n/English/Asset_UserList.pm | 24 +++++++++++++++++++++-- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/lib/WebGUI/Asset/Wobject/UserList.pm b/lib/WebGUI/Asset/Wobject/UserList.pm index 60a1a62c4..2af8291e0 100644 --- a/lib/WebGUI/Asset/Wobject/UserList.pm +++ b/lib/WebGUI/Asset/Wobject/UserList.pm @@ -253,6 +253,7 @@ sub prepareView { sub view { my $self = shift; + my $form = $self->session->form; my $i18n = WebGUI::International->new($self->session, "Asset_UserList"); my (%var, @users, @profileField_loop, @profileFields,@profileFieldNames); my ($defaultPublicProfile, $defaultPublicEmail, $user, $sth, $sql, $profileField); @@ -276,6 +277,14 @@ sub view { push(@profileFieldNames, $profileField->{fieldName}); unless($self->get("showOnlyVisibleAsNamed") && $profileField->{visible} != 1){ $var{'profileField_'.$profileField->{fieldName}.'_label'} = $label; + my $sortByURL = '?orderBy='.$profileField->{fieldName}; + if ($form->process('orderType') eq 'asc' && $form->process('orderBy') eq $profileField->{fieldName}){ + $sortByURL .= ';orderType=desc'; + } + else{ + $sortByURL .= ';orderType=asc'; + } + $var{'profileField_'.$profileField->{fieldName}.'_sortByURL'} = $sortByURL; } } @@ -292,9 +301,11 @@ sub view { my $constraint; if ($self->session->form->process('search')){ $constraint = "(".join(' or ', map {'userProfileData.'.$_->{fieldName}.' like "%'.$self->session->form->process('search').'%"'} @profileFields).")"; - }elsif ($self->session->form->process('searchExact')){ + } + elsif ($self->session->form->process('searchExact')){ $constraint = "(".join(' or ', map {'userProfileData.'.$_->{fieldName}.' like "'.$self->session->form->process('searchExact').'"'} @profileFields).")"; - }else{ + } + else{ my @profileSearchFields = (); my @profileSearchExactFields = (); foreach my $profileField (@profileFields){ @@ -371,7 +382,8 @@ sub view { push (@profileFieldValues, { "profile_emailNotPublic"=>1, }); - }else{ + } + else{ push (@profileFieldValues, { "profile_value"=>$user->{$profileField->{fieldName}}, }); @@ -389,7 +401,8 @@ sub view { $userProperties{"user_name"} = $user->{userName}; $userProperties{"user_profile_loop"} = \@profileFieldValues; push(@users,\%userProperties); - }else{ + } + else{ push(@users, { "user_id"=>$user->{userId}, "user_name"=>$user->{userName}, @@ -400,6 +413,7 @@ sub view { foreach my $profileField (@profileFields){ push (@profileField_loop, { "profileField_label"=>WebGUI::Operation::Shared::secureEval($self->session,$profileField->{label}), + "profileField_sortByURL"=>'?orderBy='.$profileField->{fieldName}, }); } $var{numberOfProfileFields} = scalar(@profileFields); diff --git a/lib/WebGUI/Help/Asset_UserList.pm b/lib/WebGUI/Help/Asset_UserList.pm index 6a4bf956f..454d23113 100644 --- a/lib/WebGUI/Help/Asset_UserList.pm +++ b/lib/WebGUI/Help/Asset_UserList.pm @@ -27,9 +27,12 @@ our $HELP = { { 'name' => 'searchFormTypeSelect' }, { 'name' => 'searchFormQuery_form' }, { 'name' => 'numberOfProfileFields' }, + { 'name' => 'profileField_PROFILEFIELDNAME_label' }, + { 'name' => 'profileField_PROFILEFIELDNAME_sortByURL' }, { 'name' => 'profileField_loop', 'variables' => [ { 'name' => 'profileField_label' }, + { 'name' => 'profileField_sortByURL' }, ], }, { 'name' => 'alphabetSearch_loop', diff --git a/lib/WebGUI/i18n/English/Asset_UserList.pm b/lib/WebGUI/i18n/English/Asset_UserList.pm index a795676e1..b12403269 100644 --- a/lib/WebGUI/i18n/English/Asset_UserList.pm +++ b/lib/WebGUI/i18n/English/Asset_UserList.pm @@ -240,12 +240,32 @@ true for the 'email' profile field.|, }, 'profileField_loop' => { - message => q|A loop contining profile fields|, + message => q|A loop containing profile fields|, lastUpdated => 1081514049 }, 'profileField_label' => { - message => q|The label for a profile field|, + message => q|The label for this profile field|, + lastUpdated => 1081514049 + }, + + + 'profileField_sortByURL' => { + message => q|The URL to sort the UserList by this profile field. The default sort order +is ascending. After clicking the sort by link for a profile field the sort order will be reversed.|, + lastUpdated => 1081514049 + }, + + 'profileField_PROFILEFIELDNAME_label' => { + message => q|The label for the profile field with fieldName PROFILEFIELDNAME. Example <tmpl_var +profileField_lastName_label>. This tmpl_var exists outside of the profileField_loop.|, + lastUpdated => 1081514049 + }, + + 'profileField_PROFILEFIELDNAME_sortByURL' => { + message => q|The URL to sort the UserList by PROFILEFIELDNAME. Example <tmpl_var +profileField_lastName_sortByURL>. This tmpl_var exists outside of the profileField_loop. The default sort order +is ascending. After clicking the sort by link for a profile field the sort order will be reversed.|, lastUpdated => 1081514049 }, From e6d3126cc518f55ce59bfe0e017bfc9de7cf62a8 Mon Sep 17 00:00:00 2001 From: Yung Han Khoe Date: Wed, 21 May 2008 10:51:40 +0000 Subject: [PATCH 09/16] More UserList sort and search changes --- lib/WebGUI/Asset/Wobject/UserList.pm | 99 +++++++++++------------ lib/WebGUI/i18n/English/Asset_UserList.pm | 4 + 2 files changed, 50 insertions(+), 53 deletions(-) diff --git a/lib/WebGUI/Asset/Wobject/UserList.pm b/lib/WebGUI/Asset/Wobject/UserList.pm index 2af8291e0..618a7a1b9 100644 --- a/lib/WebGUI/Asset/Wobject/UserList.pm +++ b/lib/WebGUI/Asset/Wobject/UserList.pm @@ -18,8 +18,6 @@ our @ISA = qw(WebGUI::Asset::Wobject); Copyright 2004-2008 United Knowledge -See the doc/license-UserList.txt file for licensing information. - http://www.unitedknowledge.nl developmentinfo@unitedknowledge.nl @@ -36,12 +34,7 @@ The wobject also checks the publicProfile and publicEmail setting for each user. =head1 SYNOPSIS -my $wobject = WebGUI::Wobject::UserList->new(\%properties); - -$text = $wobject->name; - -$html = $wobject->www_edit; -$html = $wobject->www_view; +use WebGUI::Asset::Wobject::UserList; =cut @@ -254,12 +247,21 @@ sub view { my $self = shift; my $form = $self->session->form; + my $url = $self->session->url; my $i18n = WebGUI::International->new($self->session, "Asset_UserList"); - my (%var, @users, @profileField_loop, @profileFields,@profileFieldNames); + my (%var, @users, @profileField_loop, @profileFields); my ($defaultPublicProfile, $defaultPublicEmail, $user, $sth, $sql, $profileField); my $error = $self->session->errorHandler; my $start_time = time(); + my $currentUrlWithoutSort = $self->getUrl(); + foreach ($form->param) { + unless (WebGUI::Utility::isIn($_,qw(orderBy orderType op func)) || $_ =~ /identifier/i || $_ =~ /password/i) { + $currentUrlWithoutSort = $url->append($currentUrlWithoutSort, $url->escape($_) + .'='.$url->escape($form->process($_))); + } + } + # $error->info("time :".(time() - $start_time)); $sth = $self->session->db->read("SELECT field.fieldName, field.label, field.sequenceNumber, field.visible " @@ -268,22 +270,25 @@ sub view { ."ORDER BY category.sequenceNumber, field.sequenceNumber"); while ($profileField = $sth->hashRef){ my $label = WebGUI::Operation::Shared::secureEval($self->session,$profileField->{label}); + my $sortByURL = $url->append($currentUrlWithoutSort,'orderBy='.$url->escape($profileField->{fieldName})); + if ($form->process('orderType') eq 'asc' && $form->process('orderBy') eq $profileField->{fieldName}){ + $sortByURL = $url->append($sortByURL,'orderType=desc'); + } + else{ + $sortByURL = $url->append($sortByURL,'orderType=asc'); + } push(@profileFields, { "fieldName"=>$profileField->{fieldName}, "label"=>$label, "sequenceNumber"=>$profileField->{sequenceNumber}, "visible"=>$profileField->{visible}, }); - push(@profileFieldNames, $profileField->{fieldName}); + push (@profileField_loop, { + "profileField_label"=>WebGUI::Operation::Shared::secureEval($self->session,$profileField->{label}), + "profileField_sortByURL"=>$sortByURL, + }); unless($self->get("showOnlyVisibleAsNamed") && $profileField->{visible} != 1){ $var{'profileField_'.$profileField->{fieldName}.'_label'} = $label; - my $sortByURL = '?orderBy='.$profileField->{fieldName}; - if ($form->process('orderType') eq 'asc' && $form->process('orderBy') eq $profileField->{fieldName}){ - $sortByURL .= ';orderType=desc'; - } - else{ - $sortByURL .= ';orderType=asc'; - } $var{'profileField_'.$profileField->{fieldName}.'_sortByURL'} = $sortByURL; } } @@ -299,41 +304,39 @@ sub view { # $error->info("creating constraint, time :".(time() - $start_time)); my $constraint; - if ($self->session->form->process('search')){ - $constraint = "(".join(' or ', map {'userProfileData.'.$_->{fieldName}.' like "%'.$self->session->form->process('search').'%"'} @profileFields).")"; + if ($form->process('search')){ + # Normal search with one query in one or more fields + $constraint = "(".join(' or ', map {'userProfileData.'.$_->{fieldName}.' like "%'.$form->process('search').'%"'} @profileFields).")"; } - elsif ($self->session->form->process('searchExact')){ - $constraint = "(".join(' or ', map {'userProfileData.'.$_->{fieldName}.' like "'.$self->session->form->process('searchExact').'"'} @profileFields).")"; + elsif ($form->process('searchExact')){ + # Exact search with one query in one or more fields + $constraint = "(".join(' or ', map {'userProfileData.'.$_->{fieldName}.' like "'.$form->process('searchExact').'"'} @profileFields).")"; } else{ + # Mixed normal and exact search with different queries for each field. my @profileSearchFields = (); - my @profileSearchExactFields = (); foreach my $profileField (@profileFields){ - if ($self->session->form->process('search_'.$profileField->{fieldName})){ - push(@profileSearchFields,$profileField); + # Exact search has precedence over normal search + if ($form->process('searchExact_'.$profileField->{fieldName})){ + push(@profileSearchFields,'userProfileData.'.$profileField->{fieldName} + .' like "'.$form->process('searchExact_'.$profileField->{fieldName}).'"'); } - if ($self->session->form->process('searchExact_'.$profileField->{fieldName})){ - push(@profileSearchExactFields,$profileField); + elsif ($form->process('search_'.$profileField->{fieldName})){ + push(@profileSearchFields,'userProfileData.'.$profileField->{fieldName} + .' like "%'.$form->process('search_'.$profileField->{fieldName}).'%"'); } } - my $searchType = $self->session->form->process('searchType') || 'or'; - if (scalar(@profileSearchFields) > 0){ - $constraint = "(".join(' '.$searchType.' ', map {'userProfileData.'.$_->{fieldName}.' like "%' - .$self->session->form->process('search_'.$_->{fieldName}).'%"'} @profileSearchFields).")"; - foreach my $profileSearchField (@profileSearchFields){ - } - } - if (scalar(@profileSearchExactFields) > 0){ - $constraint = "(".join(' '.$searchType.' ', map {'userProfileData.'.$_->{fieldName}.' like"' - .$self->session->form->process('searchExact_'.$_->{fieldName}).'"'} @profileSearchExactFields).")"; + my $searchType = $form->process('searchType') || 'or'; + if (scalar(@profileSearchFields) > 0){ + $constraint = '('.join(' '.$searchType.' ',@profileSearchFields).')'; } } $sql .= " and ".$constraint if ($constraint); # $error->info("created constraint, time :".(time() - $start_time)); - my $orderBy = $self->session->form->process('orderBy') || $self->get('sortBy') || 'users.username'; - my $orderType = $self->session->form->process('orderType') || $self->get('sortOrder') || 'asc'; + my $orderBy = $form->process('orderBy') || $self->get('sortBy') || 'users.username'; + my $orderType = $form->process('orderType') || $self->get('sortOrder') || 'asc'; my @orderByUserProperties = ('dateCreated', 'lastUpdated', 'karma', 'userId'); if(isIn($orderBy,@orderByUserProperties)){ @@ -344,12 +347,12 @@ sub view { ($defaultPublicProfile) = $self->session->db->quickArray("SELECT dataDefault FROM userProfileField WHERE fieldName='publicProfile'"); ($defaultPublicEmail) = $self->session->db->quickArray("SELECT dataDefault FROM userProfileField WHERE fieldName='publicEmail'"); - my $paginatePage = $self->session->form->param('pn') || 1; + my $paginatePage = $form->param('pn') || 1; my $currentUrl = $self->getUrl(); - foreach ($self->session->form->param) { + foreach ($form->param) { unless ($_ eq "pn" || $_ eq "op" || $_ eq "func" || $_ =~ /identifier/i || $_ =~ /password/i) { - $currentUrl = $self->session->url->append($currentUrl, $self->session->url->escape($_) - .'='.$self->session->url->escape($self->session->form->process($_))); + $currentUrl = $url->append($currentUrl, $url->escape($_) + .'='.$url->escape($form->process($_))); } } @@ -410,15 +413,7 @@ sub view { } } # $error->info("created tmpl vars for users, time :".(time() - $start_time)); - foreach my $profileField (@profileFields){ - push (@profileField_loop, { - "profileField_label"=>WebGUI::Operation::Shared::secureEval($self->session,$profileField->{label}), - "profileField_sortByURL"=>'?orderBy='.$profileField->{fieldName}, - }); - } $var{numberOfProfileFields} = scalar(@profileFields); - $var{profileNotPublic_message} = $i18n->get('Profile not public message'); - $var{emailNotPublic_message} = $i18n->get('Email not public message'); $var{profileField_loop} = \@profileField_loop; $var{user_loop} = \@users; $p->appendTemplateVars(\%var); @@ -435,10 +430,9 @@ sub view { } }); - $var{searchFormQuery_label} = $i18n->get('query label'); $var{searchFormQuery_form} = WebGUI::Form::text($self->session,{ name=>'search', - value=>$self->session->form->process("search"), + value=>$form->process("search"), }); $var{searchFormSubmit} = WebGUI::Form::submit($self->session,{value => $i18n->get('submit search label')}); @@ -447,7 +441,6 @@ sub view { # $error->info("global tmpl_vars created, time :".(time() - $start_time)); my $out = $self->processTemplate(\%var,$self->get("templateId")); - $out = $self->processStyle($out) if ($self->session->form->process("func") eq "list"); # $error->info("done, going to return output, time :".(time() - $start_time)); return $out; } diff --git a/lib/WebGUI/i18n/English/Asset_UserList.pm b/lib/WebGUI/i18n/English/Asset_UserList.pm index b12403269..983de5f70 100644 --- a/lib/WebGUI/i18n/English/Asset_UserList.pm +++ b/lib/WebGUI/i18n/English/Asset_UserList.pm @@ -110,6 +110,10 @@ seperated values|, message => q|Profile not public|, lastUpdated => 1081514049 }, + 'No users message' => { + message => q|No users found|, + lastUpdated => 1081514049 + }, 'Email not public message' => { message => q|Email not public|, From 012e1b35395f1ff35afd1691d11e8dc370295ea7 Mon Sep 17 00:00:00 2001 From: Yung Han Khoe Date: Wed, 21 May 2008 17:38:42 +0000 Subject: [PATCH 10/16] More UserList search options --- lib/WebGUI/Asset/Wobject/UserList.pm | 128 +++++++++++++++------- lib/WebGUI/i18n/English/Asset_UserList.pm | 5 + 2 files changed, 93 insertions(+), 40 deletions(-) diff --git a/lib/WebGUI/Asset/Wobject/UserList.pm b/lib/WebGUI/Asset/Wobject/UserList.pm index 618a7a1b9..e096c0d45 100644 --- a/lib/WebGUI/Asset/Wobject/UserList.pm +++ b/lib/WebGUI/Asset/Wobject/UserList.pm @@ -251,8 +251,8 @@ sub view { my $i18n = WebGUI::International->new($self->session, "Asset_UserList"); my (%var, @users, @profileField_loop, @profileFields); my ($defaultPublicProfile, $defaultPublicEmail, $user, $sth, $sql, $profileField); - my $error = $self->session->errorHandler; - my $start_time = time(); +# my $error = $self->session->errorHandler; +# my $start_time = time(); my $currentUrlWithoutSort = $self->getUrl(); foreach ($form->param) { @@ -270,27 +270,46 @@ sub view { ."ORDER BY category.sequenceNumber, field.sequenceNumber"); while ($profileField = $sth->hashRef){ my $label = WebGUI::Operation::Shared::secureEval($self->session,$profileField->{label}); - my $sortByURL = $url->append($currentUrlWithoutSort,'orderBy='.$url->escape($profileField->{fieldName})); - if ($form->process('orderType') eq 'asc' && $form->process('orderBy') eq $profileField->{fieldName}){ + my $fieldName = $profileField->{fieldName}; + my $sortByURL = $url->append($currentUrlWithoutSort,'orderBy='.$url->escape($fieldName)); + if ($form->process('orderType') eq 'asc' && $form->process('orderBy') eq $fieldName){ $sortByURL = $url->append($sortByURL,'orderType=desc'); } else{ $sortByURL = $url->append($sortByURL,'orderType=asc'); } push(@profileFields, { - "fieldName"=>$profileField->{fieldName}, + "fieldName"=>$fieldName, "label"=>$label, "sequenceNumber"=>$profileField->{sequenceNumber}, "visible"=>$profileField->{visible}, }); push (@profileField_loop, { - "profileField_label"=>WebGUI::Operation::Shared::secureEval($self->session,$profileField->{label}), + "profileField_label"=>$label, "profileField_sortByURL"=>$sortByURL, }); unless($self->get("showOnlyVisibleAsNamed") && $profileField->{visible} != 1){ - $var{'profileField_'.$profileField->{fieldName}.'_label'} = $label; - $var{'profileField_'.$profileField->{fieldName}.'_sortByURL'} = $sortByURL; + $var{'profileField_'.$fieldName.'_label'} = $label; + $var{'profileField_'.$fieldName.'_sortByURL'} = $sortByURL; } + # create field specific templ_vars for search + $var{'search_'.$fieldName.'_text'} = WebGUI::Form::Text($self->session, { + -name => 'search_'.$fieldName, + -value => $form->process('search_'.$fieldName), + }); + $var{'searchExact_'.$fieldName.'_text'} = WebGUI::Form::Text($self->session, { + -name => 'searchExact_'.$fieldName, + -value => $form->process('searchExact_'.$fieldName), + }); + $var{'includeInSearch_'.$fieldName.'_hidden'} = WebGUI::Form::Hidden($self->session, { + -name => 'includeInSearch_'.$fieldName, + -value => '1', + }); + $var{'includeInSearch_'.$fieldName.'_checkBox'} = WebGUI::Form::Checkbox($self->session, { + -name => 'includeInSearch_'.$fieldName, + -value => '1', + -checked=> $form->process('includeInSearch_'.$fieldName), + }); } # $error->info("selected profile fields, time :".(time() - $start_time)); @@ -304,17 +323,44 @@ sub view { # $error->info("creating constraint, time :".(time() - $start_time)); my $constraint; + my @profileSearchFields = (); + my $searchType = $form->process('searchType') || 'or'; if ($form->process('search')){ - # Normal search with one query in one or more fields - $constraint = "(".join(' or ', map {'userProfileData.'.$_->{fieldName}.' like "%'.$form->process('search').'%"'} @profileFields).")"; + # Normal search with one query takes precedence over other search options + if($form->process('limitSearch')){ + # Normal search with one query in a limited number of fields + foreach my $profileField (@profileFields){ + if ($form->process('includeInSearch_'.$profileField->{fieldName})){ + push(@profileSearchFields,'userProfileData.'.$profileField->{fieldName} + .' like "%'.$form->process('search').'%"'); + } + } + } + else{ + # Normal search with one query in all fields + $constraint = "(".join(' or ', map {'userProfileData.'.$_->{fieldName} + .' like "%'.$form->process('search').'%"'} @profileFields).")"; + } } elsif ($form->process('searchExact')){ - # Exact search with one query in one or more fields - $constraint = "(".join(' or ', map {'userProfileData.'.$_->{fieldName}.' like "'.$form->process('searchExact').'"'} @profileFields).")"; + # Exact search with one query + if($form->process('limitSearch')){ + # Exact search with one query in a limited number of fields + foreach my $profileField (@profileFields){ + if ($form->process('includeInSearch_'.$profileField->{fieldName})){ + push(@profileSearchFields,'userProfileData.'.$profileField->{fieldName} + .' like "'.$form->process('search').'"'); + } + } + } + else{ + # Exact search with one query in all fields + $constraint = "(".join(' or ', map {'userProfileData.'.$_->{fieldName} + .' like "'.$form->process('searchExact').'"'} @profileFields).")"; + } } else{ # Mixed normal and exact search with different queries for each field. - my @profileSearchFields = (); foreach my $profileField (@profileFields){ # Exact search has precedence over normal search if ($form->process('searchExact_'.$profileField->{fieldName})){ @@ -326,11 +372,10 @@ sub view { .' like "%'.$form->process('search_'.$profileField->{fieldName}).'%"'); } } - my $searchType = $form->process('searchType') || 'or'; - if (scalar(@profileSearchFields) > 0){ - $constraint = '('.join(' '.$searchType.' ',@profileSearchFields).')'; - } } + if (scalar(@profileSearchFields) > 0){ + $constraint = '('.join(' '.$searchType.' ',@profileSearchFields).')'; + } $sql .= " and ".$constraint if ($constraint); # $error->info("created constraint, time :".(time() - $start_time)); @@ -413,31 +458,34 @@ sub view { } } # $error->info("created tmpl vars for users, time :".(time() - $start_time)); - $var{numberOfProfileFields} = scalar(@profileFields); - $var{profileField_loop} = \@profileField_loop; - $var{user_loop} = \@users; - $p->appendTemplateVars(\%var); - - $var{searchFormHeader} = WebGUI::Form::formHeader($self->session,{action => $self->getUrl}); - $var{searchFormTypeOr} = WebGUI::Form::hidden($self->session, {name=>'searchType', value=>'or'}); - $var{searchFormTypeAnd} = WebGUI::Form::hidden($self->session, {name=>'searchType', value=>'and'}); - $var{searchFormTypeSelect} = WebGUI::Form::selectBox($self->session,{ - name=>'searchType', - value=>'or', - options=> { - 'or' => $i18n->get('or label'), - 'and' => $i18n->get('and label'), - } - }); + $p->appendTemplateVars(\%var); - $var{searchFormQuery_form} = WebGUI::Form::text($self->session,{ - name=>'search', - value=>$form->process("search"), - }); + $var{numberOfProfileFields} = scalar(@profileFields); + + $var{profileField_loop} = \@profileField_loop; + $var{user_loop} = \@users; + $var{alphabetSearch_loop} = $self->getAlphabetSearchLoop("lastName",$self->get("alphabet")); + + $var{searchFormHeader} = WebGUI::Form::formHeader($self->session,{action => $self->getUrl}); + $var{searchFormSubmit} = WebGUI::Form::submit($self->session,{value => $i18n->get('submit search label')}); + $var{searchFormFooter} = WebGUI::Form::formFooter($self->session); + + $var{limitSearch} = WebGUI::Form::hidden($self->session, {name=>'limitSearch', value=>'1'}); + $var{searchFormTypeOr} = WebGUI::Form::hidden($self->session, {name=>'searchType', value=>'or'}); + $var{searchFormTypeAnd} = WebGUI::Form::hidden($self->session, {name=>'searchType', value=>'and'}); + $var{searchFormTypeSelect} = WebGUI::Form::selectBox($self->session,{ + name => 'searchType', + value => $form->process('searchType') || 'or', + options => { + 'or' => $i18n->get('or label'), + 'and' => $i18n->get('and label'), + } + }); + $var{searchFormQuery_form} = WebGUI::Form::text($self->session,{ + name => 'search', + value => $form->process("search"), + }); - $var{searchFormSubmit} = WebGUI::Form::submit($self->session,{value => $i18n->get('submit search label')}); - $var{searchFormFooter} = WebGUI::Form::formFooter($self->session); - $var{alphabetSearch_loop} = $self->getAlphabetSearchLoop("lastName",$self->get("alphabet")); # $error->info("global tmpl_vars created, time :".(time() - $start_time)); my $out = $self->processTemplate(\%var,$self->get("templateId")); diff --git a/lib/WebGUI/i18n/English/Asset_UserList.pm b/lib/WebGUI/i18n/English/Asset_UserList.pm index 983de5f70..4249e62a5 100644 --- a/lib/WebGUI/i18n/English/Asset_UserList.pm +++ b/lib/WebGUI/i18n/English/Asset_UserList.pm @@ -171,6 +171,11 @@ seperated values|, lastUpdated => 1081514049 }, + 'searchFormTypeSelect label' => { + message => q|Select search type|, + lastUpdated => 1081514049 + }, + 'searchFormQuery_form' => { message => q|A text input for the search query.|, lastUpdated => 1081514049 From e696d3287eb94dc1e3db7e9eda0841ffabddb577 Mon Sep 17 00:00:00 2001 From: Yung Han Khoe Date: Fri, 23 May 2008 15:50:49 +0000 Subject: [PATCH 11/16] Some more UserList search options and added (un)install methods. --- lib/WebGUI/Asset/Wobject/UserList.pm | 292 ++++++++++++++++++---- lib/WebGUI/i18n/English/Asset_UserList.pm | 15 ++ 2 files changed, 258 insertions(+), 49 deletions(-) diff --git a/lib/WebGUI/Asset/Wobject/UserList.pm b/lib/WebGUI/Asset/Wobject/UserList.pm index e096c0d45..3165260f5 100644 --- a/lib/WebGUI/Asset/Wobject/UserList.pm +++ b/lib/WebGUI/Asset/Wobject/UserList.pm @@ -11,8 +11,9 @@ use WebGUI::Utility; use WebGUI::Asset::Wobject; use WebGUI::Operation::Shared; use WebGUI::International; - -our @ISA = qw(WebGUI::Asset::Wobject); +use WebGUI::Pluggable; +use WebGUI::Form::Image; +use base 'WebGUI::Asset::Wobject'; =head1 LEGAL @@ -48,17 +49,16 @@ Returns an array ref that contains tmpl_vars for the Alphabet Search. sub getAlphabetSearchLoop { my $self = shift; - my $fieldName = shift; + my $fieldName = shift || 'lastName'; my $alphabet = shift; my (@alphabet, @alphabetLoop); $alphabet ||= "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z"; @alphabet = split(/,/,$alphabet); foreach my $letter (@alphabet){ my $htmlEncodedLetter = encode_entities($letter); - #print "adding letter ".$letter.",htmlEncodedLetter: $htmlEncodedLetter
"; my $searchURL = "?searchExact_".$fieldName."=".$letter."%25"; my $hasResults = $self->session->db->quickScalar("select if (" - ."(select count(*) from userProfileData where lastName like '".$letter."%')<>0, 1, 0)"); + ."(select count(*) from userProfileData where ".$fieldName." like '".$letter."%')<>0, 1, 0)"); push @alphabetLoop, { alphabetSearch_loop_label => $htmlEncodedLetter || $letter, alphabetSearch_loop_hasResults => $hasResults, @@ -87,13 +87,13 @@ sub definition { my %properties; my $i18n = WebGUI::International->new($session, 'Asset_UserList'); - my %sortByOptions; - tie %sortByOptions, 'Tie::IxHash'; + my %profileFields; + tie %profileFields, 'Tie::IxHash'; my $fields = $session->db->read("SELECT field.fieldName, field.label FROM userProfileField as field " ."left join userProfileCategory as cat USING(profileCategoryId) ORDER BY cat.sequenceNumber, field.sequenceNumber"); while (my $field = $fields->hashRef){ my $label = WebGUI::Operation::Shared::secureEval($session,$field->{label}); - $sortByOptions{$field->{fieldName}} = $label; + $profileFields{$field->{fieldName}} = $label; } tie %properties, 'Tie::IxHash'; @@ -128,11 +128,19 @@ sub definition { }, alphabet=>{ fieldType=>"text", - defaultValue=>"", + defaultValue=>"a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z", tab=>"display", label=>$i18n->get("alphabet label"), hoverHelp=>$i18n->get('alphabet description'), }, + alphabetSearchField=>{ + fieldType=>"selectBox", + defaultValue=>"lastName", + tab=>"display", + options=>\%profileFields, + label=>$i18n->get("alphabetSearchField label"), + hoverHelp=>$i18n->get('alphabetSearchField description'), + }, showOnlyVisibleAsNamed=>{ fieldType=>"yesNo", defaultValue=>"0", @@ -153,7 +161,7 @@ sub definition { fieldType=>"selectBox", defaultValue=>'lastName', tab=>'display', - options=>\%sortByOptions, + options=>\%profileFields, label=>$i18n->get('sort by'), hoverHelp=>$i18n->get('sort by description'), }, @@ -251,38 +259,36 @@ sub view { my $i18n = WebGUI::International->new($self->session, "Asset_UserList"); my (%var, @users, @profileField_loop, @profileFields); my ($defaultPublicProfile, $defaultPublicEmail, $user, $sth, $sql, $profileField); -# my $error = $self->session->errorHandler; -# my $start_time = time(); my $currentUrlWithoutSort = $self->getUrl(); foreach ($form->param) { - unless (WebGUI::Utility::isIn($_,qw(orderBy orderType op func)) || $_ =~ /identifier/i || $_ =~ /password/i) { + unless (WebGUI::Utility::isIn($_,qw(sortBy sortOrder op func)) || $_ =~ /identifier/i || $_ =~ /password/i) { $currentUrlWithoutSort = $url->append($currentUrlWithoutSort, $url->escape($_) .'='.$url->escape($form->process($_))); } } -# $error->info("time :".(time() - $start_time)); - - $sth = $self->session->db->read("SELECT field.fieldName, field.label, field.sequenceNumber, field.visible " + $sth = $self->session->db->read( + "SELECT field.fieldName, field.label, field.sequenceNumber, field.visible, field.fieldType " ."FROM userProfileField as field " ."left join userProfileCategory as category USING(profileCategoryId) " ."ORDER BY category.sequenceNumber, field.sequenceNumber"); while ($profileField = $sth->hashRef){ my $label = WebGUI::Operation::Shared::secureEval($self->session,$profileField->{label}); my $fieldName = $profileField->{fieldName}; - my $sortByURL = $url->append($currentUrlWithoutSort,'orderBy='.$url->escape($fieldName)); - if ($form->process('orderType') eq 'asc' && $form->process('orderBy') eq $fieldName){ - $sortByURL = $url->append($sortByURL,'orderType=desc'); + my $sortByURL = $url->append($currentUrlWithoutSort,'sortBy='.$url->escape($fieldName)); + if ($form->process('sortOrder') eq 'asc' && $form->process('sortBy') eq $fieldName){ + $sortByURL = $url->append($sortByURL,'sortOrder=desc'); } else{ - $sortByURL = $url->append($sortByURL,'orderType=asc'); + $sortByURL = $url->append($sortByURL,'sortOrder=asc'); } push(@profileFields, { "fieldName"=>$fieldName, "label"=>$label, "sequenceNumber"=>$profileField->{sequenceNumber}, "visible"=>$profileField->{visible}, + "fieldType"=>$profileField->{fieldType}, }); push (@profileField_loop, { "profileField_label"=>$label, @@ -312,7 +318,6 @@ sub view { }); } -# $error->info("selected profile fields, time :".(time() - $start_time)); $sql = "select distinct users.userId, users.userName, userProfileData.publicProfile, userProfileData.publicEmail "; foreach my $profileField (@profileFields){ @@ -321,14 +326,13 @@ sub view { $sql .= " from users"; $sql .= " left join userProfileData using(userId) where users.userId != '1'"; -# $error->info("creating constraint, time :".(time() - $start_time)); my $constraint; my @profileSearchFields = (); my $searchType = $form->process('searchType') || 'or'; if ($form->process('search')){ - # Normal search with one query takes precedence over other search options + # Normal search with one keyword takes precedence over other search options if($form->process('limitSearch')){ - # Normal search with one query in a limited number of fields + # Normal search with one keyword in a limited number of fields foreach my $profileField (@profileFields){ if ($form->process('includeInSearch_'.$profileField->{fieldName})){ push(@profileSearchFields,'userProfileData.'.$profileField->{fieldName} @@ -337,15 +341,15 @@ sub view { } } else{ - # Normal search with one query in all fields + # Normal search with one keyword in all fields $constraint = "(".join(' or ', map {'userProfileData.'.$_->{fieldName} .' like "%'.$form->process('search').'%"'} @profileFields).")"; } } elsif ($form->process('searchExact')){ - # Exact search with one query + # Exact search with one keyword if($form->process('limitSearch')){ - # Exact search with one query in a limited number of fields + # Exact search with one keyword in a limited number of fields foreach my $profileField (@profileFields){ if ($form->process('includeInSearch_'.$profileField->{fieldName})){ push(@profileSearchFields,'userProfileData.'.$profileField->{fieldName} @@ -354,7 +358,7 @@ sub view { } } else{ - # Exact search with one query in all fields + # Exact search with one keyword in all fields $constraint = "(".join(' or ', map {'userProfileData.'.$_->{fieldName} .' like "'.$form->process('searchExact').'"'} @profileFields).")"; } @@ -378,16 +382,14 @@ sub view { } $sql .= " and ".$constraint if ($constraint); -# $error->info("created constraint, time :".(time() - $start_time)); - - my $orderBy = $form->process('orderBy') || $self->get('sortBy') || 'users.username'; - my $orderType = $form->process('orderType') || $self->get('sortOrder') || 'asc'; + my $sortBy = $form->process('sortBy') || $self->get('sortBy') || 'users.username'; + my $sortOrder = $form->process('sortOrder') || $self->get('sortOrder') || 'asc'; - my @orderByUserProperties = ('dateCreated', 'lastUpdated', 'karma', 'userId'); - if(isIn($orderBy,@orderByUserProperties)){ - $orderBy = 'users.'.$orderBy; + my @sortByUserProperties = ('dateCreated', 'lastUpdated', 'karma', 'userId'); + if(isIn($sortBy,@sortByUserProperties)){ + $sortBy = 'users.'.$sortBy; } - $sql .= " order by ".$orderBy." ".$orderType; + $sql .= " order by ".$sortBy." ".$sortOrder; ($defaultPublicProfile) = $self->session->db->quickArray("SELECT dataDefault FROM userProfileField WHERE fieldName='publicProfile'"); ($defaultPublicEmail) = $self->session->db->quickArray("SELECT dataDefault FROM userProfileField WHERE fieldName='publicEmail'"); @@ -403,9 +405,7 @@ sub view { my $p = WebGUI::Paginator->new($self->session,$currentUrl,$self->getValue("usersPerPage"), undef, $paginatePage); -# $error->info("reading from database, time :".(time() - $start_time)); $sth = $self->session->db->read($sql); -# $error->info("users read from database, time :".(time() - $start_time)); my @visibleUsers; while (my $user = $sth->hashRef){ my $showGroupId = $self->get("showGroupId"); @@ -415,10 +415,8 @@ sub view { } } } -# $error->info("applied group constraints, time :".(time() - $start_time)); $p->setDataByArrayRef(\@visibleUsers); my $users = $p->getPageData($paginatePage); -# $error->info("set data by page, time :".(time() - $start_time)); foreach my $user (@$users){ if ($user->{publicProfile} eq "1" || ($user->{publicProfile} eq "" && $defaultPublicProfile eq "1")){ my (@profileFieldValues); @@ -432,16 +430,16 @@ sub view { }); } else{ - push (@profileFieldValues, { - "profile_value"=>$user->{$profileField->{fieldName}}, - }); my $profileFieldName = $profileField->{fieldName}; $profileFieldName =~ s/ /_/g; $profileFieldName =~ s/\./_/g; + my $value = $user->{$profileField->{fieldName}}; + push (@profileFieldValues, { + "profile_value"=>$value, + }); unless($self->get("showOnlyVisibleAsNamed") && $profileField->{visible} != 1){ - $userProperties{'user_profile_'.$profileFieldName.'_value'} = $user->{$profileField->{fieldName}}; + $userProperties{'user_profile_'.$profileFieldName.'_value'} = $value; } - #$userProperties{"user.profile.".$profileFieldName.".value"} = $user->{$profileField->{fieldName}}; } } $userProperties{"user_profile_emailNotPublic"} = $emailNotPublic; @@ -457,14 +455,13 @@ sub view { }); } } -# $error->info("created tmpl vars for users, time :".(time() - $start_time)); $p->appendTemplateVars(\%var); $var{numberOfProfileFields} = scalar(@profileFields); $var{profileField_loop} = \@profileField_loop; $var{user_loop} = \@users; - $var{alphabetSearch_loop} = $self->getAlphabetSearchLoop("lastName",$self->get("alphabet")); + $var{alphabetSearch_loop} = $self->getAlphabetSearchLoop($self->get("alphabetSearchField"),$self->get("alphabet")); $var{searchFormHeader} = WebGUI::Form::formHeader($self->session,{action => $self->getUrl}); $var{searchFormSubmit} = WebGUI::Form::submit($self->session,{value => $i18n->get('submit search label')}); @@ -487,10 +484,207 @@ sub view { }); -# $error->info("global tmpl_vars created, time :".(time() - $start_time)); my $out = $self->processTemplate(\%var,$self->get("templateId")); -# $error->info("done, going to return output, time :".(time() - $start_time)); return $out; } +# Everything below here is to make it easier to install your custom +# wobject, but has nothing to do with wobjects in general +# ------------------------------------------------------------------- +# cd /data/WebGUI/lib +# perl -MWebGUI::Asset::Wobject::NewWobject -e install www.example.com.conf [ /path/to/WebGUI ] +# - or - +# perl -MWebGUI::Asset::Wobject::NewWobject -e uninstall www.example.com.conf [ /path/to/WebGUI ] +# ------------------------------------------------------------------- + + +use base 'Exporter'; +our @EXPORT = qw(install uninstall); +use WebGUI::Session; + +#------------------------------------------------------------------- +sub install { + my $config = $ARGV[0]; + my $home = $ARGV[1] || "/data/WebGUI"; + die "usage: perl -MWebGUI::Asset::Wobject::UserList -e install www.example.com.conf\n" unless ($home && +$config); + print "Installing asset.\n"; + my $session = WebGUI::Session->open($home, $config); + $session->config->addToArray("assets","WebGUI::Asset::Wobject::NewWobject"); + $session->db->write("create table UserList ( + assetId varchar(22) not null, + revisionDate bigint(20), + templateId varchar(22), + showGroupId varchar(22), + hideGroupId varchar(22), + usersPerPage int(11), + alphabet text, + alphabetSearchField varchar(128), + showOnlyVisibleAsNamed int(11), + sortBy varchar(128), + sortOrder varchar(4), + PRIMARY KEY (`assetId`,`revisionDate`) + )"); + my $import = WebGUI::Asset->getImportNode($session); + + $import->addChild({ + + className=>"WebGUI::Asset::Template", + + template=>q| + +

+
+ + +

+
+ +

+ + + + + + + + + | + +
+
+ +Search with one keyword in one or more fields that the user can select
+ + +
+
+
+ +
+
+ +Search with one keyword in one or more fields that are defined by hidden form fields
+ + + + + + +
+
+ +Search with multiple keywords
+ +^International('searchFormTypeSelect label','Asset_UserList');
+:
+ (exact):
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IdUsername + + +
+ +^International('Email not public message','Asset_UserList'); + + + +
^International('No users message','Asset_UserList');
+ +

+
+|, + + ownerUserId=>'3', + + groupIdView=>'7', + + groupIdEdit=>'12', + + title=>"Default UserList", + + menuTitle=>"Default UserList", + + url=>"templates/userlist", + + namespace=>"UserList" + + },'UserListTmpl0000001'); + + my $versionTag = WebGUI::VersionTag->getWorking($session); + $versionTag->set({name=>"Install UserList Template"}); + $versionTag->commit; + + $session->var->end; + $session->close; + print "Done. Please restart Apache.\n"; +} +#------------------------------------------------------------------- +sub uninstall { + my $config = $ARGV[0]; + my $home = $ARGV[1] || "/data/WebGUI"; + die "usage: perl -MWebGUI::Asset::Wobject::UserList -e uninstall www.example.com.conf\n" unless ($home && +$config); + print "Uninstalling asset.\n"; + my $session = WebGUI::Session->open($home, $config); + $session->config->deleteFromArray("assets","WebGUI::Asset::Wobject::UserList"); + my $rs = $session->db->read("select assetId from asset where +className='WebGUI::Asset::Wobject::UserList'"); + while (my ($id) = $rs->array) { + my $asset = WebGUI::Asset->new($session, $id, "WebGUI::Asset::Wobject::UserList"); + $asset->purge if defined $asset; + } + + $rs = $session->db->read("select distinct(assetId) from template where namespace='UserList'"); + + while (my ($id) = $rs->array) { + my $asset = WebGUI::Asset->new($session, $id, "WebGUI::Asset::Template"); + $asset->purge if defined $asset; + } + + $session->db->write("drop table UserList"); + $session->var->end; + $session->close; + print "Done. Please restart Apache.\n"; +} + 1; diff --git a/lib/WebGUI/i18n/English/Asset_UserList.pm b/lib/WebGUI/i18n/English/Asset_UserList.pm index 4249e62a5..6a776167a 100644 --- a/lib/WebGUI/i18n/English/Asset_UserList.pm +++ b/lib/WebGUI/i18n/English/Asset_UserList.pm @@ -106,6 +106,21 @@ seperated values|, lastUpdated => 1081514049 }, + 'alphabetSearchField' => { + message => q|The field in which the alphabet search will be done.|, + lastUpdated => 1081514049 + }, + + 'alphabetSearchField label' => { + message => q|Alphabet Search Field|, + lastUpdated => 1081514049 + }, + + 'alphabetSearchField description' => { + message => q|Select the profile field in which the alphabet search will be done.|, + lastUpdated => 1081514049 + }, + 'Profile not public message' => { message => q|Profile not public|, lastUpdated => 1081514049 From bbbabb48cf447914081ced84fa60ee23f7396dcf Mon Sep 17 00:00:00 2001 From: Yung Han Khoe Date: Fri, 23 May 2008 21:11:00 +0000 Subject: [PATCH 12/16] Adding small UserList icon --- www/extras/assets/small/userlist.gif | Bin 0 -> 1096 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 www/extras/assets/small/userlist.gif diff --git a/www/extras/assets/small/userlist.gif b/www/extras/assets/small/userlist.gif new file mode 100644 index 0000000000000000000000000000000000000000..8a49a417f25679eb28e222dea73328a82ac30152 GIT binary patch literal 1096 zcmc(e`!m}I0KmUUy{6}}_DWkfbVV#_MDyTStE<^4W;Ka849jVXi}prop3vbd^4GpeLu=rtS5g~~Z;?Aowk5nWg7Fo;^*8Uay`~{yMKA*4RV#6bHJOEF?q5_VN zj_CAqDvfS7o6$&w#bUu?u{a!#OrhlE<*C(bo6WYox?#0iO(v7g`foT2xw5j-*w`2b z0mETXDwVdnx+)S4snvfP3CQ_G2m}n$&R5m%9V~2(Wl-wy5dYol>@ zxPi2@yH{F`GZX>Ck8Yq5@QZL5iA0*2nYsPB7mZG5Fc_jj-=(D`o($7>2l=+xkzMt0 z_A$`<1_KTX)avwW8}GW65yLrdTB-}5-yRoxRn_;Tzw+Aq{DA)z|9?Ps0H6XOA1ppR z0XQE40=u#nMnh|gyLi^?9^s0RrILI)QU`W(JvmNl_pt|Zk)Oo8h(04>rU%0$p(RXj zkn*Rfs0KZ0E*?`+@BaO$vbaO;;0`Um?aBD%boV!7QHjbQb+vUj%VXkd{Mr|qeL_Xi z^LWj*AjeLE@poeY2a#RYSMI-izp6eEyU7GRS`uGexs@Ruto;J#pL{dm%f)ltr)RQK zuKQNj{V@0Zcy)9}aITZI;Uvg8LAud-9i9Y92Ipelxg4|i@bl)~tMGD2{Vm~aJ|_Pm z_^iy^KTa9_tPSLHP}SSkl3wZQo1c~@T#Er6a}5CH-sheMUq(5{fv31^hJ%xv^*qjx oyTFR Date: Sat, 24 May 2008 15:52:59 +0000 Subject: [PATCH 13/16] Added some UserList help and small fixes. --- lib/WebGUI/Asset/Wobject/UserList.pm | 18 ++++++++----- lib/WebGUI/Help/Asset_UserList.pm | 5 ++++ lib/WebGUI/i18n/English/Asset_UserList.pm | 31 +++++++++++++++++++++++ 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/lib/WebGUI/Asset/Wobject/UserList.pm b/lib/WebGUI/Asset/Wobject/UserList.pm index 3165260f5..530e18163 100644 --- a/lib/WebGUI/Asset/Wobject/UserList.pm +++ b/lib/WebGUI/Asset/Wobject/UserList.pm @@ -290,10 +290,12 @@ sub view { "visible"=>$profileField->{visible}, "fieldType"=>$profileField->{fieldType}, }); - push (@profileField_loop, { - "profileField_label"=>$label, - "profileField_sortByURL"=>$sortByURL, - }); + if($profileField->{visible}){ + push (@profileField_loop, { + "profileField_label"=>$label, + "profileField_sortByURL"=>$sortByURL, + }); + } unless($self->get("showOnlyVisibleAsNamed") && $profileField->{visible} != 1){ $var{'profileField_'.$fieldName.'_label'} = $label; $var{'profileField_'.$fieldName.'_sortByURL'} = $sortByURL; @@ -434,9 +436,11 @@ sub view { $profileFieldName =~ s/ /_/g; $profileFieldName =~ s/\./_/g; my $value = $user->{$profileField->{fieldName}}; - push (@profileFieldValues, { - "profile_value"=>$value, - }); + if($profileField->{visible}){ + push (@profileFieldValues, { + "profile_value"=>$value, + }); + } unless($self->get("showOnlyVisibleAsNamed") && $profileField->{visible} != 1){ $userProperties{'user_profile_'.$profileFieldName.'_value'} = $value; } diff --git a/lib/WebGUI/Help/Asset_UserList.pm b/lib/WebGUI/Help/Asset_UserList.pm index 454d23113..18d2bc783 100644 --- a/lib/WebGUI/Help/Asset_UserList.pm +++ b/lib/WebGUI/Help/Asset_UserList.pm @@ -26,6 +26,11 @@ our $HELP = { { 'name' => 'searchFormTypeAnd' }, { 'name' => 'searchFormTypeSelect' }, { 'name' => 'searchFormQuery_form' }, + { 'name' => 'search_PROFILEFIELDNAME_text' }, + { 'name' => 'searchExact_PROFILEFIELDNAME_text' }, + { 'name' => 'limitSearch' }, + { 'name' => 'includeInSearch_PROFILEFIELDNAME_hidden' }, + { 'name' => 'includeInSearch_PROFILEFIELDNAME_checkBox' }, { 'name' => 'numberOfProfileFields' }, { 'name' => 'profileField_PROFILEFIELDNAME_label' }, { 'name' => 'profileField_PROFILEFIELDNAME_sortByURL' }, diff --git a/lib/WebGUI/i18n/English/Asset_UserList.pm b/lib/WebGUI/i18n/English/Asset_UserList.pm index 6a776167a..3772be1ac 100644 --- a/lib/WebGUI/i18n/English/Asset_UserList.pm +++ b/lib/WebGUI/i18n/English/Asset_UserList.pm @@ -196,6 +196,37 @@ seperated values|, lastUpdated => 1081514049 }, + 'search_PROFILEFIELDNAME_text' => { + message => q|A text input to do a normal search in profile field PROFILEFIELDNAME. Example: +<tmpl_var search_lastName_text>.|, + lastUpdated => 1081514049 + }, + + 'searchExact_PROFILEFIELDNAME_text' => { + message => q|A text input to do an exact search in profile field PROFILEFIELDNAME. Example: +<tmpl_var searchExact_email_text>.|, + lastUpdated => 1081514049 + }, + + 'limitSearch' => { + message => q|A hidden form element to indicate that the search is limited to certain profile +fields. Use includeInSearch_PROFILEFIELDNAME_hidden or includeInSearch_PROFILEFIELDNAME_checkBox tmpl_vars to +select which fields the search is limited to.|, + lastUpdated => 1081514049 + }, + + 'includeInSearch_PROFILEFIELDNAME_hidden' => { + message => q|A hidden form element to indicate that profile field PROFILEFIELDNAME will be +searched. This will only have an effect if the limitSearch tmpl_var is part of the search form.|, + lastUpdated => 1081514049 + }, + + 'includeInSearch_PROFILEFIELDNAME_checkBox' => { + message => q|A checkBox that the user can use to choose whether profile field PROFILEFIELDNAME will +be searched or not. This will only have an effect if the limitSearch tmpl_var is part of the search form.|, + lastUpdated => 1081514049 + }, + 'numberOfProfileFields' => { message => q|The number of profile fields.|, lastUpdated => 1081514049 From 043daceb7ca3f080ef4f7479b9a1a8b1773cc795 Mon Sep 17 00:00:00 2001 From: Yung Han Khoe Date: Thu, 29 May 2008 14:44:41 +0000 Subject: [PATCH 14/16] Added some UserList search form tmpl_vars --- lib/WebGUI/Asset/Wobject/UserList.pm | 82 ++++++++++++++++++++++- lib/WebGUI/Help/Asset_UserList.pm | 2 + lib/WebGUI/i18n/English/Asset_UserList.pm | 27 ++++++++ 3 files changed, 110 insertions(+), 1 deletion(-) diff --git a/lib/WebGUI/Asset/Wobject/UserList.pm b/lib/WebGUI/Asset/Wobject/UserList.pm index 530e18163..8ef1416fb 100644 --- a/lib/WebGUI/Asset/Wobject/UserList.pm +++ b/lib/WebGUI/Asset/Wobject/UserList.pm @@ -70,6 +70,72 @@ sub getAlphabetSearchLoop { #------------------------------------------------------------------- +=head2 getFormElement ( data ) + +Returns the form element tied to this field. + +=head3 data + +A hashref containing the properties of this field. + +=cut + +sub getFormElement { + + my $self = shift; + my $data = shift; + my %param; + + $param{name} = $data->{name}; + my $name = $param{name}; + $param{value} = $data->{value} || WebGUI::Operation::Shared::secureEval($self->session,$data->{dataDefault}); + $param{fieldType} = $data->{fieldType}; + + if ($data->{fieldType} eq "Checkbox") { + $param{value} = ($data->{defaultValue} =~ /checked/xi) ? 1 : ""; + } + + if (WebGUI::Utility::isIn($data->{fieldType},qw(SelectList CheckList SelectBox Attachments SelectSlider))) { + my @defaultValues; + if ($self->session->form->param($name)) { + @defaultValues = $self->session->form->selectList($name); + } else { + foreach (split(/\n/x, $data->{value})) { + s/\s+$//x; # remove trailing spaces + push(@defaultValues, $_); + } + } + $param{value} = \@defaultValues; + } + + if ($data->{possibleValues}){ + my $values = WebGUI::Operation::Shared::secureEval($self->session,$data->{possibleValues}); + unless (ref $values eq 'HASH') { + if ($self->get('possibleValues') =~ /\S/) { + $self->session->errorHandler->warn("Could not get a hash out of possible values for profile field " + .$self->getId); + } + $values = {}; + } + $param{options} = $values; + } + + if ($data->{fieldType} eq "YesNo") { + if ($data->{defaultValue} =~ /yes/xi) { + $param{value} = 1; + } elsif ($data->{defaultValue} =~ /no/xi) { + $param{value} = 0; + } + } + + my $formElement = eval { WebGUI::Pluggable::instanciate("WebGUI::Form::". ucfirst $param{fieldType}, "new", +[$self->session, \%param ])}; + return $formElement->toHtml(); + +} + +#------------------------------------------------------------------- + =head2 definition ( properties ) Defines wobject properties for UserList instances. @@ -269,7 +335,8 @@ sub view { } $sth = $self->session->db->read( - "SELECT field.fieldName, field.label, field.sequenceNumber, field.visible, field.fieldType " + "SELECT field.fieldName, field.label, field.sequenceNumber, field.visible, field.fieldType, " + ."field.dataDefault, field.possibleValues " ."FROM userProfileField as field " ."left join userProfileCategory as category USING(profileCategoryId) " ."ORDER BY category.sequenceNumber, field.sequenceNumber"); @@ -301,18 +368,29 @@ sub view { $var{'profileField_'.$fieldName.'_sortByURL'} = $sortByURL; } # create field specific templ_vars for search + my %formElementProperties = %{$profileField}; + + $formElementProperties{value} = $form->process('search_'.$fieldName); + $formElementProperties{name} = 'search_'.$fieldName; + $var{'search_'.$fieldName.'_form'} = $self->getFormElement(\%formElementProperties); $var{'search_'.$fieldName.'_text'} = WebGUI::Form::Text($self->session, { -name => 'search_'.$fieldName, -value => $form->process('search_'.$fieldName), }); + + $formElementProperties{value} = $form->process('search_Exact'.$fieldName); + $formElementProperties{name} = 'searchExact_'.$fieldName; + $var{'searchExact_'.$fieldName.'_form'} = $self->getFormElement(\%formElementProperties); $var{'searchExact_'.$fieldName.'_text'} = WebGUI::Form::Text($self->session, { -name => 'searchExact_'.$fieldName, -value => $form->process('searchExact_'.$fieldName), }); + $var{'includeInSearch_'.$fieldName.'_hidden'} = WebGUI::Form::Hidden($self->session, { -name => 'includeInSearch_'.$fieldName, -value => '1', }); + $var{'includeInSearch_'.$fieldName.'_checkBox'} = WebGUI::Form::Checkbox($self->session, { -name => 'includeInSearch_'.$fieldName, -value => '1', @@ -526,6 +604,8 @@ $config); showOnlyVisibleAsNamed int(11), sortBy varchar(128), sortOrder varchar(4), + overridePublicEmail int(11), + overridePublicProfile int(11), PRIMARY KEY (`assetId`,`revisionDate`) )"); my $import = WebGUI::Asset->getImportNode($session); diff --git a/lib/WebGUI/Help/Asset_UserList.pm b/lib/WebGUI/Help/Asset_UserList.pm index 18d2bc783..73f7d3d8b 100644 --- a/lib/WebGUI/Help/Asset_UserList.pm +++ b/lib/WebGUI/Help/Asset_UserList.pm @@ -27,7 +27,9 @@ our $HELP = { { 'name' => 'searchFormTypeSelect' }, { 'name' => 'searchFormQuery_form' }, { 'name' => 'search_PROFILEFIELDNAME_text' }, + { 'name' => 'search_PROFILEFIELDNAME_form' }, { 'name' => 'searchExact_PROFILEFIELDNAME_text' }, + { 'name' => 'searchExact_PROFILEFIELDNAME_form' }, { 'name' => 'limitSearch' }, { 'name' => 'includeInSearch_PROFILEFIELDNAME_hidden' }, { 'name' => 'includeInSearch_PROFILEFIELDNAME_checkBox' }, diff --git a/lib/WebGUI/i18n/English/Asset_UserList.pm b/lib/WebGUI/i18n/English/Asset_UserList.pm index 3772be1ac..01fcc8543 100644 --- a/lib/WebGUI/i18n/English/Asset_UserList.pm +++ b/lib/WebGUI/i18n/English/Asset_UserList.pm @@ -135,11 +135,26 @@ seperated values|, lastUpdated => 1081514049 }, + 'id label' => { + message => q|Id|, + lastUpdated => 1081514049 + }, + + 'username label' => { + message => q|Username|, + lastUpdated => 1081514049 + }, + 'query label' => { message => q|Query|, lastUpdated => 1081514049 }, + 'search in label' => { + message => q|Search in:|, + lastUpdated => 1081514049 + }, + 'submit search label' => { message => q|Search|, lastUpdated => 1081514049 @@ -202,12 +217,24 @@ seperated values|, lastUpdated => 1081514049 }, + 'search_PROFILEFIELDNAME_form' => { + message => q|The form element tied to this field to do a normal search in profile field PROFILEFIELDNAME. Example: +<tmpl_var search_timeZone_form> will be a select box.|, + lastUpdated => 1081514049 + }, + 'searchExact_PROFILEFIELDNAME_text' => { message => q|A text input to do an exact search in profile field PROFILEFIELDNAME. Example: <tmpl_var searchExact_email_text>.|, lastUpdated => 1081514049 }, + 'searchExact_PROFILEFIELDNAME_form' => { + message => q|The form element tied to this field to do an exact search in profile field PROFILEFIELDNAME. Example: +<tmpl_var searchExact_email_form>.|, + lastUpdated => 1081514049 + }, + 'limitSearch' => { message => q|A hidden form element to indicate that the search is limited to certain profile fields. Use includeInSearch_PROFILEFIELDNAME_hidden or includeInSearch_PROFILEFIELDNAME_checkBox tmpl_vars to From 4cba70e772f77898d1f8c245d0a296e378bca412 Mon Sep 17 00:00:00 2001 From: Yung Han Khoe Date: Thu, 29 May 2008 14:47:36 +0000 Subject: [PATCH 15/16] Added UserList icon --- www/extras/assets/userlist.gif | Bin 0 -> 2001 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 www/extras/assets/userlist.gif diff --git a/www/extras/assets/userlist.gif b/www/extras/assets/userlist.gif new file mode 100644 index 0000000000000000000000000000000000000000..e07548ce59804005cff8ff9d16c3278dfa00dbc6 GIT binary patch literal 2001 zcmV;?2QK(WNk%w1VK4wN0QUd@00030|Nl2NG!zsUFEBD093Tn{3@a=x7$Yr2g}5s( zG9M-@A8MFPkh@cs!6R38SE$x7hqGOx#$~C@RfL>&qq=gKtS~)9F*7tri>p|r$ycDk zQH-c;oVs1B%3PqlYO~U6vCUwRr5qt6U#iA(yViBN(rmfXcE#Xz z!P|4W(Q~%Vd%o3y#oKbe)pfqpcD~eo#oK$q)q=^~f6U;4%iV*_-Ga;9g38;4&EAB| z+=a^9YTUY(T6D}<( zI5#vmHZ%3J4EVVh;;9wfq#EF#2hEWYz=;rEL<`ZMEtF^zz^HgPH8DOsI6FExIXE^q zHZ(>>LpnDyQ&3C1as$zW3nnBXEh{K9F)lJNEi^JOI5so?mkP|0K0P`%^oY4f=`>?1Bybix2yW5BZ4?_lOV1Yz+E|5b}i(+j$Q6h!L@hUx#{Z z{eJ-XegN%x0Nrf>-*W-fYXib%1LAW8uUG@*cm}#(2K0gp?0pN|a|-5r4$Er{yJHQQ zQVY;>5QkbTT}3P_C?zm1EHyJRH#IXlI5s~$J2NsdF)%MRG&4XyK4oNM>~jFtWdQqn z0mNPc?{x*pWCf&B1l4Q{x?T#gTM5Br49RR0xMUTlS`(X96wq@VflL|Ad@hAiBAjF} zvU57Zg-x$}OU##No_JM-a$x#(0P}DFvQhxZTLa{11jAkl(Pj$lbPU~Z6TxR1e?t+D zO%!Q98a*f$WJ)!7U`y4LI<@`5o}2^iDOD+Og(>MPiRy} zTuVSLB_PB}0B=w}G%YC+3kY{vNiZrWIX5=MJpf5QIWi?6ARQb!H#R#nF*!9gH#Ic} z2L}NG0ssI1A^8LW00930EC2ui05AYB000R80RIUbNN`}ULFRcemMT=JSgE2#OGuE|hlU#tV*<+ zwZu|JQ6DpAzLtSiR^mH$m}22+Q-{u@L#%eS+@h+KDPO-x9fD@AZ$WF{zR?2IhHxD{ zi&7~T$O~DyQideWGA67WFUth2DNELe&u2b-{zN*JYap+3IBfB$F^wP&f6s!-y)tv{DW?@c`iFn{bAt%Q24h0f;1! zKoW@}1p!fwJL5=m3N){Pt)DhD3MXfrZ~_|E z$YMzxa3BH;aT<`ILk$unkbnadkf4GMF{BW}2M<9z&?sl%^8^zIAb`LU-%w)tFu(;S2vGzH zCYL}14K~yegb_&8fPx1OIow1hXMo`a8&QCv%^cZ$LVyAaU;s}$AXIQP!8#Oy1Q9|E zaRd@Mkl;ab1wq>c8kx}l Date: Thu, 29 May 2008 16:51:11 +0000 Subject: [PATCH 16/16] Added tmpl_vars for files to UserList --- lib/WebGUI/Asset/Wobject/UserList.pm | 56 +++++++++++++++++++++-- lib/WebGUI/Help/Asset_UserList.pm | 2 + lib/WebGUI/i18n/English/Asset_UserList.pm | 12 +++++ 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/lib/WebGUI/Asset/Wobject/UserList.pm b/lib/WebGUI/Asset/Wobject/UserList.pm index 8ef1416fb..7d8ea0bc3 100644 --- a/lib/WebGUI/Asset/Wobject/UserList.pm +++ b/lib/WebGUI/Asset/Wobject/UserList.pm @@ -13,6 +13,7 @@ use WebGUI::Operation::Shared; use WebGUI::International; use WebGUI::Pluggable; use WebGUI::Form::Image; +use WebGUI::Form::File; use base 'WebGUI::Asset::Wobject'; =head1 LEGAL @@ -70,6 +71,48 @@ sub getAlphabetSearchLoop { #------------------------------------------------------------------- +=head2 getFieldValue ( value, field ) + +Processes the field value for date(Time) fields and Other Thing fields. + +=head3 value + +The value as stored in the database. + +=head3 field + +A reference to a hash containing the fields properties. + +=cut + +sub getFieldValue { + + my $self = shift; + my $value = shift; + my $field = shift; + my $dateFormat = shift || "%z"; + my $dateTimeFormat = shift; + my $processedValue = $value; + + if ($field->{fieldType} eq "date"){ + $processedValue = $self->session->datetime->epochToHuman($value,$dateFormat); + } + elsif ($field->{fieldType} eq "dateTime"){ + $processedValue = $self->session->datetime->epochToHuman($value,$dateTimeFormat); + } + elsif (WebGUI::Utility::isIn(ucfirst $field->{fieldType},qw(File Image))) { + $processedValue = WebGUI::Form::DynamicField->new($self->session, + fieldType=>$field->{fieldType}, + value=>$value + )->getValueAsHtml(); + } + + return $processedValue; + +} + +#------------------------------------------------------------------- + =head2 getFormElement ( data ) Returns the form element tied to this field. @@ -514,10 +557,17 @@ sub view { $profileFieldName =~ s/ /_/g; $profileFieldName =~ s/\./_/g; my $value = $user->{$profileField->{fieldName}}; + my %profileFieldValues; + if (WebGUI::Utility::isIn(ucfirst $profileField->{fieldType},qw(File Image)) && $value ne ''){ + my $file = $self->getFieldValue($value,{ + fieldType=>$profileField->{fieldType} + }); + $profileFieldValues{profile_file} = $file; + $userProperties{'user_profile_'.$profileFieldName.'_file'} = $file; + } + $profileFieldValues{profile_value} = $value; if($profileField->{visible}){ - push (@profileFieldValues, { - "profile_value"=>$value, - }); + push (@profileFieldValues, \%profileFieldValues); } unless($self->get("showOnlyVisibleAsNamed") && $profileField->{visible} != 1){ $userProperties{'user_profile_'.$profileFieldName.'_value'} = $value; diff --git a/lib/WebGUI/Help/Asset_UserList.pm b/lib/WebGUI/Help/Asset_UserList.pm index 73f7d3d8b..83d39fae0 100644 --- a/lib/WebGUI/Help/Asset_UserList.pm +++ b/lib/WebGUI/Help/Asset_UserList.pm @@ -54,11 +54,13 @@ our $HELP = { { 'name' => 'user_name' }, { 'name' => 'user_id' }, { 'name' => 'user_profile_PROFILEFIELDNAME_value' }, + { 'name' => 'user_profile_PROFILEFIELDNAME_file' }, { 'name' => 'user_profile_emailNotPublic' }, { 'name' => 'user_profile_loop', 'variables' => [ { 'name' => 'profile_emailNotPublic' }, { 'name' => 'profile_value' }, + { 'name' => 'profile_file' }, ], }, ], diff --git a/lib/WebGUI/i18n/English/Asset_UserList.pm b/lib/WebGUI/i18n/English/Asset_UserList.pm index 01fcc8543..cac9a56fb 100644 --- a/lib/WebGUI/i18n/English/Asset_UserList.pm +++ b/lib/WebGUI/i18n/English/Asset_UserList.pm @@ -300,6 +300,13 @@ profile. Example <tmpl_var user_profile_firstName_value>|, lastUpdated => 1081514049 }, + 'user_profile_PROFILEFIELDNAME_file' => { + message => q|The file for the profile field with the name PROFILEFIELDNAME in the users user +profile. Example <tmpl_var user_profile_firstName_file>. This is available if the profile field is a file or +an image.|, + lastUpdated => 1081514049 + }, + 'user_profile_emailNotPublic' => { message => q|A conditional that is true if the users email address is not public.|, lastUpdated => 1081514049 @@ -321,6 +328,11 @@ true for the 'email' profile field.|, lastUpdated => 1081514049 }, + 'profile_value' => { + message => q|The file for this profile field, available if the profile field is an image or file.|, + lastUpdated => 1081514049 + }, + 'profileField_loop' => { message => q|A loop containing profile fields|, lastUpdated => 1081514049