diff --git a/app/controllers/my_profile/profile_members_controller.rb b/app/controllers/my_profile/profile_members_controller.rb index 8fc39be..a1abff7 100644 --- a/app/controllers/my_profile/profile_members_controller.rb +++ b/app/controllers/my_profile/profile_members_controller.rb @@ -2,8 +2,16 @@ class ProfileMembersController < MyProfileController protect 'manage_memberships', :profile def index - @members = profile.members_by_name - @member_role = environment.roles.find_by_name('member') + @filters = params[:filters] || {:roles => []} + @filters[:roles] = [] unless @filters[:roles] + @data = {} + field = 'name' + field = 'email' if @filters[:name] =~ /\@/ + + @data[:members] = profile.members_by(field,@filters[:name]).by_role(@filters[:roles]) + session[:members_filtered] = @data[:members].map{|m|m.id} if request.post? + @data[:roles] = Profile::Roles.organization_member_roles(environment.id) + end def update_roles @@ -156,4 +164,13 @@ class ProfileMembersController < MyProfileController end end + def search_members + field = 'name' + field = 'email' if params[:filter_name] =~ /\@/ + + result = profile.members_like field, params[:filter_name] + result = result.select{|member| member.can_view_field?(current_person, "email") } if field=="email" + render :json => result.map { |member| {:label => "#{member.name}#{member.can_view_field?(current_person, "email") ? " <#{member.email}>" : ""}", :value => member.name }} + end + end diff --git a/app/controllers/public/profile_controller.rb b/app/controllers/public/profile_controller.rb index af29bc0..eec2a08 100644 --- a/app/controllers/public/profile_controller.rb +++ b/app/controllers/public/profile_controller.rb @@ -370,6 +370,7 @@ class ProfileController < PublicController def send_mail @mailing = profile.mailings.build(params[:mailing]) + @mailing.data = session[:members_filtered] ? {:members_filtered => session[:members_filtered]} : {} if request.post? @mailing.locale = locale @mailing.person = user diff --git a/app/helpers/forms_helper.rb b/app/helpers/forms_helper.rb index 7f04574..c0641cd 100644 --- a/app/helpers/forms_helper.rb +++ b/app/helpers/forms_helper.rb @@ -7,9 +7,10 @@ module FormsHelper def labelled_check_box( human_name, name, value = "1", checked = false, options = {} ) options[:id] ||= 'checkbox-' + FormsHelper.next_id_number - hidden_field_tag(name, '0') + - check_box_tag( name, value, checked, options ) + - content_tag( 'label', human_name, :for => options[:id] ) + html = options[:add_hidden] == false ? "" : hidden_field_tag(name, '0') + + html += check_box_tag( name, value, checked, options ) + + content_tag( 'label', human_name, :for => options[:id] ) end def labelled_text_field( human_name, name, value=nil, options={} ) diff --git a/app/mailers/mailing.rb b/app/mailers/mailing.rb index cb16a6a..5995f0f 100644 --- a/app/mailers/mailing.rb +++ b/app/mailers/mailing.rb @@ -2,7 +2,10 @@ require_dependency 'mailing_job' class Mailing < ActiveRecord::Base - attr_accessible :subject, :body + acts_as_having_settings :field => :data + + attr_accessible :subject, :body, :data + validates_presence_of :source_id, :subject, :body belongs_to :source, :foreign_key => :source_id, :polymorphic => true belongs_to :person diff --git a/app/mailers/organization_mailing.rb b/app/mailers/organization_mailing.rb index 1829a21..9e45813 100644 --- a/app/mailers/organization_mailing.rb +++ b/app/mailers/organization_mailing.rb @@ -5,9 +5,16 @@ class OrganizationMailing < Mailing end def recipients(offset=0, limit=100) - source.members.order(:id).offset(offset).limit(limit) + if data.present? and data.is_a?(Hash) and data[:members_filtered] + result = source.members.where('profiles.id IN (?)', data[:members_filtered]) + end + + if result.blank? + result = source.members.order(:id).offset(offset).limit(limit) .joins("LEFT OUTER JOIN mailing_sents m ON (m.mailing_id = #{id} AND m.person_id = profiles.id)") .where("m.person_id" => nil) + end + result end def each_recipient diff --git a/app/models/person.rb b/app/models/person.rb index 88c84a0..0671773 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -16,10 +16,13 @@ class Person < Profile acts_as_trackable :after_add => Proc.new {|p,t| notify_activity(t)} acts_as_accessor - scope :members_of, -> resources { + scope :members_of, lambda { |resources, field = ''| resources = Array(resources) + joins = [:role_assignments] + joins << :user if User.attribute_names.include? field + conditions = resources.map {|resource| "role_assignments.resource_type = '#{resource.class.base_class.name}' AND role_assignments.resource_id = #{resource.id || -1}"}.join(' OR ') - distinct.select('profiles.*').joins(:role_assignments).where([conditions]) + select('DISTINCT profiles.*').joins(joins).where([conditions]) } scope :not_members_of, -> resources { @@ -48,6 +51,14 @@ class Person < Profile ['( roles.key = ? AND role_assignments.accessor_type = ? AND role_assignments.accessor_id = ? ) OR ( ( ( friendships.person_id = ? ) OR (profiles.public_profile = ?)) AND (profiles.visible = ?) )', 'environment_administrator', Profile.name, person.id, person.id, true, true] ).uniq + } + scope :by_role, lambda { |roles| + + roles = [roles] unless roles.kind_of?(Array) + + if roles.length > 0 + {:select => 'DISTINCT profiles.*', :joins => :role_assignments, :conditions => ['role_assignments.role_id IN (?)', roles] } + end } diff --git a/app/models/profile.rb b/app/models/profile.rb index 70ad351..51364a7 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -155,15 +155,23 @@ class Profile < ActiveRecord::Base include TimeScopes - def members + def members(by_field = '') scopes = plugins.dispatch_scopes(:organization_members, self) - scopes << Person.members_of(self) + scopes << Person.members_of(self,by_field) return scopes.first if scopes.size == 1 ScopeTool.union *scopes end - def members_by_name - members.order('profiles.name') + def members_by(field,value = nil) + if value and !value.blank? + members_like(field,value).order('profiles.name') + else + members.order('profiles.name') + end + end + + def members_like(field,value) + members(field).where("LOWER(#{field}) LIKE ?", "%#{value.downcase}%") if value end class << self @@ -1098,6 +1106,10 @@ private :generate_url, :url_options end end + def can_view_field? current_person, field + display_private_info_to?(current_person) || (public_fields.include?(field) && public?) + end + validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true def preferred_login_redirection redirection_after_login.blank? ? environment.redirection_after_login : redirection_after_login diff --git a/app/views/profile/send_mail.html.erb b/app/views/profile/send_mail.html.erb index 86cdead..b994e88 100644 --- a/app/views/profile/send_mail.html.erb +++ b/app/views/profile/send_mail.html.erb @@ -4,6 +4,9 @@ <%= error_messages_for :mailing %> + <% to = @mailing.data[:members_filtered].present? ? @mailing.recipients.map{|r| r.name}.join(', ') : _('All members')%> + <%= labelled_form_field(_('To:'), text_area(:data, 'members_filtered', :value => to, :rows => 4, :disabled => 'disabled', :class => 'send-mail-recipients')) %> + <%= form_for :mailing, :url => {:action => 'send_mail'}, :html => {:id => 'mailing-form'} do |f| %> <%= labelled_form_field(_('Subject:'), f.text_field(:subject)) %> diff --git a/app/views/profile_members/_members_filter.erb b/app/views/profile_members/_members_filter.erb new file mode 100644 index 0000000..cbdd0c4 --- /dev/null +++ b/app/views/profile_members/_members_filter.erb @@ -0,0 +1,18 @@ +<%= form_tag '#', :method => 'post' do %> + + <%= field_set_tag _('Filter'), :class => 'filter_fields' do %> +
+ <%= labelled_text_field(_('Name or Email')+': ', "filters[name]", @filters[:name], {:id => 'filter-name-autocomplete',:size => 30}) %> +
+ +<%= _('Roles:') %>
+ <% @data[:roles].each do |r| %> + <%= labelled_check_box(r.name, 'filters[roles][]', r.id, @filters[:roles].include?(r.id.to_s), :add_hidden => false) %>+ <%= submit_button(:search, _('Search')) %> +
+ <% end %> +<% end %> + +<%= javascript_include_tag params[:controller] %> \ No newline at end of file diff --git a/app/views/profile_members/_members_list.html.erb b/app/views/profile_members/_members_list.html.erb index fcf4279..2c92a87 100644 --- a/app/views/profile_members/_members_list.html.erb +++ b/app/views/profile_members/_members_list.html.erb @@ -1,4 +1,5 @@ -<% collection = @collection == :profile_admins ? profile.admins : profile.members_by_name %> +<% members = @data ? @data[:members] : profile.members_by('name') %> +<% collection = @collection == :profile_admins ? profile.admins : members %> <% title = @title ? @title : _('Current members') %> <% remove_action = @remove_action ? @remove_action : {:action => 'unassociate'} %> @@ -9,6 +10,7 @@+ <%= _('No members found to: %s') % profile.name %> +
+<% end %> diff --git a/app/views/profile_members/index.html.erb b/app/views/profile_members/index.html.erb index 62b7b77..bfc2f0e 100644 --- a/app/views/profile_members/index.html.erb +++ b/app/views/profile_members/index.html.erb @@ -2,6 +2,8 @@ <%= render :partial => 'index_buttons' %> +<%= render :partial => 'members_filter' %> +