diff --git a/app/controllers/my_profile/profile_editor_controller.rb b/app/controllers/my_profile/profile_editor_controller.rb index b63493c..d42024f 100644 --- a/app/controllers/my_profile/profile_editor_controller.rb +++ b/app/controllers/my_profile/profile_editor_controller.rb @@ -14,6 +14,7 @@ class ProfileEditorController < MyProfileController @profile_data = profile @possible_domains = profile.possible_domains if request.post? + params[:profile_data][:fields_privacy] ||= {} if profile.person? && params[:profile_data].is_a?(Hash) begin Profile.transaction do Image.transaction do diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 6754783..169d4f4 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -866,7 +866,7 @@ module ApplicationHelper end else if profile.active_fields.include?(name) - result = field_html + result = content_tag('div', field_html + profile_field_privacy_selector(profile, name), :class => 'field-with-privacy-selector') end end @@ -881,6 +881,10 @@ module ApplicationHelper result end + def profile_field_privacy_selector(profile, name) + profile.public? ? content_tag('div', check_box_tag('profile_data[fields_privacy][' + name + ']', 'public', profile.public_fields.include?(name)) + label_tag('profile_data_fields_privacy_' + name, _('Public')), :class => 'field-privacy-selector') : '' + end + def template_stylesheet_path if profile.nil? "/designs/templates/#{environment.layout_template}/stylesheets/style.css" diff --git a/app/helpers/profile_editor_helper.rb b/app/helpers/profile_editor_helper.rb index f752ff4..1c6cb8b 100644 --- a/app/helpers/profile_editor_helper.rb +++ b/app/helpers/profile_editor_helper.rb @@ -145,4 +145,12 @@ module ProfileEditorHelper link_to title, url, :class => 'control-panel-%s' % icon end + def unchangeable_privacy_field(profile) + if profile.public? + check_box_tag('', '', true, :disabled => true) + ' ' + _('Public') + else + '' + end + end + end diff --git a/app/helpers/profile_helper.rb b/app/helpers/profile_helper.rb index fbfb6dd..e2e2415 100644 --- a/app/helpers/profile_helper.rb +++ b/app/helpers/profile_helper.rb @@ -1,7 +1,8 @@ module ProfileHelper def display_field(title, profile, field, force = false) - if !force && !profile.active_fields.include?(field.to_s) + if (!force && field.to_s != 'email' && !profile.active_fields.include?(field.to_s)) || + ((profile.active_fields.include?(field.to_s) || field.to_s == 'email') && !profile.public_fields.include?(field.to_s) && (!user || (user != profile && !user.is_a_friend?(profile)))) return '' end value = profile.send(field) diff --git a/app/models/person.rb b/app/models/person.rb index 7684717..9a76ecc 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -456,6 +456,10 @@ class Person < Profile Scrap.find_by_sql("SELECT id, updated_at, '#{Scrap.to_s}' AS klass FROM #{Scrap.table_name} WHERE scraps.receiver_id = #{self.id} AND scraps.scrap_id IS NULL UNION SELECT id, updated_at, '#{ActionTracker::Record.to_s}' AS klass FROM #{ActionTracker::Record.table_name} WHERE action_tracker.user_id = #{self.id} and action_tracker.verb != 'leave_scrap_to_self' and action_tracker.verb != 'add_member_in_community' ORDER BY updated_at DESC") end + def public_fields + self.fields_privacy.nil? ? self.active_fields : self.fields_privacy.reject{ |k, v| v != 'public' }.keys.map(&:to_s) + end + protected def followed_by?(profile) diff --git a/app/models/profile.rb b/app/models/profile.rb index 2db43c1..466391d 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -144,6 +144,7 @@ class Profile < ActiveRecord::Base settings_items :redirect_l10n, :type => :boolean, :default => false settings_items :public_content, :type => :boolean, :default => true settings_items :description + settings_items :fields_privacy, :type => :hash, :default => {} validates_length_of :description, :maximum => 550, :allow_nil => true @@ -876,6 +877,15 @@ private :generate_url, :url_options [] end + # field => privacy (e.g.: "address" => "public") + def fields_privacy + self.data[:fields_privacy] + end + + def public_fields + self.active_fields + end + private def self.f_categories_label_proc(environment) ids = environment.top_level_category_as_facet_ids diff --git a/app/views/profile/_person_profile.rhtml b/app/views/profile/_person_profile.rhtml index 02191a8..44530a7 100644 --- a/app/views/profile/_person_profile.rhtml +++ b/app/views/profile/_person_profile.rhtml @@ -13,15 +13,13 @@ <%= show_date(profile.created_at) %> - <% if profile == user || profile.friends.include?(user) %> - - <%= _('Contact')%> - - <%= display_field(_('Address:'), profile, :address) %> - <%= display_field(_('ZIP code:'), profile, :zip_code) %> - <%= display_field(_('Contact phone:'), profile, :contact_phone) %> - <%= display_field(_('e-Mail:'), profile, :email, true) { |email| link_to_email(email) } %> - <% end %> + + <%= _('Contact')%> + + <%= display_field(_('Address:'), profile, :address) %> + <%= display_field(_('ZIP code:'), profile, :zip_code) %> + <%= display_field(_('Contact phone:'), profile, :contact_phone) %> + <%= display_field(_('e-Mail:'), profile, :email) { |email| link_to_email(email) } %> <% cache_timeout(profile.relationships_cache_key, 4.hours) do %> <% if !(profile.organization.blank? && profile.organization_website.blank?) && (profile.active_fields.include?('organization') || profile.active_fields.include?('organization_website')) %> diff --git a/app/views/profile_editor/_person.rhtml b/app/views/profile_editor/_person.rhtml index 7589547..fc50c35 100644 --- a/app/views/profile_editor/_person.rhtml +++ b/app/views/profile_editor/_person.rhtml @@ -2,9 +2,19 @@ <%= required_fields_message %> - <%= required f.text_field(:name) %> +
+ <%= required f.text_field(:name) %> +
+ <%= unchangeable_privacy_field @profile %> +
+
- <%= required f.text_field(:email) %> +
+ <%= required f.text_field(:email) %> +
+ <%= profile_field_privacy_selector @profile, 'email' %> +
+
<%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_eval(&content) }.join("") %> diff --git a/app/views/profile_editor/edit.rhtml b/app/views/profile_editor/edit.rhtml index e8b7984..361c3f0 100644 --- a/app/views/profile_editor/edit.rhtml +++ b/app/views/profile_editor/edit.rhtml @@ -13,8 +13,11 @@ <%= render :partial => partial_for_class(@profile.class), :locals => { :f => f } %> <% unless @profile.person? && @environment.active_person_fields.include?('image') %> -
+

