add: User profile data table is now a flat table.

This commit is contained in:
Doug Bell 2007-05-28 21:35:34 +00:00
parent 8590ef89d5
commit 07a40788bb
41 changed files with 493 additions and 164 deletions

View file

@ -5,6 +5,8 @@
http://www.plainblack.com/rfe/request-for-enhancement/search-asset-feedback.-i.e.-no-results-found#kH5X_YA17ZxbRvi6gx5KRA
- RFE: JS confirmation Operation/DatabaseLink.pm
http://www.plainblack.com/rfe/request-for-enhancement/-1493348--js-confirmation-operation/databaselink/re--1493348--js-confirmation-operation/databaselink.pm#OUb5zN8bltGdPG_2LJZMGQ
- add: User profile data table is now a flat table, one column for each
field.

View file

@ -7,6 +7,17 @@ upgrading from one version to the next, or even between multiple
versions. Be sure to heed the warnings contained herein as they will
save you many hours of grief.
7.4.0
--------------------------------------------------------------------
* The userProfileData table has been completely re-done. Now, each
user profile field has its own column in the userProfileData table.
Any applications that you may have that makes raw SQL queries against
the userProfileData table will need to be updated to reflect these
changes.
7.3.16
--------------------------------------------------------------------

View file

@ -21,6 +21,8 @@ my $quiet; # this line required
my $session = start(); # this line required
# upgrade functions go here
fixProfileDataWithoutFields($session);
buildNewUserProfileTable($session);
finish($session); # this line required
@ -32,6 +34,125 @@ finish($session); # this line required
# # and here's our code
#}
#----------------------------------------------------------------------------
sub fixProfileDataWithoutFields {
my $session = shift;
my $db = $session->db;
use WebGUI::ProfileField;
print "\tFixing profile data without entries in userProfileField table..." unless $quiet;
for my $fieldName (qw{ firstDayOfWeek language timeZone uiLevel }) {
next if WebGUI::ProfileField->new($session, $fieldName);
$db->write(
q{INSERT INTO userProfileField (fieldName, label, visible, fieldType, protected, editable)
VALUES (?,?,0,"ReadOnly",1,0)},
[$fieldName, $fieldName]
);
}
print "OK!\n" unless $quiet;
}
#----------------------------------------------------------------------------
sub buildNewUserProfileTable {
my $session = shift;
my $db = $session->db;
print "\tBuilding new user profile table. This may take a while...\n" unless $quiet;
use WebGUI::ProfileField;
use List::Util qw( first );
print "\t\tCreating structure..." unless $quiet;
# Create a new temporary table
$db->write(q{
CREATE TABLE tmp_userProfileData (
userId VARCHAR(22) BINARY NOT NULL,
PRIMARY KEY (userId)
)
});
# Loop through the current fields and add them to the new table
my @profileFields;
my $sth = $db->read(q{SELECT fieldName, fieldType FROM userProfileField});
while (my %fieldData = $sth->hash) {
push @profileFields, $fieldData{fieldName};
my $fieldType = 'WebGUI::Form::'.ucfirst $fieldData{fieldType};
my $fieldName = $db->dbh->quote_identifier($fieldData{fieldName});
eval "use $fieldType;";
my $dataType = $fieldType->new($session)->get("dbDataType");
$db->write(
"ALTER TABLE tmp_userProfileData ADD COLUMN ($fieldName $dataType)"
);
}
print " OK!\n" unless $quiet;
# Find fields that were not in the userProfileField database.
print "\t\tLooking for profile fields not defined in User Profiling... \n" unless $quiet;
my @dataFields = $db->buildArray("SELECT fieldName FROM userProfileData GROUP BY fieldName");
for my $dataField (@dataFields) {
if (!first { $_ eq $dataField } @profileFields) {
print "\t\t\tCreating invisible, read-only profile field '$dataField'\n" unless $quiet;
my $fieldType = 'WebGUI::Form::ReadOnly';
my $fieldName = $db->dbh->quote_identifier($dataField);
eval "use $fieldType;";
my $dataType = $fieldType->new($session)->get("dbDataType");
$db->write(
"ALTER TABLE tmp_userProfileData ADD COLUMN ($fieldName $dataType)"
);
# Create the profile field
WebGUI::ProfileField->create($session, $dataField, {
label => $dataField,
fieldType => "ReadOnly",
visible => 0,
protected => 1,
});
}
}
print "\t\t... Done!\n";
print "\t\tMigrating data to temporary table... " unless $quiet;
# Loop over the old table and put them in the new table
$sth = $db->read(q{SELECT userId FROM users});
while (my $user = $sth->hashRef) {
# Get all of this user's profile data
my %profile
= $db->buildHash(
"SELECT fieldName, fieldData FROM userProfileData WHERE userId=?",
[$user->{userId}]
);
# Write to the temp table
my $sql
= q{INSERT INTO tmp_userProfileData }
. q{(userId,} . join(",", map { $db->dbh->quote_identifier($_) } keys %profile) . q{)}
. q{VALUES (?,} . join(",",("?")x values %profile) . q{)}
;
$db->write($sql, [$user->{userId},values %profile]);
}
$sth->finish;
print "OK!\n" unless $quiet;
# Delete the old table
print "\t\tExchanging old data with new... ";
$db->write("drop table userProfileData");
# Rename the new table
$db->write("rename table tmp_userProfileData to userProfileData");
print "OK!\n" unless $quiet;
print "\t\t... Done!\n" unless $quiet;
}
# ---- DO NOT EDIT BELOW THIS LINE ----

