Merge with HEAD, 10472

This commit is contained in:
Colin Kuskie 2009-04-24 17:12:17 +00:00
commit 19f703dc9b
102 changed files with 5700 additions and 2269 deletions

View file

@ -1532,11 +1532,26 @@ sub www_process {
my $default = $field->{defaultValue};
WebGUI::Macro::process($self->session, \$default);
my $value = $entry->field( $field->{name} ) || $default;
# WebGUI::Form::Integer::getValue() returns 0 even if no number is passed in.
# Not really a suitable default if we want to trigger the error message
if ($field->{status} eq "required" || $field->{status} eq "editable") {
# get the raw value (by sending field type as blank)
my $rawValue = $session->form->process($field->{name}, '');
$value = $session->form->process($field->{name}, $field->{type}, undef, {
defaultValue => $default,
value => $value,
});
# this is a hack, but it's better than changing the default getValue() of Integer, which
# could have massive effects downstream in other uses.
if(($field->{type} =~ /integer/i) && defined($rawValue) && ($rawValue eq '') && ($value eq "0")) {
$value = $rawValue;
}
WebGUI::Macro::filter(\$value);
}
if ($field->{status} eq "required" && (! defined($value) || $value =~ /^\s*$/)) {

View file

@ -175,6 +175,7 @@ sub prepareView {
}
my %vars;
$vars{showAdmin} = ($session->var->isAdminOn && $self->canEdit && $self->canEditIfLocked);
my $splitter = $self->{_viewSplitter} = $self->getSeparator;
@ -194,9 +195,12 @@ sub prepareView {
$child->prepareView;
$placeHolder{$assetId} = $child;
push @children, {
id => $assetId,
isUncommitted => $child->get('status') eq 'pending',
content => $splitter . $assetId . '~~',
id => $assetId,
isUncommitted => $child->get('status') eq 'pending',
content => $splitter . $assetId . '~~',
};
if ($vars{showAdmin}) {
$children[-1]->{'dragger.icon'} = sprintf '<div id="td%s_handle" class="dragable"><div class="dragTrigger dragTriggerWrap">%s</div></div>', $assetId, $session->icon->drag('class="dragTrigger"');
};
}
@ -230,7 +234,6 @@ sub prepareView {
unshift @{ $vars{"position1_loop"} }, reverse @children;
}
$vars{showAdmin} = ($session->var->isAdminOn && $self->canEdit && $self->canEditIfLocked);
if ($vars{showAdmin}) {
# under normal circumstances we don't put HTML stuff in our code, but this will make it much easier
# for end users to work with our templates
@ -247,7 +250,6 @@ sub prepareView {
}
</style>
');
$vars{"dragger.icon"} = '<div class="dragTrigger dragTriggerWrap">'.$session->icon->drag('class="dragTrigger"').'</div>';
$vars{"dragger.init"} = '
<iframe id="dragSubmitter" style="display: none;" src="'.$session->url->extras('spacer.gif').'"></iframe>
<script type="text/javascript">

View file

@ -194,6 +194,20 @@ sub definition {
hoverHelp =>$i18n->get('compare color yes description'),
label =>$i18n->get('compare color yes label'),
},
maxScreenshotWidth=>{
fieldType =>"integer",
tab =>"display",
defaultValue =>"800",
hoverHelp =>$i18n->get('max screenshot width description'),
label =>$i18n->get('max screenshot width label'),
},
maxScreenshotHeight=>{
fieldType =>"integer",
tab =>"display",
defaultValue =>"600",
hoverHelp =>$i18n->get('max screenshot height description'),
label =>$i18n->get('max screenshot height label'),
},
categories=>{
fieldType =>"textarea",
tab =>"properties",

View file

@ -197,8 +197,6 @@ sub definition {
fieldType => 'workflow',
label => 'Survey End Workflow',
hoverHelp => 'Workflow to run when user completes the Survey',
# label => $i18n->get('editForm workflowIdAddEntry label'),
# hoverHelp => $i18n->get('editForm workflowIdAddEntry description'),
none => 1,
},
quizModeSummary => {
@ -207,13 +205,16 @@ sub definition {
tab => 'properties',
label => $i18n->get('Quiz mode summaries'),
hoverHelp => $i18n->get('Quiz mode summaries help'),
}
},
allowBackBtn => {
fieldType => 'yesNo',
defaultValue => 0,
tab => 'properties',
label => $i18n->get('Allow back button'),
hoverHelp => $i18n->get('Allow back button help'),
},
);
#my $defaultMC = $session->
#%properties = ();
push @{$definition}, {
assetName => $i18n->get('assetName'),
icon => 'survey.gif',
@ -800,7 +801,7 @@ sub www_loadSurvey {
elsif ( $lastType eq 'question' ) {
$q = 1;
}
$html .= "<li id='$scount' class='section'>S" . ( $scount + 1 ) . ": $_->{text}<\/li><br>\n";
$html .= "<li id='$scount' class='section'>S" . ( $scount + 1 ) . ": $_->{text}<\/li>\n";
push( @ids, $scount );
}
elsif ( $_->{type} eq 'question' ) {
@ -808,7 +809,7 @@ sub www_loadSurvey {
if ( $lastType eq 'answer' ) {
$a = 1;
}
$html .= "<li id='$scount-$qcount' class='question'>Q" . ( $qcount + 1 ) . ": $_->{text}<\/li><br>\n";
$html .= "<li id='$scount-$qcount' class='question'>Q" . ( $qcount + 1 ) . ": $_->{text}<\/li>\n";
push @ids, "$scount-$qcount";
$lastType = 'question';
$acount = -1;
@ -818,12 +819,12 @@ sub www_loadSurvey {
$html
.= "<li id='$scount-$qcount-$acount' class='answer'>A"
. ( $acount + 1 )
. ": $_->{text}<\/li><br>\n";
. ": $_->{text}<\/li>\n";
push @ids, "$scount-$qcount-$acount";
$lastType = 'answer';
}
}
$html = "<ul class='draglist'>$html</ul>";
my $warnings = $self->surveyJSON->validateSurvey();
my $return = {
@ -1154,6 +1155,41 @@ sub www_submitQuestions {
}
#-------------------------------------------------------------------
=head2 www_goBack
Handles the Survey back button
=cut
sub www_goBack {
my $self = shift;
if ( !$self->canTakeSurvey() ) {
$self->session->log->debug('canTakeSurvey false, surveyEnd');
return $self->surveyEnd();
}
my $responseId = $self->responseId();
if ( !$responseId ) {
$self->session->log->debug('No response id, surveyEnd');
return $self->surveyEnd();
}
if ( !$self->get('allowBackBtn') ) {
$self->session->log->debug('allowBackBtn false, delegating to www_loadQuestions');
return $self->www_loadQuestions();
}
$self->responseJSON->pop;
$self->persistResponseJSON;
return $self->www_loadQuestions();
}
#-------------------------------------------------------------------
=head2 getSummary
@ -1305,15 +1341,8 @@ Sends the processed template and questions structure to the client
sub prepareShowSurveyTemplate {
my ( $self, $section, $questions ) = @_;
# my %multipleChoice = (
# 'Multiple Choice', 1, 'Gender', 1, 'Yes/No', 1, 'True/False', 1, 'Ideology', 1,
# 'Race', 1, 'Party', 1, 'Education', 1, 'Scale', 1, 'Agree/Disagree', 1,
# 'Oppose/Support', 1, 'Importance', 1, 'Likelihood', 1, 'Certainty', 1, 'Satisfaction', 1,
# 'Confidence', 1, 'Effectiveness', 1, 'Concern', 1, 'Risk', 1, 'Threat', 1,
# 'Security', 1
# );
my %textArea = ( 'TextArea', 1 );
my %text = ( 'Text', 1, 'Email', 1, 'Phone Number', 1, 'Text Date', 1, 'Currency', 1 );
my %text = ( 'Text', 1, 'Email', 1, 'Phone Number', 1, 'Text Date', 1, 'Currency', 1, 'Number', 1 );
my %slider = ( 'Slider', 1, 'Dual Slider - Range', 1, 'Multi Slider - Allocate', 1 );
my %dateType = ( 'Date', 1, 'Date Range', 1 );
my %dateShort = ( 'Year Month', 1 );
@ -1379,6 +1408,7 @@ sub prepareShowSurveyTemplate {
if(scalar @{$questions} == ($section->{totalQuestions} - $section->{questionsAnswered})){
$section->{isLastPage} = 1
}
$section->{allowBackBtn} = $self->get('allowBackBtn');
my $out = $self->processTemplate( $section, $self->get('surveyQuestionsId') );

View file

@ -54,7 +54,7 @@ sub value {
if (my $other_instance = $other_instances->{$asset_spec}) {
my $values = $other_instance->{values};
my $value = $values->{$key};
$session->log->debug("[$asset_spec, $key] resolves to [$value]");
$session->log->debug("value($asset_spec, $key) resolves to [$value]");
return $value;
} else {
# Throw an exception, triggering run() to resolve the external reference and re-run
@ -63,7 +63,7 @@ sub value {
}
my $key = shift;
my $value = $values->{$key};
$session->log->debug("[$key] resolves to [$value]");
$session->log->debug("value($key) resolves to [$value]");
return $value; # scalar variable, so no need to clone
}
@ -85,7 +85,7 @@ sub score {
if (my $other_instance = $other_instances->{$asset_spec}) {
my $scores = $other_instance->{scores};
my $score = $scores->{$key};
$session->log->debug("[$asset_spec, $key] resolves to [$score]");
$session->log->debug("score($asset_spec, $key) resolves to [$score]");
return $score;
} else {
# Throw an exception, triggering run() to resolve the external reference and re-run
@ -94,7 +94,7 @@ sub score {
}
my $key = shift;
my $score = $scores->{$key};
$session->log->debug("[$key] resolves to [$score]");
$session->log->debug("score($key) resolves to [$score]");
return $score; # scalar variable, so no need to clone
}

View file

@ -39,59 +39,6 @@ number of questions answered (L<"questionsAnswered">) and the Survey start time
This package is not intended to be used by any other Asset in WebGUI.
=head2 surveyOrder
This data strucutre is an array (reference) of Survey addresses (see
L<WebGUI::Asset::Wobject::Survey::SurveyJSON/Address Parameter>), stored in the order
in which items are presented to the user.
By making use of L<WebGUI::Asset::Wobject::Survey::SurveyJSON> methods which expect address params as
arguments, you can access Section/Question/Answer items in order by iterating over surveyOrder.
For example:
# Access sections in order..
for my $address (@{ $self->surveyOrder }) {
my $section = $self->survey->section( $address );
# etc..
}
In general, the surveyOrder data structure looks like:
[ $sectionIndex, $questionIndex, [ $answerIndex1, $answerIndex2, ....]
There is one array element for every section and address in the survey. If there are
no questions, or no addresses, those array elements will not be present.
=head2 responses
This data structure stores a snapshot of all question responses. Both question data and answer data
is stored in this hash reference.
Questions keys are constructed by hypenating the relevant L<"sIndex"> and L<"qIndex">.
Answer keys are constructed by hypenating the relevant L<"sIndex">, L<"qIndex"> and L<aIndex|"aIndexes">.
Question entries only contain a comment field:
{
...
questionId => {
comment => "question comment",
}
...
}
Answers entries contain: value (the recorded value), time and comment fields.
{
...
answerId => {
value => "recorded answer value",
time => time(),
comment => "answer comment",
},
...
}
=cut
use strict;
@ -252,7 +199,7 @@ sub hasTimedOut{
=head2 lastResponse ([ $responseIndex ])
Mutator. The lastResponse property represents the index of the most recent surveyOrder entry shown.
Mutator. The lastResponse property represents the surveyOrder index of the most recent item shown.
This method returns (and optionally sets) the value of lastResponse.
@ -325,8 +272,32 @@ sub startTime {
=head2 surveyOrder
Accessor for surveyOrder (see L<"surveyOrder">).
Initialized on first access via L<"initSurveyOrder">.
Accessor. Initialized on first access via L<"initSurveyOrder">.
This data strucutre represents the list of items that are shown to the user, in the order
that they will be shown (ignoring jumps and jump expressions).
Typically each item will correspond to a question, and contains enough information to look
up both the corresponding section and all contained answers (if any).
Empty sections also appear in the list.
Each element of the array is an address, similar in structure to
L<WebGUI::Asset::Wobject::Survey::SurveyJSON/Address Parameter>,
except that instead of an answerIndex in the third slot, we have a sub-array of all contained answer indicies.
[ $sectionIndex, $questionIndex, [ $answerIndex1, $answerIndex2, ....]
By making use of L<WebGUI::Asset::Wobject::Survey::SurveyJSON> methods which expect address params as
arguments, you can access Section/Question/Answer items in order by iterating over surveyOrder.
For example:
# Access sections in order..
for my $address (@{ $self->surveyOrder }) {
my $section = $self->survey->section( $address );
# etc..
}
=cut
@ -489,7 +460,6 @@ sub recordResponses {
$gotoExpression = $section->{gotoExpression};
}
# Handle empty Section..
if ( !@questions ) {
# No questions to process, so increment lastResponse and return
@ -526,9 +496,22 @@ sub recordResponses {
# Pluck the values out of the responses hash that we want to record..
my $submittedAnswerResponse = $submittedResponses->{ $answer->{id} };
my $submittedAnswerComment = $submittedResponses->{ $answer->{id} . 'comment' };
my $submittedAnswerVerbatim = $submittedResponses->{ $answer->{id} . 'verbatim' };
# Proceed if we're satisfied that the submitted answer response is valid..
if ( defined $submittedAnswerResponse && $submittedAnswerResponse =~ /\S/ ) {
#Validate answers met question criteria
if($question->{questionType} eq 'Number'){
if($answer->{max} =~ /\d/ and $submittedAnswerResponse > $answer->{max}){
next;
}elsif($answer->{min} =~ /\d/ and $submittedAnswerResponse < $answer->{min}){
next;
}elsif($answer->{step} =~ /\d/ and $submittedAnswerResponse % $answer->{step} != 0){
next;
}
}
$aAnswered = 1;
# Now, decide what to record. For multi-choice questions, use recordedAnswer.
@ -537,9 +520,10 @@ sub recordResponses {
= $knownTypes{ $question->{questionType} }
? $submittedAnswerResponse
: $answer->{recordedAnswer};
$self->responses->{ $answer->{id} }->{time} = time;
$self->responses->{ $answer->{id} }->{comment} = $submittedAnswerComment;
$self->responses->{ $answer->{id} }->{verbatim} = $answer->{verbatim} ? $submittedAnswerVerbatim : undef;
$self->responses->{ $answer->{id} }->{time} = time;
$self->responses->{ $answer->{id} }->{comment} = $submittedAnswerComment;
# Handle terminal Answers..
if ( $answer->{terminal} ) {
@ -609,6 +593,23 @@ A variable name to match against all section and question variable names.
sub processGoto {
my $self = shift;
my ($goto) = validate_pos(@_, {type => SCALAR});
if ($goto eq 'NEXT_SECTION') {
$self->session->log->debug("NEXT_SECTION jump target encountered");
my $lastResponseSectionIndex = $self->lastResponseSectionIndex;
# Increment lastRepsonse until nextResponseSectionIndex moves
while ($self->nextResponseSectionIndex == $lastResponseSectionIndex) {
$self->lastResponse( $self->lastResponse + 1);
}
return;
}
if ($goto eq 'END_SURVEY') {
$self->session->log->debug("END_SURVEY jump target encountered");
$self->lastResponse( scalar( @{ $self->surveyOrder} ) - 1 );
return;
}
# Iterate over items in order..
my $itemIndex = 0;
@ -714,17 +715,31 @@ sub recordedResponses{
#-------------------------------------------------------------------
=head2 responseValuesByVariableName
=head2 responseValuesByVariableName ( $options )
Returns a lookup table to question variable names and recorded response values.
Only questions with a defined variable name set are included. Values come from
the L<responses> hash.
=head3 options
The following options are supported:
=over 3
=item * useText
For multiple choice questions, use the answer text instead of the recorded value
(useful for doing [[var]] text substitution
=back
=cut
sub responseValuesByVariableName {
my $self = shift;
my %options = validate(@_, { useText => 0 });
my %lookup;
while (my ($address, $response) = each %{$self->responses}) {
@ -742,14 +757,23 @@ sub responseValuesByVariableName {
# Filter out questions without defined variable names
next if !$question || !defined $question->{variable};
#Test if question is a multiple choice type so we can use the answer text instead
my $answerText;
if($self->survey->getMultiChoiceBundle($question->{questionType})){
$answerText = $self->survey->answer([@address])->{text};
my $value = $response->{value};
if ($options{useText}) {
# Test if question is a multiple choice type so we can use the answer text instead
if($self->survey->getMultiChoiceBundle($question->{questionType})){
my $answer = $self->survey->answer([@address]);
my $answerText = $answer->{text};
# For verbatim mc answers, combine answer text and recorded value
if ($answer->{verbatim}) {
$answerText = "$answerText - \"$response->{verbatim}\"";
}
$value = $answerText ? $answerText : $value;
}
}
# Add variable => value to our hash
$lookup{$question->{variable}} = $answerText ? $answerText : $response->{value};
$lookup{$question->{variable}} = $value;
}
return \%lookup;
}
@ -885,7 +909,7 @@ sub nextQuestions {
my $questionsPerPage = $self->survey->section( [ $self->nextResponseSectionIndex ] )->{questionsPerPage};
# Get all of the existing question responses (so that we can do Section and Question [[var]] replacements
my $responseValuesByVariableName = $self->responseValuesByVariableName();
my $responseValuesByVariableName = $self->responseValuesByVariableName( { useText => 1 } );
# Do text replacement
$section->{text} = $self->getTemplatedText($section->{text}, $responseValuesByVariableName);
@ -1230,11 +1254,32 @@ sub response {
return $self->{_response};
}
#-------------------------------------------------------------------
=head2 responses
Mutator for the L<"responses"> property.
Mutator. Note, this is an unsafe reference.
Note, this is an unsafe reference.
This data structure stores a snapshot of all question responses. Both question data and answer data
is stored in this hash reference.
Questions keys are constructed by hypenating the relevant L<"sIndex"> and L<"qIndex">.
Answer keys are constructed by hypenating the relevant L<"sIndex">, L<"qIndex"> and L<aIndex|"aIndexes">.
{
# Question entries only contain a comment field, e.g.
'0-0' => {
comment => "question comment",
},
# ...
# Answers entries contain: value (the recorded value), time and comment fields.
'0-0-0' => {
value => "recorded answer value",
time => time(),
comment => "answer comment",
},
# ...
}
=cut
@ -1247,6 +1292,62 @@ sub responses {
return $self->response->{responses};
}
=head2 pop
=cut
sub pop {
my $self = shift;
my %responses = %{ $self->responses };
# Iterate over responses first time to determine time of most recent response(s)
my $lastResponseTime;
for my $r ( values %responses ) {
if ( $r->{time} ) {
$lastResponseTime
= !$lastResponseTime || $r->{time} > $lastResponseTime
? $r->{time}
: $lastResponseTime
;
}
}
return unless $lastResponseTime;
my $popped;
my $poppedQuestions;
# Iterate again, removing most recent responses
while (my ($address, $r) = each %responses ) {
if ( $r->{time} == $lastResponseTime) {
$popped->{$address} = $r;
delete $self->responses->{$address};
# Remove associated question/comment entry
my ($sIndex, $qIndex, $aIndex) = split /-/, $address;
my $qAddress = "$sIndex-$qIndex";
$popped->{$qAddress} = $responses{$qAddress};
delete $self->responses->{$qAddress};
# while we're here, build lookup table of popped question ids
$poppedQuestions->{$qAddress} = 1;
}
}
# Now, nextResponse should be set to index of the first popped question we can find in surveyOrder
my $nextResponse = 0;
for my $address (@{ $self->surveyOrder }) {
my $questionId = "$address->[0]-$address->[1]";
if ($poppedQuestions->{$questionId} ) {
$self->session->log->debug("setting nextResponse to $nextResponse");
$self->nextResponse($nextResponse);
last;
}
$nextResponse++;
}
return $popped;
}
#-------------------------------------------------------------------
=head2 survey

View file

@ -117,6 +117,7 @@ sub loadTypes {
'Slider',
'Currency',
'Email',
'Number',
'Phone Number',
'Text',
'Text Date',
@ -413,16 +414,17 @@ Generates the list of valid goto targets
sub getGotoTargets {
my $self = shift;
# Valid goto targets are all of the section variable names..
my @section_vars = map {$_->{variable}} @{$self->sections};
# Valid goto targets are all of the non-empty section variable names..
my @section_vars = grep { $_ ne q{} } map {$_->{variable}} @{$self->sections};
# ..and all of the question variable names..
my @question_vars = map {$_->{variable}} @{$self->questions};
# ..and all of the non-empty question variable names..
my @question_vars = grep { $_ ne q{} } map {$_->{variable}} @{$self->questions};
# ..excluding the ones that are empty
my @grep = grep { $_ ne q{} } (@section_vars, @question_vars);
return \@grep;
#return grep { $_ ne q{} } (@section_vars, @question_vars);
# ..plus some special vars
my @special_vars = qw(NEXT_SECTION END_SURVEY);
# ..all combined
return [ @section_vars, @question_vars, @special_vars ];
}
=head2 getSectionEditVars ( $address )
@ -665,16 +667,32 @@ sub update {
}
}
$self->_handleSpecialAnswerUpdates($address,$properties);
# Update $object with all of the data in $properties
while (my ($key, $value) = each %{$properties}) {
if (defined $value) {
$object->{$key} = $value;
}
}
return;
}
sub _handleSpecialAnswerUpdates{
my $self = shift;
my $address = shift;
my $properties = shift;
my $question = $self->question($address);
if($question->{questionType} =~ /^Slider|Multi Slider - Allocate|Dual Slider - Range$/){
for my $answer(@{$self->answers($address)}){
$answer->{max} = $properties->{max};
$answer->{min} = $properties->{min};
$answer->{step} = $properties->{step};
}
}
}
=head2 insertObject ( $object, $address )
Rearrange existing objects in the current data structure.
@ -1036,10 +1054,9 @@ sub addAnswersToQuestion {
# when updating answer text without causing side-effects for the caller's $address
my @address_copy = @{$address};
for my $answer_index ( 0 .. $#{$answers} ) {
for my $answer (@$answers) {
# Add a new answer to question
push @{ $self->question( \@address_copy )->{answers} }, $answers->[$answer_index];
push @{ $self->question( \@address_copy )->{answers} }, $answer;
}
return;

View file

@ -153,7 +153,7 @@ sub generateFeed {
# care of any encoding specified in the XML prolog
utf8::downgrade($value, 1);
eval {
my $singleFeed = XML::FeedPP->new($value, utf8_flag => 1);
my $singleFeed = XML::FeedPP->new($value, utf8_flag => 1, -type => 'string');
$feed->merge($singleFeed);
};
if ($@) {

View file

@ -292,19 +292,44 @@ sub duplicate {
my $assetId = $self->get("assetId");
my $fields;
my $otherThingFields = $db->buildHashRefOfHashRefs(
"select fieldType, fieldId, right(fieldType,22) as otherThingId, fieldInOtherThingId from Thingy_fields
where fieldType like 'otherThing_%' and assetId = ?",
[$assetId],'fieldInOtherThingId'
);
my $things = $self->getThings;
while ( my $thing = $things->hashRef) {
my $oldThingId = $thing->{thingId};
my $newThingId = $newAsset->addThing($thing,0);
my $oldSortBy = $thing->{sortBy};
my $oldThingId = $thing->{thingId};
my $newThingId = $newAsset->addThing($thing,0);
$fields = $db->buildArrayRefOfHashRefs('select * from Thingy_fields where assetId=? and thingId=?'
,[$assetId,$oldThingId]);
foreach my $field (@$fields) {
# set thingId to newly created thing's id.
$field->{thingId} = $newThingId;
my $originalFieldId = $field->{fieldId};
$newAsset->addField($field,0);
my $newFieldId = $newAsset->addField($field,0);
if ($originalFieldId eq $oldSortBy){
$self->session->db->write( "update Thingy_things set sortBy = ? where thingId = ?",
[ $newFieldId, $newThingId ] );
}
if ($otherThingFields->{$originalFieldId}){
$otherThingFields->{$originalFieldId}->{newFieldType} = 'otherThing_'.$newThingId;
$otherThingFields->{$originalFieldId}->{newFieldId} = $newFieldId;
}
}
}
foreach my $otherThingField (keys %$otherThingFields){
$db->write('update Thingy_fields set fieldType = ?, fieldInOtherThingId = ?
where fieldInOtherThingId = ? and assetId = ?',
[$otherThingFields->{$otherThingField}->{newFieldType},
$otherThingFields->{$otherThingField}->{newFieldId},
$otherThingFields->{$otherThingField}->{fieldInOtherThingId}, $newAsset->get('assetId')]);
}
return $newAsset;
}

View file

@ -61,7 +61,7 @@ sub getAlphabetSearchLoop {
my $htmlEncodedLetter = encode_entities($letter);
my $searchURL = "?searchExact_".$fieldName."=".$letter."%25";
my $hasResults;
my $users = $self->session->db->read("select userId from userProfileData where lastName like '".$letter."%'");
my $users = $self->session->db->read("select userId from userProfileData where `$fieldName` like '".$letter."%'");
while (my $user = $users->hashRef){
my $showGroupId = $self->get("showGroupId");
if ($showGroupId eq '0' || ($showGroupId && $self->isInGroup($showGroupId,$user->{userId}))){
@ -535,7 +535,7 @@ sub view {
my $users = $p->getPageData($paginatePage);
foreach my $user (@$users){
my $userObject = WebGUI::User->new($self->session,$user->{userId});
if ($self->get('overridePublicProfile') || $userObject->profileIsViewable($userObject)){
if ($self->get('overridePublicProfile') || $userObject->profileIsViewable()) {
my (@profileFieldValues);
my %userProperties;
foreach my $profileField (@profileFields){