<%= _('Change picture') %>

+ <%= unchangeable_privacy_field @profile %> +
+
<% f.fields_for :image_builder, @profile.image do |i| %> <%= file_field_or_thumbnail(_('Image:'), @profile.image, i) %><%= _("Max size: %s (.jpg, .gif, .png)")% Image.max_size.to_humanreadable %> <% end %> diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css index e6f4ed8..153be0f 100644 --- a/public/stylesheets/application.css +++ b/public/stylesheets/application.css @@ -6097,3 +6097,49 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { margin: .8em 0 .2em; line-height: 1.5; } + +.controller-profile_editor #profile-data { + display: table; + width: auto; +} + +.field-with-privacy-selector { + display: table-row; +} + +.controller-profile_editor #profile-data .field-with-privacy-selector .formfieldline { + display: table-cell; + width: auto; +} + +.field-privacy-selector { + display: table-cell; + vertical-align: bottom; + text-align: center; + width: 100px; +} + +#profile_change_picture { + clear: both; + margin-top: 20px; +} + +#profile_change_picture_title { + display: table-row; + width: 100%; +} + +#profile_change_picture_title h2, +#profile_change_picture_title span { + display: table-cell; +} + +#profile_change_picture_title h2 { + padding-top: 20px; + width: auto; +} + +#profile_change_picture_title span { + width: 100px; + text-align: center; +} diff --git a/test/functional/profile_controller_test.rb b/test/functional/profile_controller_test.rb index fffb144..42be419 100644 --- a/test/functional/profile_controller_test.rb +++ b/test/functional/profile_controller_test.rb @@ -1371,4 +1371,80 @@ class ProfileControllerTest < ActionController::TestCase assert_redirected_to :action => 'members' end + should 'show all fields to anonymous user' do + viewed = create_user('person_1').person + Environment.any_instance.stubs(:active_person_fields).returns(['sex', 'birth_date']) + Environment.any_instance.stubs(:required_person_fields).returns([]) + viewed.birth_date = Time.now.ago(22.years) + viewed.data = { :sex => 'male', :fields_privacy => { 'sex' => 'public', 'birth_date' => 'public' } } + viewed.save! + get :index, :profile => viewed.identifier + assert_tag :tag => 'td', :content => 'Sex:' + assert_tag :tag => 'td', :content => 'Male' + assert_tag :tag => 'td', :content => 'Date of birth:' + assert_tag :tag => 'td', :content => 'August 26, 1990' + end + + should 'show some fields to anonymous user' do + viewed = create_user('person_1').person + Environment.any_instance.stubs(:active_person_fields).returns(['sex', 'birth_date']) + Environment.any_instance.stubs(:required_person_fields).returns([]) + viewed.birth_date = Time.now.ago(22.years) + viewed.data = { :sex => 'male', :fields_privacy => { 'sex' => 'public' } } + viewed.save! + get :index, :profile => viewed.identifier + assert_tag :tag => 'td', :content => 'Sex:' + assert_tag :tag => 'td', :content => 'Male' + assert_no_tag :tag => 'td', :content => 'Date of birth:' + assert_no_tag :tag => 'td', :content => 'August 26, 1990' + end + + should 'show some fields to non friend' do + viewed = create_user('person_1').person + Environment.any_instance.stubs(:active_person_fields).returns(['sex', 'birth_date']) + Environment.any_instance.stubs(:required_person_fields).returns([]) + viewed.birth_date = Time.now.ago(22.years) + viewed.data = { :sex => 'male', :fields_privacy => { 'sex' => 'public' } } + viewed.save! + strange = create_user('person_2').person + login_as(strange.identifier) + get :index, :profile => viewed.identifier + assert_tag :tag => 'td', :content => 'Sex:' + assert_tag :tag => 'td', :content => 'Male' + assert_no_tag :tag => 'td', :content => 'Date of birth:' + assert_no_tag :tag => 'td', :content => 'August 26, 1990' + end + + should 'show all fields to friend' do + viewed = create_user('person_1').person + friend = create_user('person_2').person + Environment.any_instance.stubs(:active_person_fields).returns(['sex', 'birth_date']) + Environment.any_instance.stubs(:required_person_fields).returns([]) + viewed.birth_date = Time.now.ago(22.years) + viewed.data = { :sex => 'male', :fields_privacy => { 'sex' => 'public' } } + viewed.save! + Person.any_instance.stubs(:is_a_friend?).returns(true) + login_as(friend.identifier) + get :index, :profile => viewed.identifier + assert_tag :tag => 'td', :content => 'Sex:' + assert_tag :tag => 'td', :content => 'Male' + assert_tag :tag => 'td', :content => 'Date of birth:' + assert_tag :tag => 'td', :content => 'August 26, 1990' + end + + should 'show all fields to self' do + viewed = create_user('person_1').person + Environment.any_instance.stubs(:active_person_fields).returns(['sex', 'birth_date']) + Environment.any_instance.stubs(:required_person_fields).returns([]) + viewed.birth_date = Time.now.ago(22.years) + viewed.data = { :sex => 'male', :fields_privacy => { 'sex' => 'public' } } + viewed.save! + login_as(viewed.identifier) + get :index, :profile => viewed.identifier + assert_tag :tag => 'td', :content => 'Sex:' + assert_tag :tag => 'td', :content => 'Male' + assert_tag :tag => 'td', :content => 'Date of birth:' + assert_tag :tag => 'td', :content => 'August 26, 1990' + end + end diff --git a/test/functional/profile_editor_controller_test.rb b/test/functional/profile_editor_controller_test.rb index b3fbeda..1af2662 100644 --- a/test/functional/profile_editor_controller_test.rb +++ b/test/functional/profile_editor_controller_test.rb @@ -979,4 +979,12 @@ class ProfileEditorControllerTest < ActionController::TestCase get :edit, :profile => profile.identifier assert_no_tag :tag => 'select', :attributes => {:id => 'profile_data_redirection_after_login'} end + + should 'uncheck all field privacy fields' do + person = profile + assert_nil person.fields_privacy + post :edit, :profile => profile.identifier, :profile_data => {} + assert_equal({}, person.reload.fields_privacy) + end + end diff --git a/test/unit/person_test.rb b/test/unit/person_test.rb index af7442a..e3f9e25 100644 --- a/test/unit/person_test.rb +++ b/test/unit/person_test.rb @@ -1262,4 +1262,18 @@ class PersonTest < ActiveSupport::TestCase assert person.has_permission?('bli', Profile.new) end + + should 'active fields are public if fields privacy is nil' do + p = fast_create(Person) + p.expects(:fields_privacy).returns(nil) + f = %w(sex birth_date) + p.expects(:active_fields).returns(f) + assert_equal f, p.public_fields + end + + should 'return public fields' do + p = fast_create(Person) + p.stubs(:fields_privacy).returns({ 'sex' => 'public', 'birth_date' => 'private' }) + assert_equal ['sex'], p.public_fields + end end diff --git a/test/unit/profile_test.rb b/test/unit/profile_test.rb index 29ba067..bff378d 100644 --- a/test/unit/profile_test.rb +++ b/test/unit/profile_test.rb @@ -1945,4 +1945,18 @@ class ProfileTest < ActiveSupport::TestCase end end + should 'public fields are active fields' do + p = fast_create(Profile) + f = %w(sex birth_date) + p.expects(:active_fields).returns(f) + assert_equal f, p.public_fields + end + + should 'return fields privacy' do + p = fast_create(Profile) + f = { 'sex' => 'public' } + p.data[:fields_privacy] = f + assert_equal f, p.fields_privacy + end + end -- libgit2 0.21.2