Added UserList wobject

This commit is contained in:
Yung Han Khoe 2008-05-30 15:31:24 +00:00
commit 075c02221f
9 changed files with 1356 additions and 0 deletions

View file

@ -0,0 +1,783 @@
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;
use WebGUI::Pluggable;
use WebGUI::Form::Image;
use WebGUI::Form::File;
use base 'WebGUI::Asset::Wobject';
=head1 LEGAL
Copyright 2004-2008 United Knowledge
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
use WebGUI::Asset::Wobject::UserList;
=cut
#-------------------------------------------------------------------
=head2 getAlphabetSearchLoop ( )
Returns an array ref that contains tmpl_vars for the Alphabet Search.
=cut
sub getAlphabetSearchLoop {
my $self = 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);
my $searchURL = "?searchExact_".$fieldName."=".$letter."%25";
my $hasResults = $self->session->db->quickScalar("select if ("
."(select count(*) from userProfileData where ".$fieldName." like '".$letter."%')<>0, 1, 0)");
push @alphabetLoop, {
alphabetSearch_loop_label => $htmlEncodedLetter || $letter,
alphabetSearch_loop_hasResults => $hasResults,
alphabetSearch_loop_searchURL => $searchURL,
}
}
return \@alphabetLoop;
}
#-------------------------------------------------------------------
=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.
=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');
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});
$profileFields{$field->{fieldName}} = $label;
}
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=>"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",
tab=>"display",
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=>\%profileFields,
label=>$i18n->get('sort by'),
hoverHelp=>$i18n->get('sort by description'),
},
);
push(@{$definition}, {
assetName=>$i18n->get('assetName'),
icon=>'userlist.gif',
autoGenerateForms=>1,
tableName=>'UserList',
className=>'WebGUI::Asset::Wobject::UserList',
properties=>\%properties
});
return $class->SUPER::definition($session, $definition);
}
#-------------------------------------------------------------------
=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.
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;
return undef;
}
#-------------------------------------------------------------------
=head2 view ( )
=cut
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);
my ($defaultPublicProfile, $defaultPublicEmail, $user, $sth, $sql, $profileField);
my $currentUrlWithoutSort = $self->getUrl();
foreach ($form->param) {
unless (WebGUI::Utility::isIn($_,qw(sortBy sortOrder op func)) || $_ =~ /identifier/i || $_ =~ /password/i) {
$currentUrlWithoutSort = $url->append($currentUrlWithoutSort, $url->escape($_)
.'='.$url->escape($form->process($_)));
}
}
$sth = $self->session->db->read(
"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");
while ($profileField = $sth->hashRef){
my $label = WebGUI::Operation::Shared::secureEval($self->session,$profileField->{label});
my $fieldName = $profileField->{fieldName};
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,'sortOrder=asc');
}
push(@profileFields, {
"fieldName"=>$fieldName,
"label"=>$label,
"sequenceNumber"=>$profileField->{sequenceNumber},
"visible"=>$profileField->{visible},
"fieldType"=>$profileField->{fieldType},
});
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;
}
# 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',
-checked=> $form->process('includeInSearch_'.$fieldName),
});
}
$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'";
my $constraint;
my @profileSearchFields = ();
my $searchType = $form->process('searchType') || 'or';
if ($form->process('search')){
# Normal search with one keyword takes precedence over other search options
if($form->process('limitSearch')){
# 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}
.' like "%'.$form->process('search').'%"');
}
}
}
else{
# 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 keyword
if($form->process('limitSearch')){
# 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}
.' like "'.$form->process('search').'"');
}
}
}
else{
# Exact search with one keyword 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.
foreach my $profileField (@profileFields){
# Exact search has precedence over normal search
if ($form->process('searchExact_'.$profileField->{fieldName})){
push(@profileSearchFields,'userProfileData.'.$profileField->{fieldName}
.' like "'.$form->process('searchExact_'.$profileField->{fieldName}).'"');
}
elsif ($form->process('search_'.$profileField->{fieldName})){
push(@profileSearchFields,'userProfileData.'.$profileField->{fieldName}
.' like "%'.$form->process('search_'.$profileField->{fieldName}).'%"');
}
}
}
if (scalar(@profileSearchFields) > 0){
$constraint = '('.join(' '.$searchType.' ',@profileSearchFields).')';
}
$sql .= " and ".$constraint if ($constraint);
my $sortBy = $form->process('sortBy') || $self->get('sortBy') || 'users.username';
my $sortOrder = $form->process('sortOrder') || $self->get('sortOrder') || 'asc';
my @sortByUserProperties = ('dateCreated', 'lastUpdated', 'karma', 'userId');
if(isIn($sortBy,@sortByUserProperties)){
$sortBy = 'users.'.$sortBy;
}
$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'");
my $paginatePage = $form->param('pn') || 1;
my $currentUrl = $self->getUrl();
foreach ($form->param) {
unless ($_ eq "pn" || $_ eq "op" || $_ eq "func" || $_ =~ /identifier/i || $_ =~ /password/i) {
$currentUrl = $url->append($currentUrl, $url->escape($_)
.'='.$url->escape($form->process($_)));
}
}
my $p = WebGUI::Paginator->new($self->session,$currentUrl,$self->getValue("usersPerPage"), undef, $paginatePage);
$sth = $self->session->db->read($sql);
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);
}
}
}
$p->setDataByArrayRef(\@visibleUsers);
my $users = $p->getPageData($paginatePage);
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{
my $profileFieldName = $profileField->{fieldName};
$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 = WebGUI::Form::DynamicField->new($self->session,
fieldType=>$profileField->{fieldType},
value=>$value
)->getValueAsHtml();
$profileFieldValues{profile_file} = $file;
$userProperties{'user_profile_'.$profileFieldName.'_file'} = $file;
}
$profileFieldValues{profile_value} = $value;
if($profileField->{visible}){
push (@profileFieldValues, \%profileFieldValues);
}
unless($self->get("showOnlyVisibleAsNamed") && $profileField->{visible} != 1){
$userProperties{'user_profile_'.$profileFieldName.'_value'} = $value;
}
}
}
$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},
});
}
}
$p->appendTemplateVars(\%var);
$var{numberOfProfileFields} = scalar(@profileFields);
$var{profileField_loop} = \@profileField_loop;
$var{user_loop} = \@users;
$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')});
$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"),
});
my $out = $self->processTemplate(\%var,$self->get("templateId"));
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),
overridePublicEmail int(11),
overridePublicProfile int(11),
PRIMARY KEY (`assetId`,`revisionDate`)
)");
my $import = WebGUI::Asset->getImportNode($session);
$import->addChild({
className=>"WebGUI::Asset::Template",
template=>q|
<tmpl_if session.var.adminOn>
<p><tmpl_var controls></p>
</tmpl_if>
<tmpl_if displayTitle>
<h1><tmpl_var title></h1>
</tmpl_if>
<tmpl_if description>
<tmpl_var description><p />
</tmpl_if>
<tmpl_if alphabetSearch_loop>
<tmpl_loop alphabetSearch_loop>
<tmpl_if alphabetSearch_loop_hasResults>
<a href="<tmpl_var alphabetSearch_loop_searchURL>"><tmpl_var alphabetSearch_loop_label></a>
<tmpl_else>
<tmpl_var alphabetSearch_loop_label>
</tmpl_if><tmpl_unless __LAST__> &#124; </tmpl_unless>
</tmpl_loop>
</tmpl_if><br />
<br />
Search with one keyword in one or more fields that the user can select <br />
<tmpl_var searchFormHeader>
<tmpl_var limitSearch>
<tmpl_var searchFormQuery_form><br />
<tmpl_var includeInSearch_lastName_checkBox> <tmpl_var profileField_lastName_label> <br />
<tmpl_var includeInSearch_email_checkBox> <tmpl_var profileField_email_label> <br />
<tmpl_var searchFormSubmit>
<tmpl_var searchFormFooter><br />
<br />
Search with one keyword in one or more fields that are defined by hidden form fields<br />
<tmpl_var searchFormHeader>
<tmpl_var searchFormQuery_form>
<tmpl_var limitSearch>
<tmpl_var includeInSearch_lastName_hidden>
<tmpl_var includeInSearch_email_hidden>
<tmpl_var searchFormSubmit>
<tmpl_var searchFormFooter><br />
<br />
Search with multiple keywords<br />
<tmpl_var searchFormHeader>
^International('searchFormTypeSelect label','Asset_UserList');<tmpl_var searchFormTypeSelect><br />
<tmpl_var profileField_lastName_label>: <tmpl_var search_lastName_text><br />
<tmpl_var profileField_email_label> (exact): <tmpl_var searchExact_email_text><br />
<tmpl_var searchFormSubmit>
<tmpl_var searchFormFooter><br />
<br />
<table cellpadding="1" cellspacing="1" border="0" width="100%">
<tr>
<tmpl_if session.var.adminOn>
<td class="tableData">Id</td>
</tmpl_if>
<td class="tableData">Username</td>
<td class="tableData">
<a href="<tmpl_var profileField_firstName_sortByURL>"><tmpl_var profileField_firstName_label></td>
<td class="tableData">
<a href="<tmpl_var profileField_lastName_sortByURL>"><tmpl_var profileField_lastName_label></td>
<td class="tableData">
<a href="<tmpl_var profileField_email_sortByURL>"><tmpl_var profileField_email_label></td>
</tr>
<tmpl_if user_loop>
<tmpl_loop user_loop>
<tr>
<tmpl_if session.var.adminOn>
<td class="tableData"> <tmpl_var user_id></td>
</tmpl_if>
<td class="tableData"> <tmpl_var user_name></td>
<td class="tableData"> <tmpl_var user_profile_fistName_value></td>
<td class="tableData"> <tmpl_var user_profile_lastName_value></td>
<td class="tableData">
<tmpl_if profile_emailNotPublic>
^International('Email not public message','Asset_UserList');
<tmpl_else>
<tmpl_var user_profile_email_value>
</tmpl_if>
</td>
</tr>
</tmpl_loop>
<tmpl_else>
<tr><td>^International('No users message','Asset_UserList');</td></tr>
</tmpl_if>
</table>
<tmpl_if multiplePages>
<div class="pagination">
<tmpl_var previousPage> &middot; <tmpl_var pageList> &middot; <tmpl_var nextPage>
</div>
</tmpl_if>
|,
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;

View file

@ -0,0 +1,93 @@
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' => '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' },
{ 'name' => 'numberOfProfileFields' },
{ 'name' => 'profileField_PROFILEFIELDNAME_label' },
{ 'name' => 'profileField_PROFILEFIELDNAME_sortByURL' },
{ 'name' => 'profileField_loop',
'variables' => [
{ 'name' => 'profileField_label' },
{ 'name' => 'profileField_sortByURL' },
],
},
{ '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_PROFILEFIELDNAME_file' },
{ 'name' => 'user_profile_emailNotPublic' },
{ 'name' => 'user_profile_loop',
'variables' => [
{ 'name' => 'profile_emailNotPublic' },
{ 'name' => 'profile_value' },
{ 'name' => 'profile_file' },
],
},
],
},
],
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;