View file

@ -31,14 +31,10 @@ sub _fetchNames {
my $self = shift;
my @userIds = @_;
my %nameHash;
my $sql = "select users.username,
users.userId,
a.fieldData as firstName,
b.fieldData as lastName
from users
left join userProfileData a on users.userId=a.userId and a.fieldName='firstName'
left join userProfileData b on users.userId=b.userId and b.fieldName='lastName'
where users.userId=?";
my $sql = "SELECT users.username, users.userId, firstName, lastName
FROM users
LEFT JOIN userProfileData ON users.userId=userProfileData.userId
WHERE users.userId=?";
my $sth = $self->session->db->prepare($sql);
foreach my $userId (@userIds) {
$sth->execute([ $userId ]);
@ -51,7 +47,7 @@ where users.userId=?";
#-------------------------------------------------------------------
sub _fetchDepartments {
my $self = shift;
return $self->session->db->buildArray("select fieldData from userProfileData where fieldName='department' GROUP by fieldData");
return $self->session->db->buildArray("SELECT department FROM userProfileData GROUP BY department");
}
@ -244,19 +240,17 @@ sub view {
my $sql = "select users.username,
users.userId,
a.fieldData as firstName,
firstName,
InOutBoard_status.message,
b.fieldData as lastName,
lastName,
InOutBoard_status.status,
InOutBoard_status.dateStamp,
c.fieldData as department,
department,
groupings.groupId
from users
left join groupings on groupings.userId=users.userId
left join InOutBoard on groupings.groupId=InOutBoard.inOutGroup
left join userProfileData a on users.userId=a.userId and a.fieldName='firstName'
left join userProfileData b on users.userId=b.userId and b.fieldName='lastName'
left join userProfileData c on users.userId=c.userId and c.fieldName='department'
left join userProfileData on users.userId=userProfileData.userId
left join InOutBoard_status on users.userId=InOutBoard_status.userId and InOutBoard_status.assetId=".$self->session->db->quote($self->getId())."
where users.userId<>'1' and InOutBoard.inOutGroup=".$self->session->db->quote($self->get("inOutGroup"))."
group by userId
@ -312,14 +306,12 @@ sub www_selectDelegates {
"select
users.username,
users.userId,
a.fieldData as firstName,
b.fieldData as lastName
firstName,
lastName
from users
left join groupings on users.userId=groupings.userId
left join InOutBoard on groupings.groupId=InOutBoard.inOutGroup
left join userProfileData a on users.userId=a.userId and a.fieldName='firstName'
left join userProfileData b on users.userId=b.userId and b.fieldName='lastName'
left join userProfileData c on users.userId=c.userId and c.fieldName='department'
left join userProfileData on users.userId=userProfileData.userId
left join InOutBoard_status on users.userId=InOutBoard_status.userId and InOutBoard_status.assetId=?
where
users.userId<>'1'
@ -465,19 +457,17 @@ sub www_viewReport {
my $sql = "select users.username,
users.userId,
a.fieldData as firstName,
firstName,
InOutBoard_statusLog.message,
b.fieldData as lastName,
lastName,
InOutBoard_statusLog.status,
InOutBoard_statusLog.dateStamp,
InOutBoard_statusLog.createdBy,
c.fieldData as department,
department,
groupings.groupId
from users
left join groupings on groupings.userId=users.userId
left join userProfileData a on users.userId=a.userId and a.fieldName='firstName'
left join userProfileData b on users.userId=b.userId and b.fieldName='lastName'
left join userProfileData c on users.userId=c.userId and c.fieldName='department'
left join userProfileData on users.userId=userProfileData.userId
left join InOutBoard_statusLog on users.userId=InOutBoard_statusLog.userId and InOutBoard_statusLog.assetId=".$self->session->db->quote($self->getId())."
where users.userId<>'1' and
groupings.groupId=".$self->session->db->quote($self->getValue("inOutGroup"))." and

View file

@ -270,13 +270,10 @@ sub _userSearchQuery {
my $query = <<"SQL";
SELECT 'user' AS resourceKind, users.userId AS resourceId
FROM users
LEFT JOIN userProfileData AS lastName ON users.userId = lastName.userId
AND lastName.fieldName = 'lastName'
LEFT JOIN userProfileData AS firstName ON users.userId = firstName.userId
AND firstName.fieldName = 'firstName'
WHERE (LOWER(lastName.fieldData) LIKE ? OR LOWER(firstName.fieldData) LIKE ?
LEFT JOIN userProfileData ON users.userId = userProfileData.userId
WHERE (LOWER(lastName) LIKE ? OR LOWER(firstName) LIKE ?
OR LOWER(users.username) LIKE ?) AND (users.userId NOT IN $excludePlaceholders)
ORDER BY lastName.fieldData, firstName.fieldData
ORDER BY lastName, firstName
SQL
my @placeholders = (($searchPattern) x 3, @exclude);
return ($query, \@placeholders);

View file

@ -651,10 +651,9 @@ sub recoverPasswordFinish {
my @fieldNames = keys %fieldValues;
my @fieldValues = values %fieldValues;
my $joins = join(' ', map{"INNER JOIN userProfileData AS p$_ ON u.userId = p$_.userId AND p$_.fieldName = ".$self->session->db->quote($fieldNames[$_])} (0..$#fieldNames));
my $wheres = join(' ', map{"AND p$_.fieldData = ?"} (0..$#fieldNames));
my $wheres = join(' ', map{"AND upd.$_ = ?"} (0..$#fieldNames));
$wheres .= ' AND u.username = ?' if defined $username;
my $sql = "SELECT u.userId FROM users AS u $joins WHERE u.authMethod = 'WebGUI' $wheres";
my $sql = "SELECT u.userId FROM users AS u JOIN userProfileData AS upd ON u.userId=upd.userId WHERE u.authMethod = 'WebGUI' $wheres";
my @userIds = $self->session->db->buildArray($sql, [@fieldValues, (defined($username)? ($username) : ())]);
if (@userIds == 0) {

View file

@ -81,6 +81,9 @@ sub definition {
class=>{
defaultValue=> undef
},
dbDataType => {
defaultValue => "VARCHAR(22) BINARY",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -64,6 +64,9 @@ sub definition {
defaultValue=>{
defaultValue=>$i18n->get(62)
},
dbDataType => {
defaultValue => "VARCHAR(255)",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -72,6 +72,9 @@ sub definition {
profileEnabled=>{
defaultValue=>0
},
dbDataType => {
defaultValue => "VARCHAR(6)",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -85,7 +85,10 @@ sub definition {
},
profileEnabled=>{
defaultValue=>1
}
},
dbDataType => {
defaultValue => "TEXT",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -53,6 +53,9 @@ sub definition {
formName=>{
defaultValue=>$i18n->get("color")
},
dbDataType => {
defaultValue => "VARCHAR(7)",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -68,7 +68,10 @@ sub definition {
},
profileEnabled=>{
defaultValue=>1
}
},
dbDataType => {
defaultValue => "TEXT",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -159,6 +159,12 @@ A text string that will pop up when the user hovers over the label when toHtmlWi
Flag that tells the User Profile system that this is a valid form element in a User Profile
=head4 dbDataType
The SQL data type for this form element. Fields created using this form control
will create a column with this data type. If undef, will not create a database
column. Defaults to "VARCHAR(255)".
=cut
sub definition {
@ -216,8 +222,11 @@ sub definition {
},
profileEnabled=>{
defaultValue=>0
},
});
},
dbDataType => {
defaultValue => "VARCHAR(255)",
},
});
return $definition;
}

View file

@ -93,6 +93,9 @@ sub definition {
hoverHelp=>{
defaultValue=>$i18n->get('1075 description')
},
dbDataType => {
defaultValue => "VARCHAR(22) BINARY",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -101,6 +101,9 @@ sub definition {
profileEnabled=>{
defaultValue=>1
},
dbDataType => {
defaultValue => "BIGINT",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -96,6 +96,9 @@ sub definition {
profileEnabled=>{
defaultValue=>1
},
dbDataType => {
defaultValue => "BIGINT",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -87,7 +87,10 @@ sub definition {
},
deleteFileUrl=>{
defaultValue=>undef
}
},
dbDataType => {
defaultValue => "VARCHAR(22) BINARY",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -79,6 +79,9 @@ sub definition {
defaultValue=>{
defaultValue=>"most",
},
dbDataType => {
defaultValue => "VARCHAR(16)",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -85,6 +85,9 @@ sub definition {
profileEnabled=>{
defaultValue=>1
},
dbDataType => {
defaultValue => "DOUBLE",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -93,6 +93,9 @@ sub definition {
profileEnabled=>{
defaultValue=>1
},
dbDataType => {
defaultValue => "VARCHAR(22) BINARY",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -95,6 +95,9 @@ sub definition {
profileEnabled=>{
defaultValue=>1
},
dbDataType => {
defaultValue => "LONGTEXT",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -72,6 +72,9 @@ sub definition {
profileEnabled=>{
defaultValue=>1
},
dbDataType => {
defaultValue => "TEXT",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -81,8 +81,11 @@ sub definition {
forceImageOnly=>{
defaultValue=>0
},
});
return $class->SUPER::definition($session, $definition);
dbDataType => {
defaultValue => "VARCHAR(22) BINARY",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -71,6 +71,9 @@ sub definition {
profileEnabled=>{
defaultValue=>1
},
dbDataType => {
defaultValue => "BIGINT",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -85,6 +85,9 @@ sub definition {
profileEnabled=>{
defaultValue=>1
},
dbDataType => {
defaultValue => "BIGINT",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -76,6 +76,9 @@ sub definition {
profileEnabled=>{
defaultValue=>1
},
dbDataType => {
defaultValue => "BIGINT",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -99,7 +99,10 @@ sub definition {
},
afterEdit=>{
defaultValue=>undef
}
},
dbDataType => {
defaultValue => "TEXT",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -171,6 +171,9 @@ sub definition {
profileEnabled=>{
defaultValue=>0
},
dbDataType => {
defaultValue => "TEXT",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -84,6 +84,9 @@ sub definition {
profileEnabled=>{
defaultValue=>1,
},
dbDataType => {
defaultValue => "VARCHAR(255)",
}
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -68,18 +68,21 @@ sub definition {
push(@{$definition}, {
formName=>{
defaultValue=>$i18n->get("484"),
},
},
multiple=>{
defaultValue=>1
},
},
size=>{
defaultValue=>5
},
},
profileEnabled=>{
defaultValue=>1
},
});
return $class->SUPER::definition($session, $definition);
},
dbDataType => {
defaultValue => "LONGTEXT",
},
});
return $class->SUPER::definition($session, $definition);
}
#-------------------------------------------------------------------

View file

@ -54,6 +54,9 @@ sub definition {
profileEnabled=>{
defaultValue=>1
},
dbDataType => {
defaultValue => "TEXT",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -79,6 +79,9 @@ sub definition {
namespace=>{
defaultValue=>undef
},
dbDataType => {
defaultValue => "VARCHAR(22) BINARY",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -92,6 +92,9 @@ sub definition {
profileEnabled=>{
defaultValue=>1
},
dbDataType => {
defaultValue => "LONGTEXT",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -90,6 +90,9 @@ sub definition {
profileEnabled=>{
defaultValue=>1
},
dbDataType => {
defaultValue => "BIGINT",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -81,6 +81,9 @@ sub definition {
readOnly=>{
defaultValue=>0,
},
dbDataType => {
defaultValue => "VARCHAR(22) BINARY",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -85,7 +85,10 @@ sub definition {
},
none=>{
defaulValue=>0
}
},
dbDataType => {
defaultValue => "VARCHAR(22) BINARY",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -72,6 +72,9 @@ sub definition {
profileEnabled=>{
defaultValue=>1
},
dbDataType => {
defaultValue => "INT(1)",
},
});
return $class->SUPER::definition($session, $definition);
}

View file

@ -84,10 +84,14 @@ email address to check for duplication
=cut
sub isDuplicateEmail {
my $session = shift;
my $email = shift;
my ($otherEmail) = $session->db->quickArray("select count(*) from userProfileData where fieldName='email' and fieldData = ".$session->db->quote($email)." and userId <> ".$session->db->quote($session->user->userId));
return ($otherEmail > 0);
my $session = shift;
my $email = shift;
my ($otherEmail)
= $session->db->quickArray(
'select count(*) from userProfileData where email = ? and userId <> ?',
[$email, $session->user->userId]
);
return ($otherEmail > 0);
}
#-------------------------------------------------------------------

View file

@ -138,10 +138,9 @@ sub doUserSearch {
}
$keyword = $session->db->quote($keyword);
my $sql = "select users.userId, users.username, users.status, users.dateCreated, users.lastUpdated,
email.fieldData as email from users
left join userProfileData email on users.userId=email.userId and email.fieldName='email'
left join userProfileData useralias on users.userId=useralias.userId and useralias.fieldName='alias'
where $selectedStatus and (users.username like ".$keyword." or useralias.fieldData like ".$keyword." or email.fieldData like ".$keyword.")
userProfileData.email from users
left join userProfileData on users.userId=userProfileData.userId
where $selectedStatus and (users.username like ".$keyword." or alias like ".$keyword." or email like ".$keyword.")
and users.userId not in (".$session->db->quoteAndJoin($userFilter).") order by users.username";
if ($returnPaginator) {
my $p = WebGUI::Paginator->new($session,$session->url->page("op=".$op));

View file

@ -94,20 +94,45 @@ 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 $fieldNameExists = $session->db->quickScalar("select count(*) from userProfileField where fieldName=?", [$fieldName]);
return undef if $fieldNameExists;
return undef if $class->isReservedFieldName($fieldName);
my $class = shift;
my $session = shift;
my $fieldName = shift;
my $properties = shift;
my $categoryId = shift || "1";
my $db = $session->db;
my $id = $session->db->setRow("userProfileField","fieldName",{fieldName=>"new"},$fieldName);
my $self = $class->new($session,$id);
$self->setCategory($categoryId);
$self->set($properties);
return $self;
### Check data
# Check if the field already exists
my $fieldNameExists
= $session->db->quickScalar(
"select count(*) from userProfileField where fieldName=?",
[$fieldName]
);
return undef if $fieldNameExists;
return undef if $class->isReservedFieldName($fieldName);
### Data okay, create the field
# Add the record
my $id
= $session->db->setRow("userProfileField","fieldName",{fieldName=>"new"},$fieldName);
my $self = $class->new($session,$id);
# Get the field's data type
my $formClass = 'WebGUI::Form::' . ucfirst $properties->{fieldType};
eval "use $formClass;";
my $dbDataType = $formClass->new($session, $self->_formProperties($properties))->get("dbDataType");
# Add the column to the userProfileData table
$db->write(
"ALTER TABLE userProfileData ADD " . $db->dbh->quote_identifier($fieldName)
. $dbDataType
);
$self->setCategory($categoryId);
$self->set($properties);
return $self;
}
#-------------------------------------------------------------------
@ -119,19 +144,31 @@ Deletes this field and all user data attached to it.
=cut
sub delete {
my $self = shift;
$self->session->db->write("delete from userProfileData where fieldName=?", [$self->getId]);
$self->session->db->deleteRow("userProfileField","fieldName",$self->getId);
my $self = shift;
my $db = $self->session->db;
# Remove the column from the userProfileData table
$db->write("ALTER TABLE userProfileData DROP " . $self->getId);
# Remove the record
$db->deleteRow("userProfileField","fieldName",$self->getId);
}
#-------------------------------------------------------------------
# Get a hashref of properties to give to a WebGUI::Form::Control
sub _formProperties {
my $self = shift;
my $properties = shift || {};
$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"));
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);
@ -140,13 +177,13 @@ sub _formProperties {
}
my $orderedValues = {};
tie %{$orderedValues}, 'Tie::IxHash';
foreach my $ov (sort keys %{$values}) {
$orderedValues->{$ov} = $values->{$ov};
}
$properties->{options} = $orderedValues;
$properties->{forceImageOnly} = $self->get("forceImageOnly");
$properties->{dataDefault} = $self->get("dataDefault");
return $properties;
for my $ov (sort keys %{$values}) {
$orderedValues->{$ov} = $values->{$ov};
}
$properties{ options } = $orderedValues;
$properties{ forceImageOnly } = $self->get("forceImageOnly");
$properties{ dataDefault } = $self->get("dataDefault");
return \%properties;
}
=head2 formField ( [ formProperties, withWrapper, userObject ] )
@ -334,6 +371,19 @@ sub getFields {
#-------------------------------------------------------------------
=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 getRequiredFields ( session )
Returns an array reference of WebGUI::ProfileField objects that are marked "required". This is a class method.
@ -484,15 +534,15 @@ 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;
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;
}
#-------------------------------------------------------------------
@ -508,14 +558,40 @@ The new name this field should take.
=cut
sub rename {
my $self = shift;
my $newName = shift;
my ($fieldNameExists) = $self->session->db->quickArray("select count(*) from userProfileField where fieldName=".$self->session->db->quote($newName));
my $self = shift;
my $newName = shift;
my $session = $self->session;
my $db = $session->db;
### Check data
# Make sure the field doesn't exist
my $fieldNameExists
= $self->session->db->quickScalar(
"SELECT COUNT(*) FROM userProfileField WHERE fieldName=?",
[$newName]
);
return 0 if ($fieldNameExists);
$self->session->db->write("update userProfileData set fieldName=".$self->session->db->quote($newName)." where fieldName=".$self->session->db->quote($self->getId));
$self->session->db->write("update userProfileField set fieldName=".$self->session->db->quote($newName)." where fieldName=".$self->session->db->quote($self->getId));
# Rename the userProfileData column
my $fieldClass = $self->getFormControlClass;
eval "use $fieldClass;";
my $dbDataType = $fieldClass->new($session, $self->_formProperties)->get("dbDataType");
$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;
return 1;
}
@ -577,9 +653,14 @@ A scalar containing an array reference or scalar declaration of defaultly select
=cut
sub set {
my $self = shift;
my $properties = shift;
$properties->{visible} = 0 unless ($properties->{visible} == 1);
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->{editable} = 0 unless ($properties->{editable} == 1);
$properties->{protected} = 0 unless ($properties->{protected} == 1);
$properties->{required} = 0 unless ($properties->{required} == 1);
@ -594,7 +675,26 @@ sub set {
}
}
$properties->{fieldName} = $self->getId;
$self->session->db->setRow("userProfileField","fieldName",$properties);
# If the fieldType has changed, modify the userProfileData column
if ($properties->{fieldType} ne $self->get("fieldType")) {
# Create a copy of the new properties so we don't mess them up
my $fieldClass = "WebGUI::Form::".ucfirst($properties->{fieldType});
eval "use $fieldClass;";
my $dbDataType
= $fieldClass->new($session, $self->_formProperties($properties))->get("dbDataType");
my $sql
= "ALTER TABLE userProfileData MODIFY COLUMN "
. $db->dbh->quote_identifier($self->getId) . q{ }
. $dbDataType
;
$db->write($sql);
}
# Update the record
$db->setRow("userProfileField","fieldName",$properties);
foreach my $key (keys %{$properties}) {
$self->{_properties}{$key} = $properties->{$key};
}

View file

@ -58,12 +58,13 @@ These methods are available from this class:
#-------------------------------------------------------------------
sub _create {
my $session = shift;
my $userId = shift || $session->id->generate();
$session->db->write("insert into users (userId,dateCreated) values (?,?)",[$userId, time()]);
WebGUI::Group->new($session,2)->addUsers([$userId]);
WebGUI::Group->new($session,7)->addUsers([$userId]);
return $userId;
my $session = shift;
my $userId = shift || $session->id->generate();
$session->db->write("insert into users (userId,dateCreated) values (?,?)",[$userId, time()]);
$session->db->write("INSERT INTO userProfileData (userId) VALUES (?)",[$userId]);
WebGUI::Group->new($session,2)->addUsers([$userId]);
WebGUI::Group->new($session,7)->addUsers([$userId]);
return $userId;
}
#-------------------------------------------------------------------
@ -375,41 +376,45 @@ A unique ID to use instead of the ID that WebGUI will generate for you. It must
=cut
sub new {
my $class = shift;
my $session = shift;
my $userId = shift || 1;
my $overrideId = shift;
$userId = _create($session, $overrideId) if ($userId eq "new");
my $cache = WebGUI::Cache->new($session,["user",$userId]);
my $userData = $cache->get;
unless ($userData->{_userId} && $userData->{_user}{username}) {
my %user;
tie %user, 'Tie::CPHash';
%user = $session->db->quickHash("select * from users where userId=?",[$userId]);
my %profile = $session->db->buildHash("select userProfileField.fieldName, userProfileData.fieldData
from userProfileField, userProfileData where userProfileField.fieldName=userProfileData.fieldName and
userProfileData.userId=?",[$user{userId}]);
my %default = $session->db->buildHash("select fieldName, dataDefault from userProfileField");
foreach my $key (keys %default) {
my $value;
if ($profile{$key} eq "" && $default{$key}) {
$value = eval($default{$key});
if (ref $value eq "ARRAY") {
$profile{$key} = $$value[0];
} else {
$profile{$key} = $value;
}
}
}
$profile{alias} = $user{username} if ($profile{alias} =~ /^\W+$/ || $profile{alias} eq "");
$userData = {
_userId => $userId,
_user => \%user,
_profile => \%profile
};
$cache->set($userData, 60*60*24);
}
$userData->{_session} = $session;
my $class = shift;
my $session = shift;
my $userId = shift || 1;
my $overrideId = shift;
$userId = _create($session, $overrideId) if ($userId eq "new");
my $cache = WebGUI::Cache->new($session,["user",$userId]);
my $userData = $cache->get;
unless ($userData->{_userId} && $userData->{_user}{username}) {
my %user;
tie %user, 'Tie::CPHash';
%user = $session->db->quickHash("select * from users where userId=?",[$userId]);
my %profile
= $session->db->quickHash(
"select * from userProfileData where userId=?",
[$user{userId}]
);
delete $profile{userId};
my %default = $session->db->buildHash("select fieldName, dataDefault from userProfileField");
foreach my $key (keys %default) {
my $value;
if ($profile{$key} eq "" && $default{$key}) {
$value = eval($default{$key});
if (ref $value eq "ARRAY") {
$profile{$key} = $$value[0];
} else {
$profile{$key} = $value;
}
}
}
$profile{alias} = $user{username} if ($profile{alias} =~ /^\W+$/ || $profile{alias} eq "");
$userData = {
_userId => $userId,
_user => \%user,
_profile => \%profile
};
$cache->set($userData, 60*60*24);
}
$userData->{_session} = $session;
bless $userData, $class;
}
@ -433,7 +438,7 @@ sub newByEmail {
my $class = shift;
my $session = shift;
my $email = shift;
my ($id) = $session->dbSlave->quickArray("select userId from userProfileData where fieldName='email' and fieldData=?",[$email]);
my ($id) = $session->dbSlave->quickArray("select userId from userProfileData where email=?",[$email]);
my $user = $class->new($session, $id);
return undef if ($user->userId eq "1"); # visitor is never valid for this method
return undef unless $user->username;
@ -458,22 +463,24 @@ The value to set the profile field name to.
=cut
sub profileField {
my ($self, $fieldName, $value);
$self = shift;
$fieldName = shift;
$value = shift;
if (!exists $self->{_profile}{$fieldName} && !$self->session->db->quickScalar("SELECT COUNT(*) FROM userProfileField WHERE fieldName = ?", [$fieldName]) ) {
$self->session->errorHandler->warn("No such profile field: $fieldName");
return undef;
}
if (defined $value) {
$self->uncache;
$self->{_profile}{$fieldName} = $value;
$self->session->db->write("delete from userProfileData where userId=? and fieldName=?",[$self->{_userId}, $fieldName]);
$self->session->db->write("insert into userProfileData values (?,?,?)", [$self->{_userId}, $fieldName,$value]);
my $time = $self->session->datetime->time();
$self->{_user}{"lastUpdated"} = $time;
$self->session->db->write("update users set lastUpdated=? where userId=?", [$time, $self->{_userId}]);
my $self = shift;
my $fieldName = shift;
my $value = shift;
my $db = $self->session->db;
if (!exists $self->{_profile}{$fieldName} && !$self->session->db->quickScalar("SELECT COUNT(*) FROM userProfileField WHERE fieldName = ?", [$fieldName]) ) {
$self->session->errorHandler->warn("No such profile field: $fieldName");
return undef;
}
if (defined $value) {
$self->uncache;
$self->{_profile}{$fieldName} = $value;
$db->write(
"UPDATE userProfileData SET ".$db->dbh->quote_identifier($fieldName)."=? WHERE userId=?",
[$value, $self->{_userId}]
);
my $time = $self->session->datetime->time;
$self->{_user}{"lastUpdated"} = $time;
$self->session->db->write("update users set lastUpdated=? where userId=?", [$time, $self->{_userId}]);
}
return $self->{_profile}{$fieldName};
}