976 lines
28 KiB
Perl
976 lines
28 KiB
Perl
package WebGUI::ProfileField;
|
|
|
|
|
|
=head1 LEGAL
|
|
|
|
-------------------------------------------------------------------
|
|
WebGUI is Copyright 2001-2009 Plain Black Corporation.
|
|
-------------------------------------------------------------------
|
|
Please read the legal notices (docs/legal.txt) and the license
|
|
(docs/license.txt) that came with this distribution before using
|
|
this software.
|
|
-------------------------------------------------------------------
|
|
http://www.plainblack.com info@plainblack.com
|
|
-------------------------------------------------------------------
|
|
|
|
=cut
|
|
|
|
use strict;
|
|
use WebGUI::ProfileCategory;
|
|
use WebGUI::Form::DynamicField;
|
|
use WebGUI::Operation::Shared;
|
|
use WebGUI::HTML;
|
|
use WebGUI::User;
|
|
use WebGUI::Utility;
|
|
use WebGUI::Pluggable;
|
|
|
|
=head1 NAME
|
|
|
|
Package WebGUI::ProfileField
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
This package is used to manipulate the schema of the user profiling system. If you wish to manipulate the profile data for an individual user look at WebGUI::User.
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
use WebGUI::ProfileField;
|
|
|
|
=head1 METHODS
|
|
|
|
These methods are available from this package:
|
|
|
|
=cut
|
|
|
|
#-------------------------------------------------------------------
|
|
sub _reorderFields {
|
|
my $self = shift;
|
|
my $category = shift;
|
|
my ($sth, $i, $id);
|
|
$sth = $self->session->db->read("select fieldName from userProfileField where profileCategoryId=".$self->session->db->quote($category)." order by sequenceNumber");
|
|
while (($id) = $sth->array) {
|
|
$i++;
|
|
$self->session->db->write("update userProfileField set sequenceNumber='$i' where fieldName=".$self->session->db->quote($id));
|
|
}
|
|
$sth->finish;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 isReservedFieldName ( fieldName )
|
|
|
|
Return true iff fieldName is reserved and therefore not usable as a profile field name.
|
|
|
|
=cut
|
|
|
|
sub isReservedFieldName {
|
|
my $class = shift;
|
|
my $fieldName = shift;
|
|
return isIn($fieldName, qw/userId shop specialState func op wg_privacySettings username authMethod dateCreated lastUpdated karma status referringAffiliate friendsGroup/);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 fixDataColumnTypes ( session )
|
|
|
|
Checks the column types of userProfileData against the form fields that they use. If they
|
|
differ then they are updated to match for the form field. This is to account for bugs in
|
|
this module, and changes in Form types.
|
|
|
|
This is a class method.
|
|
|
|
=head3 session
|
|
|
|
A reference to the current session.
|
|
|
|
=cut
|
|
|
|
sub fixDataColumnTypes {
|
|
my $class = shift;
|
|
my $session = shift;
|
|
|
|
my $dbh = $session->db->dbh;
|
|
|
|
my $fields = WebGUI::ProfileField->getFields($session);
|
|
foreach my $field ( @{ $fields } ) {
|
|
my $columnInfo = $dbh->column_info(undef, undef, 'userProfileData', $field->getId)->fetchrow_hashref();
|
|
my $formField = $field->formField(undef, undef, undef, undef, undef, 'returnObject');
|
|
my $columnType = $formField->getDatabaseFieldType();
|
|
$columnType =~ s/\s+\w+$//;
|
|
if ($columnType eq 'BOOLEAN') {
|
|
$columnType = 'TINYINT'; ##Alias for INT(1)
|
|
}
|
|
my $actualType = $columnInfo->{TYPE_NAME};
|
|
if ($columnType =~ m/\(\d+\)/) {
|
|
$actualType = sprintf('%s(%s)', $actualType, $columnInfo->{COLUMN_SIZE});
|
|
}
|
|
if ($actualType ne $columnType) {
|
|
$session->log->warn("Updating ".$field->getId." from $actualType to $columnType");
|
|
$session->db->write('ALTER TABLE userProfileData MODIFY COLUMN '.$dbh->quote_identifier($field->getId).' '.$columnType);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 create ( session, fieldName [, properties, categoryId] )
|
|
|
|
Add a new field to the system. Returns a WebGUI::ProfileField object if created successfully, otherwise returns undef.
|
|
|
|
=head3 session
|
|
|
|
A reference to the current session.
|
|
|
|
=head3 fieldName
|
|
|
|
The unique name of this field.
|
|
|
|
=head3 properties
|
|
|
|
A hash reference containing the properties of this field. See the set() method for details.
|
|
|
|
=head3 categoryId
|
|
|
|
The unique id of the category to assign this field to. Defaults to "1" (misc).
|
|
|
|
=cut
|
|
|
|
sub create {
|
|
my $class = shift;
|
|
my $session = shift;
|
|
my $fieldName = shift;
|
|
my $properties = shift;
|
|
my $categoryId = shift || "1";
|
|
|
|
my $db = $session->db;
|
|
|
|
### Check data
|
|
# Check if the field already exists
|
|
$properties->{fieldType} ||= "ReadOnly";
|
|
return undef if $class->exists($session,$fieldName);
|
|
return undef if $class->isReservedFieldName($fieldName);
|
|
return undef if $fieldName =~ m{\s};
|
|
|
|
### Data okay, create the field
|
|
# Add the record
|
|
my $id = $session->db->setRow("userProfileField","fieldName",
|
|
{
|
|
fieldName=>"new",
|
|
fieldType => $properties->{fieldType},
|
|
},
|
|
$fieldName
|
|
);
|
|
my $self = $class->new($session,$id);
|
|
|
|
# Get the field's data type
|
|
my $formClass = $self->getFormControlClass;
|
|
eval { WebGUI::Pluggable::load($formClass) };
|
|
my $dbDataType = $formClass->getDatabaseFieldType;
|
|
|
|
# Add the column to the userProfileData table
|
|
$db->write(
|
|
"ALTER TABLE userProfileData ADD " . $db->dbh->quote_identifier($id)
|
|
. $dbDataType
|
|
);
|
|
|
|
$self->setCategory($categoryId);
|
|
$self->set($properties);
|
|
|
|
return $self;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 delete ( )
|
|
|
|
Deletes this field and all user data attached to it.
|
|
|
|
=cut
|
|
|
|
sub delete {
|
|
my $self = shift;
|
|
my $db = $self->session->db;
|
|
|
|
# Remove the column from the userProfileData table
|
|
$db->write("ALTER TABLE userProfileData DROP " . $db->dbh->quote_identifier($self->getId));
|
|
|
|
# Remove the record
|
|
$db->deleteRow("userProfileField","fieldName",$self->getId);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 exists ( session, fieldName )
|
|
|
|
Class method that returns true if a field with the given name already
|
|
exists. The first argument is a WebGUI::Session object. C<fieldName> is
|
|
the field name to check
|
|
|
|
=cut
|
|
|
|
sub exists {
|
|
my ( $class, $session, $fieldName ) = @_;
|
|
|
|
return 1 if $session->db->quickScalar(
|
|
"SELECT COUNT(*) FROM userProfileField WHERE fieldName=?",
|
|
[$fieldName]
|
|
);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 formProperties ( hashRef )
|
|
|
|
Get a hashref of properties to give to a WebGUI::Form::Control. The
|
|
hashRef argument allows you to specify some additional items (such as
|
|
a value) that are not known by the ProfileField.
|
|
|
|
=cut
|
|
|
|
sub formProperties {
|
|
my $self = shift;
|
|
my $properties = shift || {};
|
|
|
|
# Make a copy of the properties so we don't clobber them
|
|
my %properties = %{$properties};
|
|
|
|
$properties{ label } = $self->getLabel unless $properties->{label};
|
|
$properties{ fieldType } = $self->get("fieldType");
|
|
$properties{ name } = $self->getId;
|
|
my $values
|
|
= WebGUI::Operation::Shared::secureEval($self->session,$self->get("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 = {};
|
|
}
|
|
my $orderedValues = {};
|
|
tie %{$orderedValues}, 'Tie::IxHash';
|
|
for my $ov (sort keys %{$values}) {
|
|
$orderedValues->{$ov} = $values->{$ov};
|
|
}
|
|
$properties{ options } = $orderedValues;
|
|
$properties{ forceImageOnly } = $self->get("forceImageOnly");
|
|
$properties{ dataDefault } = $self->get("dataDefault");
|
|
$properties{ extras } = $self->get("extras");
|
|
return \%properties;
|
|
}
|
|
|
|
#-- This is here in case people did not understand that _ means private
|
|
#-- this can be removed when the API is unlocked.
|
|
sub _formProperties { my $self = shift; return $self->formProperties(@_); }
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 formField ( [ formProperties, withWrapper, userObject, skipDefault, assignedValue ] )
|
|
|
|
Returns an HTMLified form field element.
|
|
|
|
=head3 formProperties
|
|
|
|
Optionally pass in a list of properties to override the default properties of any form element. You cannot override the pieces specified as part of the form field like field type, label, options, etc.
|
|
|
|
=head3 withWrapper
|
|
|
|
An integer indicating whether to return just the field's form input, or the field with a table label wrapper (1), or just the field value (2).
|
|
|
|
=head3 userObject
|
|
|
|
A WebGUI::User object reference to use instead of the currently logged in user.
|
|
|
|
=head3 skipDefault
|
|
|
|
If true, this causes the default value set up for the form field to be ignored. In choosing default,
|
|
skipDefault has the highest priority.
|
|
|
|
=head3 assignedValue
|
|
|
|
If assignedValue is defined, it will be used to override the default value set up for the
|
|
form. assignedValue has the next highest priority.
|
|
|
|
=head3 returnObject
|
|
|
|
If true, it returns a WebGUI::Form object, instead of returning HTML.
|
|
|
|
=head3 useFieldDefault
|
|
|
|
If true, it uses the default setup for the ProfileField, instead of the user's default. useFieldDefault
|
|
has the lowest priority.
|
|
|
|
=cut
|
|
|
|
# FIXME This would be better if it returned an OBJECT not the HTML
|
|
# TODO add a toHtml sub to take the place of this sub and a getFormControl
|
|
# And refactor to not require all these arguments HERE but rather in the
|
|
# constructor or something...
|
|
sub formField {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $properties = $self->formProperties(shift);
|
|
my $withWrapper = shift;
|
|
my $u = shift || $session->user;
|
|
my $skipDefault = shift;
|
|
my $assignedValue = shift;
|
|
my $returnObject = shift;
|
|
my $useFieldDefault = shift;
|
|
|
|
if ($skipDefault) {
|
|
$properties->{value} = undef;
|
|
}
|
|
elsif (defined $assignedValue) {
|
|
$properties->{value} = $assignedValue;
|
|
}
|
|
elsif ($useFieldDefault) {
|
|
$properties->{value} = WebGUI::Operation::Shared::secureEval($session,$properties->{dataDefault});
|
|
}
|
|
else {
|
|
# start with specified (or current) user's data. previous data needed by some form types as well (file).
|
|
$properties->{value} = $u->profileField($self->getId);
|
|
#If the fieldId is actually found in the request, try to process the form
|
|
if ($session->form->param($self->getId)) {
|
|
$properties->{value} = $self->formProcess($u);
|
|
}
|
|
#If no value is set, go with the default value
|
|
if(!defined $properties->{value}) {
|
|
$properties->{value} = WebGUI::Operation::Shared::secureEval($session,$properties->{dataDefault});
|
|
}
|
|
if ($self->getId eq "language") {
|
|
if ($self->session->scratch->getLanguageOverride) {
|
|
$properties->{value} = $self->session->scratch->getLanguageOverride;
|
|
}
|
|
}
|
|
}
|
|
my $form = WebGUI::Form::DynamicField->new($session,%{$properties});
|
|
return $form if $returnObject;
|
|
if ($withWrapper == 1) {
|
|
return $form->toHtmlWithWrapper;
|
|
} elsif ($withWrapper == 2) {
|
|
return $form->getValueAsHtml;
|
|
} else {
|
|
return $form->toHtml;
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 formProcess ( [ user ] )
|
|
|
|
Returns the value retrieved from a form post.
|
|
|
|
=head3 user
|
|
|
|
Optional user object to process properties for. If no user object is passed
|
|
in the current user will be used.
|
|
|
|
=cut
|
|
|
|
sub formProcess {
|
|
my $self = shift;
|
|
my $u = shift || $self->session->user;
|
|
my $userId = $u->userId;
|
|
|
|
my $properties = $self->formProperties({value => $u->profileField($self->getId)});
|
|
my $result = $self->session->form->process(
|
|
$self->getId,
|
|
$self->get("fieldType"),
|
|
WebGUI::Operation::Shared::secureEval($self->session,$self->get("dataDefault")),
|
|
$properties
|
|
);
|
|
if (ref $result eq "ARRAY") {
|
|
my @results = @$result;
|
|
for (my $count=0;$count<scalar(@results);$count++) {
|
|
$results[$count] = WebGUI::HTML::filter($results[$count], "javascript");
|
|
}
|
|
$result = \@results;
|
|
} else {
|
|
$result = WebGUI::HTML::filter($result, "javascript");
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 get ( [ property ] )
|
|
|
|
Returns a hash reference of all the properties of the field.
|
|
|
|
=head3 property
|
|
|
|
If specified, the value of an individual property is returned.
|
|
|
|
=cut
|
|
|
|
sub get {
|
|
my $self = shift;
|
|
my $propertyName = shift;
|
|
if (defined $propertyName) {
|
|
return $self->{_properties}{$propertyName};
|
|
}
|
|
return $self->{_properties};
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getCategory ( )
|
|
|
|
Returns a WebGUI::ProfileCategory object for the category that this profile field belongs to.
|
|
|
|
=cut
|
|
|
|
sub getCategory {
|
|
my $self = shift;
|
|
unless ($self->{_category}) {
|
|
$self->{_category} = WebGUI::ProfileCategory->new($self->session,$self->get("profileCategoryId"));
|
|
}
|
|
return $self->{_category};
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getId ( )
|
|
|
|
Returns the unique fieldName for this field.
|
|
|
|
B<NOTE:> This method is named getId for consistency amongst other packages even though technically profile fields have field names rather than ids.
|
|
|
|
=cut
|
|
|
|
sub getId {
|
|
my $self = shift;
|
|
return $self->get("fieldName");
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getExtras ()
|
|
|
|
Returns the value of the extras property for this field.
|
|
|
|
=cut
|
|
|
|
sub getExtras {
|
|
my $self = shift;
|
|
return $self->get('extras');
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getLabel ( )
|
|
|
|
Returns the eval'd label for this field.
|
|
|
|
=cut
|
|
|
|
sub getLabel {
|
|
my $self = shift;
|
|
return WebGUI::Operation::Shared::secureEval($self->session,$self->get("label"));
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
sub _listFieldsWhere {
|
|
my $class = shift;
|
|
my $session = shift;
|
|
my $whereClause = shift;
|
|
return [map{$class->new($session, $_)} $session->db->buildArray(<<"SQL")];
|
|
SELECT f.fieldName
|
|
FROM userProfileField AS f
|
|
LEFT JOIN userProfileCategory AS c ON f.profileCategoryId = c.profileCategoryId
|
|
WHERE $whereClause
|
|
ORDER BY c.sequenceNumber, f.sequenceNumber
|
|
SQL
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getEditableFields ( session )
|
|
|
|
Returns an array reference of WebGUI::ProfileField objects that are marked "editable" or "required". This is a class method.
|
|
|
|
=cut
|
|
|
|
sub getEditableFields {
|
|
my $class = shift;
|
|
my $session = shift;
|
|
return $class->_listFieldsWhere($session, "c.editable=1 AND (f.required = 1 OR f.editable = 1 OR f.showAtRegistration = 1)");
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getFields ( session )
|
|
|
|
Returns an array reference of all WebGUI::ProfileField objects. This is a class method.
|
|
|
|
=cut
|
|
|
|
sub getFields {
|
|
my $class = shift;
|
|
my $session = shift;
|
|
return $class->_listFieldsWhere($session, "1");
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getFormControlClass
|
|
|
|
Returns the full class name of the form control for this profile field.
|
|
|
|
=cut
|
|
|
|
sub getFormControlClass {
|
|
my $self = shift;
|
|
return "WebGUI::Form::" . ucfirst $self->get("fieldType");
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getPrivacyOptions ( session )
|
|
|
|
Class method which returns a hash reference containing the privacy options available.
|
|
|
|
=cut
|
|
|
|
sub getPrivacyOptions {
|
|
my $class = shift;
|
|
my $session = shift;
|
|
my $i18n = WebGUI::International->new($session);
|
|
tie my %hash, "Tie::IxHash";
|
|
%hash = (
|
|
all => $i18n->get('user profile field private message allow label'),
|
|
friends => $i18n->get('user profile field private message friends only label'),
|
|
none => $i18n->get('user profile field private message allow none label'),
|
|
);
|
|
return \%hash;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getRequiredFields ( session )
|
|
|
|
Returns an array reference of WebGUI::ProfileField objects that are marked "required". This is a class method.
|
|
|
|
=cut
|
|
|
|
sub getRequiredFields {
|
|
my $class = shift;
|
|
my $session = shift;
|
|
return $class->_listFieldsWhere($session, "f.required = 1");
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getRegistrationFields ( session )
|
|
|
|
Returns an array reference of profile field objects to use during anonymous registration. Class method.
|
|
|
|
=cut
|
|
|
|
sub getRegistrationFields {
|
|
my $class = shift;
|
|
my $session = shift;
|
|
return $class->_listFieldsWhere($session, "f.showAtRegistration = 1");
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getPasswordRecoveryFields ( session )
|
|
|
|
Returns an array reference of profile field objects that are required
|
|
for password recovery. Class method.
|
|
|
|
=cut
|
|
|
|
sub getPasswordRecoveryFields {
|
|
my $class = shift;
|
|
my $session = shift;
|
|
return $class->_listFieldsWhere($session, "f.requiredForPasswordRecovery = 1");
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 isDuplicate( fieldValue, userId )
|
|
|
|
Checks the value of the field to see if it is duplicated in the system. Returns true of false.
|
|
|
|
=head3 fieldValue
|
|
|
|
value to check for duplicates against
|
|
|
|
=head3 userId
|
|
|
|
userId to check for duplicates againts
|
|
|
|
=cut
|
|
|
|
sub isDuplicate {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $fieldId = $self->getId;
|
|
my $value = shift;
|
|
my $userId = shift || $session->user->userId;
|
|
|
|
my $sql = qq{select count(*) from userProfileData where $fieldId = ? and userId <> ?};
|
|
my $duplicate = $session->db->quickScalar($sql,[$value, $userId]);
|
|
return ($duplicate > 0);
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 isEditable ( )
|
|
|
|
Returns a boolean indicating whether this field may be editable by a user.
|
|
|
|
=cut
|
|
|
|
sub isEditable {
|
|
my $self = shift;
|
|
return $self->getCategory->isEditable && ($self->get("editable") || $self->isRequired);
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 isInRequest ( )
|
|
|
|
Returns a boolean indicating whether this field was in the posted data.
|
|
|
|
=cut
|
|
|
|
sub isInRequest {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $form = WebGUI::Form::DynamicField->new($session,
|
|
fieldType => $self->get('fieldType'),
|
|
name => $self->getId,
|
|
);
|
|
return $form->isInRequest;
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 isProtected ( )
|
|
|
|
Returns a boolean indicating whether this field may be deleted.
|
|
|
|
=cut
|
|
|
|
sub isProtected {
|
|
my $self = shift;
|
|
return $self->get("protected");
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 isRequired ( )
|
|
|
|
Returns a boolean indicating whether this field is required when a user creates an account or updates their account.
|
|
|
|
=cut
|
|
|
|
sub isRequired {
|
|
my $self = shift;
|
|
return $self->get("required");
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 isValid ( [fieldValue] )
|
|
|
|
Validates the profile field returning true (1) if valid or false(1) if false
|
|
|
|
=head3 fieldValue
|
|
|
|
value to validate the field against
|
|
|
|
=cut
|
|
|
|
sub isValid {
|
|
my $self = shift;
|
|
my $fieldValue = shift;
|
|
|
|
#If the field value is an array ref, set the value to the first element
|
|
if(ref $fieldValue eq "ARRAY") {
|
|
$fieldValue = $fieldValue->[0];
|
|
}
|
|
|
|
return !$self->isRequired || ($self->isRequired && $fieldValue ne "");
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 isViewable ( )
|
|
|
|
Returns a boolean indicating whether this field may be viewed by a user.
|
|
|
|
=cut
|
|
|
|
sub isViewable {
|
|
my $self = shift;
|
|
return $self->getCategory->isViewable && $self->get("visible");
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 moveDown ( )
|
|
|
|
Moves this field down one position within it's category.
|
|
|
|
=cut
|
|
|
|
sub moveDown {
|
|
my $self = shift;
|
|
my ($id, $thisSeq, $profileCategoryId);
|
|
($thisSeq,$profileCategoryId) = $self->session->db->quickArray("select sequenceNumber,profileCategoryId from userProfileField where fieldName=".$self->session->db->quote($self->getId));
|
|
($id) = $self->session->db->quickArray("select fieldName from userProfileField where profileCategoryId=".$self->session->db->quote($profileCategoryId)." and sequenceNumber=$thisSeq+1");
|
|
if ($id ne "") {
|
|
$self->session->db->write("update userProfileField set sequenceNumber=sequenceNumber+1 where fieldName=".$self->session->db->quote($self->getId));
|
|
$self->session->db->write("update userProfileField set sequenceNumber=sequenceNumber-1 where fieldName=".$self->session->db->quote($id));
|
|
$self->_reorderFields($profileCategoryId);
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 moveUp ( )
|
|
|
|
Moves this field up one position within it's category.
|
|
|
|
=cut
|
|
|
|
sub moveUp {
|
|
my $self = shift;
|
|
my ($id, $thisSeq, $profileCategoryId);
|
|
($thisSeq,$profileCategoryId) = $self->session->db->quickArray("select sequenceNumber,profileCategoryId from userProfileField where fieldName=".$self->session->db->quote($self->getId));
|
|
($id) = $self->session->db->quickArray("select fieldName from userProfileField where profileCategoryId=".$self->session->db->quote($profileCategoryId)." and sequenceNumber=$thisSeq-1");
|
|
if ($id ne "") {
|
|
$self->session->db->write("update userProfileField set sequenceNumber=sequenceNumber-1 where fieldName=".$self->session->db->quote($self->getId));
|
|
$self->session->db->write("update userProfileField set sequenceNumber=sequenceNumber+1 where fieldName=".$self->session->db->quote($id));
|
|
$self->_reorderFields($profileCategoryId);
|
|
}
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 new ( session, fieldName )
|
|
|
|
Constructor
|
|
|
|
=head3 session
|
|
|
|
A reference to the current session.
|
|
|
|
=head3 fieldName
|
|
|
|
The unique name of this field.
|
|
|
|
=cut
|
|
|
|
sub new {
|
|
my $class = shift;
|
|
my $session = shift;
|
|
my $id = shift;
|
|
return undef unless ($id);
|
|
return undef if $class->isReservedFieldName($id);
|
|
my $properties = $session->db->getRow("userProfileField","fieldName",$id);
|
|
# Reject properties that don't exist.
|
|
return undef unless scalar keys %$properties;
|
|
bless {_session=>$session, _properties=>$properties}, $class;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 rename ( newFieldName )
|
|
|
|
Renames this field. Returns a 1 if successful and a 0 if not.
|
|
|
|
=head3 newFieldName
|
|
|
|
The new name this field should take.
|
|
|
|
=cut
|
|
|
|
sub rename {
|
|
my $self = shift;
|
|
my $newName = shift;
|
|
|
|
my $session = $self->session;
|
|
my $db = $session->db;
|
|
|
|
### Check data
|
|
# Make sure the field doesn't exist
|
|
return 0 if $self->exists($session, $newName);
|
|
|
|
# Rename the userProfileData column
|
|
my $fieldClass = $self->getFormControlClass;
|
|
eval { WebGUI::Pluggable::load($fieldClass) };
|
|
my $dbDataType = $fieldClass->getDatabaseFieldType;
|
|
|
|
$self->session->db->write(
|
|
"ALTER TABLE userProfileData "
|
|
. "CHANGE " . $db->dbh->quote_identifier($self->getId)
|
|
. $db->dbh->quote_identifier($newName) . " " . $dbDataType
|
|
);
|
|
|
|
# Update the record
|
|
$self->session->db->write(
|
|
"update userProfileField set fieldName=? where fieldName=?",
|
|
[$newName, $self->getId]
|
|
);
|
|
$self->{_properties}{fieldName} = $newName;
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 session ( )
|
|
|
|
Returns a reference to the current session.
|
|
|
|
=cut
|
|
|
|
sub session {
|
|
my $self = shift;
|
|
return $self->{_session};
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 set ( properties )
|
|
|
|
Update the profile field properties.
|
|
|
|
=head3 properties
|
|
|
|
A hash reference containing the properties to be updated.
|
|
|
|
=head4 label
|
|
|
|
A perl structure that will return a scalar. Defaults to 'Undefined'.
|
|
|
|
=head4 visible
|
|
|
|
A boolean indicating whether this field should be visible when a user views a user's profile. Defaults to 0.
|
|
|
|
=head4 required
|
|
|
|
A boolean indicating whether the user must fill out this field in order to create/update his account. Defaults to 0.
|
|
|
|
=head4 protected
|
|
|
|
A boolean indicating whether this field may be deleted or not. Defaults to 0.
|
|
|
|
=head4 editable
|
|
|
|
A boolean indicating whether this field is editable by the user or not. Defaults to 0.
|
|
|
|
=head4 fieldType
|
|
|
|
A scalar indicating the type of field this will be when generated as a form element. Defaults to 'text'.
|
|
|
|
=head4 possibleValues
|
|
|
|
A scalar containing a hash reference declaration of possible values. Only used for list type fields.
|
|
|
|
=head4 dataDefault
|
|
|
|
A scalar containing an array reference or scalar declaration of defaultly selected value(s).
|
|
|
|
=cut
|
|
|
|
sub set {
|
|
my $self = shift;
|
|
my $properties = shift;
|
|
|
|
my $session = $self->session;
|
|
my $db = $session->db;
|
|
|
|
# Set the defaults
|
|
$properties->{visible} = 0 unless ($properties->{visible} == 1);
|
|
$properties->{protected} = 0 unless ($properties->{protected} == 1);
|
|
$properties->{required} = 0 unless ($properties->{required} == 1);
|
|
$properties->{editable} = $properties->{required} == 1 ? 1
|
|
: $properties->{editable} == 1 ? 1
|
|
: 0;
|
|
$properties->{label} = 'Undefined' if ($properties->{label} =~ /^[\"\']*$/);
|
|
$properties->{fieldType} = 'text' unless ($properties->{fieldType});
|
|
$properties->{extras} = '' unless ($properties->{extras});
|
|
if ($properties->{dataDefault} && $properties->{fieldType}=~/List$/) {
|
|
unless ($properties->{dataDefault} =~ /^\[/) {
|
|
$properties->{dataDefault} = "[".$properties->{dataDefault};
|
|
}
|
|
unless ($properties->{dataDefault} =~ /\]$/) {
|
|
$properties->{dataDefault} .= "]";
|
|
}
|
|
}
|
|
$properties->{fieldName} = $self->getId;
|
|
|
|
##Save the fieldType now. It can't be chacked against getFormControlClass now
|
|
##because it will return the OLD formControlClass, not the new one that we need
|
|
##to check against.
|
|
my $originalFieldType = $self->get('fieldType');
|
|
|
|
# Update the record
|
|
$db->setRow("userProfileField","fieldName",$properties);
|
|
foreach my $key (keys %{$properties}) {
|
|
$self->{_properties}{$key} = $properties->{$key};
|
|
}
|
|
|
|
# If the fieldType has changed, modify the userProfileData column
|
|
if ($properties->{fieldType} ne $originalFieldType) {
|
|
# Create a copy of the new properties so we don't mess them up
|
|
my $fieldClass = $self->getFormControlClass;
|
|
eval { WebGUI::Pluggable::load($fieldClass) };
|
|
my $dbDataType
|
|
= $fieldClass->new($session, $self->formProperties($properties))->getDatabaseFieldType;
|
|
|
|
my $sql
|
|
= "ALTER TABLE userProfileData MODIFY COLUMN "
|
|
. $db->dbh->quote_identifier($self->getId) . q{ }
|
|
. $dbDataType
|
|
;
|
|
|
|
$db->write($sql);
|
|
}
|
|
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 setCategory ( id )
|
|
|
|
Assigns this field to a new category.
|
|
|
|
=head3 id
|
|
|
|
The unique ID of a category to assign this field to.
|
|
|
|
=cut
|
|
|
|
sub setCategory {
|
|
my $self = shift;
|
|
my $categoryId = shift;
|
|
return undef unless ($categoryId);
|
|
my $currentCategoryId = $self->get("profileCategoryId");
|
|
|
|
return undef if ($categoryId eq $currentCategoryId);
|
|
|
|
my ($sequenceNumber) = $self->session->db->quickArray("select max(sequenceNumber) from userProfileField where profileCategoryId=?", [$categoryId]);
|
|
$self->session->db->setRow("userProfileField","fieldName",{fieldName=>$self->getId, profileCategoryId=>$categoryId, sequenceNumber=>$sequenceNumber+1});
|
|
$self->{_property}{profileCategoryId} = $categoryId;
|
|
$self->{_property}{sequenceNumber} = $sequenceNumber+1;
|
|
$self->_reorderFields($currentCategoryId) if ($currentCategoryId);
|
|
$self->_reorderFields($categoryId);
|
|
}
|
|
|
|
|
|
1;
|
|
|
|
|