View file

@ -0,0 +1,401 @@
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
},
'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
},
'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
},
'hideGroupId' => {
message => q|Users in this group will be hidden.|,
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
},
'usersPerPage' => {
message => q|The number of users per page|,
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' => {
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
},
'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' => {
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
},
'alphabet description' => {
message => q|The alphabet that is used for the alphabet search. Has to be a string of comma
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
},
'No users message' => {
message => q|No users found|,
lastUpdated => 1081514049
},
'Email not public message' => {
message => q|Email not public|,
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
},
'or label' => {
message => q|Or|,
lastUpdated => 1081514049
},
'and label' => {
message => q|And|,
lastUpdated => 1081514049
},
'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
},
'searchFormTypeSelect label' => {
message => q|Select search type|,
lastUpdated => 1081514049
},
'searchFormQuery_form' => {
message => q|A text input for the search query.|,
lastUpdated => 1081514049
},
'search_PROFILEFIELDNAME_text' => {
message => q|A text input to do a normal search in profile field PROFILEFIELDNAME. Example:
&lt;tmpl_var search_lastName_text&gt;.|,
lastUpdated => 1081514049
},
'search_PROFILEFIELDNAME_form' => {
message => q|The form element tied to this field to do a normal search in profile field PROFILEFIELDNAME. Example:
&lt;tmpl_var search_timeZone_form&gt; 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:
&lt;tmpl_var searchExact_email_text&gt;.|,
lastUpdated => 1081514049
},
'searchExact_PROFILEFIELDNAME_form' => {
message => q|The form element tied to this field to do an exact search in profile field PROFILEFIELDNAME. Example:
&lt;tmpl_var searchExact_email_form&gt;.|,
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
},
'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 &lt;tmpl_var user_profile_firstName_value&gt;|,
lastUpdated => 1081514049
},
'user_profile_PROFILEFIELDNAME_file' => {
message => q|The file for the profile field with the name PROFILEFIELDNAME in the users user
profile. Example &lt;tmpl_var user_profile_firstName_file&gt;. 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
},
'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
},
'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
},
'profileField_label' => {
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 &lt;tmpl_var
profileField_lastName_label&gt;. 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 &lt;tmpl_var
profileField_lastName_sortByURL&gt;. 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
},
'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,
},
};
1;