rfe: User Profile Privacy Settings (#507) - users now have granular control of whether or not their profile fields are viewable - admin settings still apply
This commit is contained in:
parent
2945189adb
commit
6eff997f81
8 changed files with 266 additions and 46 deletions
|
|
@ -10,6 +10,7 @@
|
|||
- New Friends Account module added providing a better interface into WebGUI's friends system
|
||||
- rfe: Event hover detail exclusions (#8761)
|
||||
- rfe: Database Link test (#513)
|
||||
- rfe: User Profile Privacy Settings (#507) - users now have granular control of whether or not their profile fields are viewable - admin settings still apply
|
||||
- The Display Account and My Purchases interfaces have been added to the new Account system
|
||||
- Added a new macro which returns the self deactivation link if the setting is enabled.
|
||||
- Added a new macro which returns the back to site link
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -24,6 +24,7 @@ use WebGUI::Asset::Wobject::Survey;
|
|||
use WebGUI::Asset::Wobject::Survey::SurveyJSON;
|
||||
use WebGUI::Asset::Wobject::Survey::ResponseJSON;
|
||||
use WebGUI::ProfileField;
|
||||
use JSON;
|
||||
|
||||
my $toVersion = '7.6.4';
|
||||
my $quiet; # this line required
|
||||
|
|
@ -37,9 +38,48 @@ addPosMode($session);
|
|||
fixFriendsGroups( $session );
|
||||
upgradeAccount( $session );
|
||||
removeProcessRecurringPaymentsFromConfig( $session );
|
||||
addExtendedProfilePrivileges( $session );
|
||||
addStorageUrlMacro( $session );
|
||||
finish($session); # this line required
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
sub addExtendedProfilePrivileges {
|
||||
my $session = shift;
|
||||
|
||||
print qq{\tExtending User Profile Privileges..} if !$quiet;
|
||||
|
||||
my $userProfDesc = $session->db->buildHashRef('describe userProfileData');
|
||||
if(grep { $_ =~ /^wg_privacySettings/ } keys %{$userProfDesc}) {
|
||||
$session->db->write("alter table userProfileData drop column wg_privacySettings");
|
||||
}
|
||||
$session->db->write("alter table userProfileData add wg_privacySettings longtext");
|
||||
|
||||
my $fields = WebGUI::ProfileField->getFields($session);
|
||||
|
||||
my $users = $session->db->buildArrayRef("select userId from users");
|
||||
foreach my $userId (@{$users}) {
|
||||
my $hash = {};
|
||||
foreach my $field (@{$fields}) {
|
||||
if($field->getId eq "publicEmail") {
|
||||
my $u = WebGUI::User->new($session,$userId);
|
||||
$hash->{$field->getId} = $u->profileField("publicEmail") ? "all" : "none";
|
||||
next;
|
||||
}
|
||||
$hash->{$field->getId} = $field->isViewable ? "all" : "none";
|
||||
}
|
||||
my $json = JSON->new->encode($hash);
|
||||
$session->db->write("update userProfileData set wg_privacySettings=? where userId=?",[$json,$userId]);
|
||||
}
|
||||
|
||||
#Delete the public email field
|
||||
my $publicEmail = WebGUI::ProfileField->new($session,"publicEmail");
|
||||
if(defined $publicEmail) {
|
||||
$publicEmail->delete;
|
||||
}
|
||||
|
||||
print qq{Finished\n} if !$quiet;
|
||||
}
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
sub addPosMode {
|
||||
|
|
@ -447,7 +487,6 @@ sub upgradeAccount {
|
|||
$setting->add("shopStyleTemplateId",""); #Use the userStyle by default
|
||||
$setting->add("shopLayoutTemplateId","aUDsJ-vB9RgP-AYvPOy8FQ");
|
||||
|
||||
|
||||
#Add inbox changes
|
||||
$session->db->write(q{
|
||||
create table inbox_messageState (
|
||||
|
|
|
|||
|
|
@ -353,37 +353,50 @@ sub www_edit {
|
|||
#Initialize the category template loop which gets filled inside the loop
|
||||
$var->{'profile_category_loop'} = [];
|
||||
|
||||
#Cache the privacy settings
|
||||
my $privacySettingsHash = WebGUI::ProfileField->getPrivacyOptions($session);
|
||||
#Get the editable categories
|
||||
my $categories = WebGUI::ProfileCategory->getCategories($session, { editable => 1 } );
|
||||
foreach my $category (@{ $categories } ) {
|
||||
my @fields = ();
|
||||
use Data::Dumper;
|
||||
foreach my $field (@{ $category->getFields( { editable => 1 } ) }) {
|
||||
my $fieldId = $field->getId;
|
||||
my $fieldLabel = $field->getLabel;
|
||||
my $fieldForm = $field->formField({ extras=>$self->getExtrasStyle($field,\@errorFields,$user->profileField($fieldId)) });
|
||||
my $fieldSubtext = $field->isRequired ? "*" : undef;
|
||||
my $fieldExtras = $field->getExtras;
|
||||
my $fieldPrivacy = WebGUI::Form::radoList($session,{
|
||||
my $fieldId = $field->getId;
|
||||
my $fieldLabel = $field->getLabel;
|
||||
my $fieldForm = $field->formField({ extras=>$self->getExtrasStyle($field,\@errorFields,$user->profileField($fieldId)) });
|
||||
my $fieldRequired = $field->isRequired;
|
||||
my $fieldExtras = $field->getExtras;
|
||||
my $fieldViewable = $field->isViewable;
|
||||
my $rawPrivacySetting = $user->getProfileFieldPrivacySetting($fieldId);
|
||||
my $fieldPrivacySetting = $privacySettingsHash->{$rawPrivacySetting};
|
||||
|
||||
my $fieldPrivacy = WebGUI::Form::selectBox($session,{
|
||||
name => "privacy_$fieldId",
|
||||
options => $field->getPrivacyOptions($session),
|
||||
value => $user->getProfileFieldPrivacySetting($fieldId)
|
||||
options => $privacySettingsHash,
|
||||
value => $rawPrivacySetting,
|
||||
extras => (!$fieldViewable) ? " disabled" : ""
|
||||
});
|
||||
|
||||
#Create a seperate template var for each field
|
||||
$var->{'profile_field_'.$fieldId.'_form' } = $fieldForm;
|
||||
$var->{'profile_field_'.$fieldId.'_label' } = $fieldLabel;
|
||||
$var->{'profile_field_'.$fieldId.'_subtext'} = $fieldSubtext;
|
||||
$var->{'profile_field_'.$fieldId.'_extras' } = $fieldExtras;
|
||||
$var->{'profile_field_'.$fieldId.'_privacy'} = $fieldPrivacy;
|
||||
my $fieldBase = 'profile_field_'.$fieldId;
|
||||
$var->{$fieldBase.'_form' } = $fieldForm;
|
||||
$var->{$fieldBase.'_label' } = $fieldLabel;
|
||||
$var->{$fieldBase.'_required' } = $fieldRequired;
|
||||
$var->{$fieldBase.'_extras' } = $fieldExtras;
|
||||
$var->{$fieldBase.'_privacy_form' } = $fieldPrivacy;
|
||||
$var->{$fieldBase.'_field_viewable' } = $fieldViewable;
|
||||
$var->{$fieldBase.'_privacy_setting' } = $fieldPrivacySetting;
|
||||
$var->{$fieldBase.'_privacy_is_'.$rawPrivacySetting } = $rawPrivacySetting;
|
||||
|
||||
push(@fields, {
|
||||
'profile_field_id' => $fieldId,
|
||||
'profile_field_form' => $fieldForm,
|
||||
'profile_field_label' => $fieldLabel,
|
||||
'profile_field_subtext' => $field->isRequired ? "*" : undef,
|
||||
'profile_field_extras' => $field->getExtras,
|
||||
'profile_field_privacy' => $fieldPrivacy,
|
||||
'profile_field_id' => $fieldId,
|
||||
'profile_field_form' => $fieldForm,
|
||||
'profile_field_label' => $fieldLabel,
|
||||
'profile_field_required' => $fieldRequired,
|
||||
'profile_field_extras' => $fieldExtras,
|
||||
'profile_field_viewable' => $fieldViewable,
|
||||
'profile_field_privacy_form' => $fieldPrivacy,
|
||||
'profile_field_privacy_setting' => $fieldPrivacySetting,
|
||||
'profile_field_privacy_is_'.$rawPrivacySetting => $rawPrivacySetting,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -420,7 +433,15 @@ sub www_editSave {
|
|||
push (@{$retHash->{errors}},@{$retHash->{warnings}});
|
||||
|
||||
unless(scalar(@{$retHash->{errors}})) {
|
||||
$session->user->updateProfileFields( $retHash->{profile} );
|
||||
my $profile = $retHash->{profile};
|
||||
my $privacy = {};
|
||||
foreach my $fieldName (keys %{$profile}) {
|
||||
$session->user->profileField($fieldName,$profile->{$fieldName});
|
||||
my $privacySetting = $session->form->get("privacy_".$fieldName);
|
||||
next unless $privacySetting;
|
||||
$privacy->{$fieldName} = $privacySetting;
|
||||
}
|
||||
$session->user->setProfileFieldPrivacySetting($privacy);
|
||||
}
|
||||
|
||||
#Store the category the error occurred in the object for reference
|
||||
|
|
@ -457,6 +478,8 @@ sub www_view {
|
|||
#Overwrite these
|
||||
$var->{'user_full_name' } = $user->getWholeName;
|
||||
$var->{'user_member_since' } = $user->dateCreated;
|
||||
$var->{'profile_user_id' } = $user->userId;
|
||||
$var->{'can_edit_profile' } = $uid eq $session->user->userId;
|
||||
|
||||
#Check user privileges
|
||||
unless ($user->profileIsViewable($session->user)) {
|
||||
|
|
@ -469,28 +492,38 @@ sub www_view {
|
|||
);
|
||||
}
|
||||
|
||||
#Cache the privacy settings
|
||||
my $privacySettingsHash = WebGUI::ProfileField->getPrivacyOptions($session);
|
||||
$var->{'profile_category_loop' } = [];
|
||||
foreach my $category (@{WebGUI::ProfileCategory->getCategories($session,{ visible => 1})}) {
|
||||
my @fields = ();
|
||||
foreach my $field (@{$category->getFields({ visible => 1 })}) {
|
||||
my $fieldId = $field->getId;
|
||||
my $fieldLabel = $field->getLabel;
|
||||
my $fieldValue = $field->formField(undef,2,$user);
|
||||
my $fieldRaw = $user->profileField($fieldId);;
|
||||
next unless ($user->canViewField($field->getId,$session->user));
|
||||
my $rawPrivacySetting = $user->getProfileFieldPrivacySetting($field->getId);
|
||||
my $privacySetting = $privacySettingsHash->{$rawPrivacySetting};
|
||||
my $fieldId = $field->getId;
|
||||
my $fieldLabel = $field->getLabel;
|
||||
my $fieldValue = $field->formField(undef,2,$user);
|
||||
my $fieldRaw = $user->profileField($fieldId);;
|
||||
#Create a seperate template var for each field
|
||||
$var->{'profile_field_'.$fieldId.'_label' } = $fieldLabel;
|
||||
$var->{'profile_field_'.$fieldId.'_value' } = $fieldValue;
|
||||
$var->{'profile_field_'.$fieldId.'_raw' } = $fieldRaw;
|
||||
|
||||
my $fieldBase = 'profile_field_'.$fieldId;
|
||||
$var->{$fieldBase.'_label' } = $fieldLabel;
|
||||
$var->{$fieldBase.'_value' } = $fieldValue;
|
||||
$var->{$fieldBase.'_raw' } = $fieldRaw;
|
||||
$var->{$fieldBase.'_privacySetting' } = $privacySetting;
|
||||
$var->{$fieldBase.'_privacy_is_'.$rawPrivacySetting } = "true";
|
||||
push(@fields, {
|
||||
'profile_field_id' => $fieldId,
|
||||
'profile_field_is_'.$fieldId => "true",
|
||||
'profile_field_label' => $fieldLabel,
|
||||
'profile_field_value' => $fieldValue,
|
||||
'profile_field_raw' => $fieldRaw
|
||||
'profile_field_id' => $fieldId,
|
||||
'profile_field_is_'.$fieldId => "true",
|
||||
'profile_field_label' => $fieldLabel,
|
||||
'profile_field_value' => $fieldValue,
|
||||
'profile_field_raw' => $fieldRaw,
|
||||
'profile_field_privacySetting' => $privacySetting,
|
||||
'profile_field_privacy_is_'.$rawPrivacySetting => "true",
|
||||
});
|
||||
}
|
||||
|
||||
#Don't bother displaying the category if there's nothing in it.
|
||||
next unless (scalar(@fields));
|
||||
#Append the category variables
|
||||
$self->appendCategoryVars($var,$category,\@fields);
|
||||
}
|
||||
|
|
@ -503,8 +536,6 @@ sub www_view {
|
|||
my $privacySetting = $user->profileField("publicProfile") || "none";
|
||||
$var->{'profile_privacy_'.$privacySetting } = "true";
|
||||
|
||||
$var->{'profile_user_id' } = $user->userId;
|
||||
$var->{'can_edit_profile' } = $uid eq $session->user->userId;
|
||||
$var->{'acceptsPrivateMessages'} = $user->acceptsPrivateMessages($session->user->userId);
|
||||
$var->{'acceptsFriendsRequests'} = $user->acceptsFriendsRequests($session->user);
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ Return true iff fieldName is reserved and therefore not usable as a profile fiel
|
|||
sub isReservedFieldName {
|
||||
my $class = shift;
|
||||
my $fieldName = shift;
|
||||
return isIn($fieldName, ('func', 'op'));
|
||||
return isIn($fieldName, ('func', 'op', 'wg_privacySettings'));
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -337,7 +337,10 @@ Returns a WebGUI::ProfileCategory object for the category that this profile fiel
|
|||
|
||||
sub getCategory {
|
||||
my $self = shift;
|
||||
return WebGUI::ProfileCategory->new($self->session,$self->get("profileCategoryId"));
|
||||
unless ($self->{_category}) {
|
||||
$self->{_category} = WebGUI::ProfileCategory->new($self->session,$self->get("profileCategoryId"));
|
||||
}
|
||||
return $self->{_category};
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -440,6 +443,27 @@ sub getFormControlClass {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=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.
|
||||
|
|
@ -512,7 +536,7 @@ Returns a boolean indicating whether this field may be editable by a user.
|
|||
|
||||
sub isEditable {
|
||||
my $self = shift;
|
||||
return $self->get("editable") || $self->isRequired;
|
||||
return $self->getCategory->isEditable && ($self->get("editable") || $self->isRequired);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -575,8 +599,8 @@ Returns a boolean indicating whether this field may be viewed by a user.
|
|||
=cut
|
||||
|
||||
sub isViewable {
|
||||
my $self = shift;
|
||||
return $self->get("visible");
|
||||
my $self = shift;
|
||||
return $self->getCategory->isViewable && $self->get("visible");
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ use WebGUI::DatabaseLink;
|
|||
use WebGUI::Exception;
|
||||
use WebGUI::Utility;
|
||||
use WebGUI::Operation::Shared;
|
||||
use JSON;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
|
@ -258,6 +259,42 @@ sub canUseAdminMode {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 canViewField ( field, user)
|
||||
|
||||
Returns whether or not the user passed in can view the field value for the user.
|
||||
This will only check the user level privileges.
|
||||
|
||||
=head3 field
|
||||
|
||||
Field to check privileges on
|
||||
|
||||
=head3 user
|
||||
|
||||
User to check field privileges for
|
||||
|
||||
=cut
|
||||
|
||||
sub canViewField {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $field = shift;
|
||||
my $user = shift;
|
||||
|
||||
return 0 unless ($field && $user);
|
||||
#Always true for yourself
|
||||
return 1 if ($self->userId eq $user->userId);
|
||||
|
||||
my $privacySetting = $self->getProfileFieldPrivacySetting($field);
|
||||
return 0 unless (WebGUI::Utility::isIn($privacySetting,qw(all none friends)));
|
||||
return 1 if ($privacySetting eq "all");
|
||||
return 0 if ($privacySetting eq "none");
|
||||
|
||||
#It's friends so return whether or not user is a friend
|
||||
return WebGUI::Friends->new($session,$self)->isFriend($user->userId);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 dateCreated ( )
|
||||
|
||||
Returns the epoch for when this user was created.
|
||||
|
|
@ -449,6 +486,42 @@ sub getGroupIdsRecursive {
|
|||
return [ keys %groupIds ];
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getProfileFieldPrivacySetting ( [field ])
|
||||
|
||||
Returns the privacy setting for the field passed in. If no field is passed in the entire hash is returned
|
||||
|
||||
=head3 field
|
||||
|
||||
Field to get privacy setting for.
|
||||
|
||||
=cut
|
||||
|
||||
sub getProfileFieldPrivacySetting {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $field = shift;
|
||||
|
||||
unless ($self->{_privacySettings}) {
|
||||
#Look it up manually because we want to cache this separately.
|
||||
my $privacySettings = $session->db->quickScalar(
|
||||
q{select wg_privacySettings from userProfileData where userId=?},
|
||||
[$self->userId]
|
||||
);
|
||||
$privacySettings = "{}" unless $privacySettings;
|
||||
$self->{_privacySettings} = JSON->new->decode($privacySettings);
|
||||
}
|
||||
|
||||
return $self->{_privacySettings} unless ($field);
|
||||
|
||||
#No privacy settings returned the privacy setting field
|
||||
return "none" if($field eq "wg_privacySettings");
|
||||
|
||||
return $self->{_privacySettings}->{$field};
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getProfileUrl ( [page] )
|
||||
|
|
@ -806,6 +879,7 @@ sub profileField {
|
|||
my $fieldName = shift;
|
||||
my $value = shift;
|
||||
my $db = $self->session->db;
|
||||
return "" if ($fieldName eq "wg_privacySettings"); # this is a special internal field, don't try to process it.
|
||||
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;
|
||||
|
|
@ -902,6 +976,43 @@ sub session {
|
|||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 setProfileFieldPrivacySetting ( settings )
|
||||
|
||||
Sets the profile field privacy settings
|
||||
|
||||
=head3 settings
|
||||
|
||||
hash ref containing the field and it's corresponding privacy setting
|
||||
|
||||
=cut
|
||||
|
||||
sub setProfileFieldPrivacySetting {
|
||||
my $self = shift;
|
||||
my $session = $self->session;
|
||||
my $settings = shift;
|
||||
|
||||
return undef unless scalar(keys %{$settings});
|
||||
|
||||
#Get the current settings
|
||||
my $currentSettings = $self->getProfileFieldPrivacySetting;
|
||||
|
||||
foreach my $fieldId (keys %{$settings}) {
|
||||
my $privacySetting = $settings->{$fieldId};
|
||||
next unless (WebGUI::Utility::isIn($privacySetting,qw(all none friends)));
|
||||
$currentSettings->{$fieldId} = $settings->{$fieldId};
|
||||
}
|
||||
|
||||
#Store the data in the database
|
||||
my $json = JSON->new->encode($currentSettings);
|
||||
$session->db->write("update userProfileData set wg_privacySettings=? where userId=?",[$json,$self->userId]);
|
||||
|
||||
#Recache the current settings
|
||||
$self->{_privacySettings} = $currentSettings;
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 status ( [ value ] )
|
||||
|
|
|
|||
|
|
@ -160,7 +160,15 @@ our $I18N = {
|
|||
lastUpdated => 1225724810,
|
||||
},
|
||||
|
||||
'set by admin' => {
|
||||
message => q{site administrator has set this field to not be visible },
|
||||
lastUpdated => 1225724810,
|
||||
},
|
||||
|
||||
'required field' => {
|
||||
message => q{required },
|
||||
lastUpdated => 1225724810,
|
||||
},
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -3603,17 +3603,17 @@ LongTruncOk=1</p>
|
|||
},
|
||||
|
||||
'user profile field private message allow label' => {
|
||||
message => q|Allow All|,
|
||||
message => q|Public|,
|
||||
lastUpdated => 1181019679,
|
||||
},
|
||||
|
||||
'user profile field private message friends only label' => {
|
||||
message => q|Allow From My Friends Only|,
|
||||
message => q|Friends Only|,
|
||||
lastUpdated => 1181019679,
|
||||
},
|
||||
|
||||
'user profile field private message allow none label' => {
|
||||
message => q|Allow None|,
|
||||
message => q|Private|,
|
||||
lastUpdated => 1181019679,
|
||||
},
|
||||
|
||||
|
|
@ -4306,6 +4306,12 @@ Users may override this setting in their profile.
|
|||
context => q{i18n label for time duration in WebGUI::DateTime},
|
||||
},
|
||||
|
||||
'profile privacy settings' => {
|
||||
message => q{Privacy Settings},
|
||||
lastUpdated => 1226706547,
|
||||
context => q{i18n label for time duration in WebGUI::DateTime},
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue