##// END OF EJS Templates
Refactor: Move recipients method into acts_as_event...
Eric Davis -
r3244:358e3194d79b
parent child
Show More
@@ -1,56 +1,49
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class Document < ActiveRecord::Base
18 class Document < ActiveRecord::Base
19 belongs_to :project
19 belongs_to :project
20 belongs_to :category, :class_name => "DocumentCategory", :foreign_key => "category_id"
20 belongs_to :category, :class_name => "DocumentCategory", :foreign_key => "category_id"
21 acts_as_attachable :delete_permission => :manage_documents
21 acts_as_attachable :delete_permission => :manage_documents
22
22
23 acts_as_searchable :columns => ['title', "#{table_name}.description"], :include => :project
23 acts_as_searchable :columns => ['title', "#{table_name}.description"], :include => :project
24 acts_as_event :title => Proc.new {|o| "#{l(:label_document)}: #{o.title}"},
24 acts_as_event :title => Proc.new {|o| "#{l(:label_document)}: #{o.title}"},
25 :author => Proc.new {|o| (a = o.attachments.find(:first, :order => "#{Attachment.table_name}.created_on ASC")) ? a.author : nil },
25 :author => Proc.new {|o| (a = o.attachments.find(:first, :order => "#{Attachment.table_name}.created_on ASC")) ? a.author : nil },
26 :url => Proc.new {|o| {:controller => 'documents', :action => 'show', :id => o.id}}
26 :url => Proc.new {|o| {:controller => 'documents', :action => 'show', :id => o.id}}
27 acts_as_activity_provider :find_options => {:include => :project}
27 acts_as_activity_provider :find_options => {:include => :project}
28
28
29 validates_presence_of :project, :title, :category
29 validates_presence_of :project, :title, :category
30 validates_length_of :title, :maximum => 60
30 validates_length_of :title, :maximum => 60
31
31
32 def visible?(user=User.current)
32 def visible?(user=User.current)
33 !user.nil? && user.allowed_to?(:view_documents, project)
33 !user.nil? && user.allowed_to?(:view_documents, project)
34 end
34 end
35
35
36 def after_initialize
36 def after_initialize
37 if new_record?
37 if new_record?
38 self.category ||= DocumentCategory.default
38 self.category ||= DocumentCategory.default
39 end
39 end
40 end
40 end
41
41
42 def updated_on
42 def updated_on
43 unless @updated_on
43 unless @updated_on
44 a = attachments.find(:first, :order => 'created_on DESC')
44 a = attachments.find(:first, :order => 'created_on DESC')
45 @updated_on = (a && a.created_on) || created_on
45 @updated_on = (a && a.created_on) || created_on
46 end
46 end
47 @updated_on
47 @updated_on
48 end
48 end
49
50 # Returns the mail adresses of users that should be notified
51 def recipients
52 notified = project.notified_users
53 notified.reject! {|user| !visible?(user)}
54 notified.collect(&:mail)
55 end
56 end
49 end
@@ -1,105 +1,98
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class Message < ActiveRecord::Base
18 class Message < ActiveRecord::Base
19 belongs_to :board
19 belongs_to :board
20 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
20 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
21 acts_as_tree :counter_cache => :replies_count, :order => "#{Message.table_name}.created_on ASC"
21 acts_as_tree :counter_cache => :replies_count, :order => "#{Message.table_name}.created_on ASC"
22 acts_as_attachable
22 acts_as_attachable
23 belongs_to :last_reply, :class_name => 'Message', :foreign_key => 'last_reply_id'
23 belongs_to :last_reply, :class_name => 'Message', :foreign_key => 'last_reply_id'
24
24
25 acts_as_searchable :columns => ['subject', 'content'],
25 acts_as_searchable :columns => ['subject', 'content'],
26 :include => {:board => :project},
26 :include => {:board => :project},
27 :project_key => 'project_id',
27 :project_key => 'project_id',
28 :date_column => "#{table_name}.created_on"
28 :date_column => "#{table_name}.created_on"
29 acts_as_event :title => Proc.new {|o| "#{o.board.name}: #{o.subject}"},
29 acts_as_event :title => Proc.new {|o| "#{o.board.name}: #{o.subject}"},
30 :description => :content,
30 :description => :content,
31 :type => Proc.new {|o| o.parent_id.nil? ? 'message' : 'reply'},
31 :type => Proc.new {|o| o.parent_id.nil? ? 'message' : 'reply'},
32 :url => Proc.new {|o| {:controller => 'messages', :action => 'show', :board_id => o.board_id}.merge(o.parent_id.nil? ? {:id => o.id} :
32 :url => Proc.new {|o| {:controller => 'messages', :action => 'show', :board_id => o.board_id}.merge(o.parent_id.nil? ? {:id => o.id} :
33 {:id => o.parent_id, :anchor => "message-#{o.id}"})}
33 {:id => o.parent_id, :anchor => "message-#{o.id}"})}
34
34
35 acts_as_activity_provider :find_options => {:include => [{:board => :project}, :author]},
35 acts_as_activity_provider :find_options => {:include => [{:board => :project}, :author]},
36 :author_key => :author_id
36 :author_key => :author_id
37 acts_as_watchable
37 acts_as_watchable
38
38
39 attr_protected :locked, :sticky
39 attr_protected :locked, :sticky
40 validates_presence_of :board, :subject, :content
40 validates_presence_of :board, :subject, :content
41 validates_length_of :subject, :maximum => 255
41 validates_length_of :subject, :maximum => 255
42
42
43 after_create :add_author_as_watcher
43 after_create :add_author_as_watcher
44
44
45 def visible?(user=User.current)
45 def visible?(user=User.current)
46 !user.nil? && user.allowed_to?(:view_messages, project)
46 !user.nil? && user.allowed_to?(:view_messages, project)
47 end
47 end
48
48
49 def validate_on_create
49 def validate_on_create
50 # Can not reply to a locked topic
50 # Can not reply to a locked topic
51 errors.add_to_base 'Topic is locked' if root.locked? && self != root
51 errors.add_to_base 'Topic is locked' if root.locked? && self != root
52 end
52 end
53
53
54 def after_create
54 def after_create
55 if parent
55 if parent
56 parent.reload.update_attribute(:last_reply_id, self.id)
56 parent.reload.update_attribute(:last_reply_id, self.id)
57 end
57 end
58 board.reset_counters!
58 board.reset_counters!
59 end
59 end
60
60
61 def after_update
61 def after_update
62 if board_id_changed?
62 if board_id_changed?
63 Message.update_all("board_id = #{board_id}", ["id = ? OR parent_id = ?", root.id, root.id])
63 Message.update_all("board_id = #{board_id}", ["id = ? OR parent_id = ?", root.id, root.id])
64 Board.reset_counters!(board_id_was)
64 Board.reset_counters!(board_id_was)
65 Board.reset_counters!(board_id)
65 Board.reset_counters!(board_id)
66 end
66 end
67 end
67 end
68
68
69 def after_destroy
69 def after_destroy
70 board.reset_counters!
70 board.reset_counters!
71 end
71 end
72
72
73 def sticky=(arg)
73 def sticky=(arg)
74 write_attribute :sticky, (arg == true || arg.to_s == '1' ? 1 : 0)
74 write_attribute :sticky, (arg == true || arg.to_s == '1' ? 1 : 0)
75 end
75 end
76
76
77 def sticky?
77 def sticky?
78 sticky == 1
78 sticky == 1
79 end
79 end
80
80
81 def project
81 def project
82 board.project
82 board.project
83 end
83 end
84
84
85 def editable_by?(usr)
85 def editable_by?(usr)
86 usr && usr.logged? && (usr.allowed_to?(:edit_messages, project) || (self.author == usr && usr.allowed_to?(:edit_own_messages, project)))
86 usr && usr.logged? && (usr.allowed_to?(:edit_messages, project) || (self.author == usr && usr.allowed_to?(:edit_own_messages, project)))
87 end
87 end
88
88
89 def destroyable_by?(usr)
89 def destroyable_by?(usr)
90 usr && usr.logged? && (usr.allowed_to?(:delete_messages, project) || (self.author == usr && usr.allowed_to?(:delete_own_messages, project)))
90 usr && usr.logged? && (usr.allowed_to?(:delete_messages, project) || (self.author == usr && usr.allowed_to?(:delete_own_messages, project)))
91 end
91 end
92
92
93 # Returns the mail adresses of users that should be notified
94 def recipients
95 notified = project.notified_users
96 notified.reject! {|user| !visible?(user)}
97 notified.collect(&:mail)
98 end
99
100 private
93 private
101
94
102 def add_author_as_watcher
95 def add_author_as_watcher
103 Watcher.create(:watchable => self.root, :user => author)
96 Watcher.create(:watchable => self.root, :user => author)
104 end
97 end
105 end
98 end
@@ -1,47 +1,40
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2008 Jean-Philippe Lang
2 # Copyright (C) 2006-2008 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class News < ActiveRecord::Base
18 class News < ActiveRecord::Base
19 belongs_to :project
19 belongs_to :project
20 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
20 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
21 has_many :comments, :as => :commented, :dependent => :delete_all, :order => "created_on"
21 has_many :comments, :as => :commented, :dependent => :delete_all, :order => "created_on"
22
22
23 validates_presence_of :title, :description
23 validates_presence_of :title, :description
24 validates_length_of :title, :maximum => 60
24 validates_length_of :title, :maximum => 60
25 validates_length_of :summary, :maximum => 255
25 validates_length_of :summary, :maximum => 255
26
26
27 acts_as_searchable :columns => ['title', 'summary', "#{table_name}.description"], :include => :project
27 acts_as_searchable :columns => ['title', 'summary', "#{table_name}.description"], :include => :project
28 acts_as_event :url => Proc.new {|o| {:controller => 'news', :action => 'show', :id => o.id}}
28 acts_as_event :url => Proc.new {|o| {:controller => 'news', :action => 'show', :id => o.id}}
29 acts_as_activity_provider :find_options => {:include => [:project, :author]},
29 acts_as_activity_provider :find_options => {:include => [:project, :author]},
30 :author_key => :author_id
30 :author_key => :author_id
31
31
32 def visible?(user=User.current)
32 def visible?(user=User.current)
33 !user.nil? && user.allowed_to?(:view_news, project)
33 !user.nil? && user.allowed_to?(:view_news, project)
34 end
34 end
35
35
36 # Returns the mail adresses of users that should be notified
37 def recipients
38 notified = project.notified_users
39 notified.reject! {|user| !visible?(user)}
40 notified.collect(&:mail)
41 end
42
43 # returns latest news for projects visible by user
36 # returns latest news for projects visible by user
44 def self.latest(user = User.current, count = 5)
37 def self.latest(user = User.current, count = 5)
45 find(:all, :limit => count, :conditions => Project.allowed_to_condition(user, :view_news), :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC")
38 find(:all, :limit => count, :conditions => Project.allowed_to_condition(user, :view_news), :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC")
46 end
39 end
47 end
40 end
@@ -1,76 +1,83
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 module Redmine
18 module Redmine
19 module Acts
19 module Acts
20 module Event
20 module Event
21 def self.included(base)
21 def self.included(base)
22 base.extend ClassMethods
22 base.extend ClassMethods
23 end
23 end
24
24
25 module ClassMethods
25 module ClassMethods
26 def acts_as_event(options = {})
26 def acts_as_event(options = {})
27 return if self.included_modules.include?(Redmine::Acts::Event::InstanceMethods)
27 return if self.included_modules.include?(Redmine::Acts::Event::InstanceMethods)
28 default_options = { :datetime => :created_on,
28 default_options = { :datetime => :created_on,
29 :title => :title,
29 :title => :title,
30 :description => :description,
30 :description => :description,
31 :author => :author,
31 :author => :author,
32 :url => {:controller => 'welcome'},
32 :url => {:controller => 'welcome'},
33 :type => self.name.underscore.dasherize }
33 :type => self.name.underscore.dasherize }
34
34
35 cattr_accessor :event_options
35 cattr_accessor :event_options
36 self.event_options = default_options.merge(options)
36 self.event_options = default_options.merge(options)
37 send :include, Redmine::Acts::Event::InstanceMethods
37 send :include, Redmine::Acts::Event::InstanceMethods
38 end
38 end
39 end
39 end
40
40
41 module InstanceMethods
41 module InstanceMethods
42 def self.included(base)
42 def self.included(base)
43 base.extend ClassMethods
43 base.extend ClassMethods
44 end
44 end
45
45
46 %w(datetime title description author type).each do |attr|
46 %w(datetime title description author type).each do |attr|
47 src = <<-END_SRC
47 src = <<-END_SRC
48 def event_#{attr}
48 def event_#{attr}
49 option = event_options[:#{attr}]
49 option = event_options[:#{attr}]
50 if option.is_a?(Proc)
50 if option.is_a?(Proc)
51 option.call(self)
51 option.call(self)
52 elsif option.is_a?(Symbol)
52 elsif option.is_a?(Symbol)
53 send(option)
53 send(option)
54 else
54 else
55 option
55 option
56 end
56 end
57 end
57 end
58 END_SRC
58 END_SRC
59 class_eval src, __FILE__, __LINE__
59 class_eval src, __FILE__, __LINE__
60 end
60 end
61
61
62 def event_date
62 def event_date
63 event_datetime.to_date
63 event_datetime.to_date
64 end
64 end
65
65
66 def event_url(options = {})
66 def event_url(options = {})
67 option = event_options[:url]
67 option = event_options[:url]
68 (option.is_a?(Proc) ? option.call(self) : send(option)).merge(options)
68 (option.is_a?(Proc) ? option.call(self) : send(option)).merge(options)
69 end
69 end
70
70
71 # Returns the mail adresses of users that should be notified
72 def recipients
73 notified = project.notified_users
74 notified.reject! {|user| !visible?(user)}
75 notified.collect(&:mail)
76 end
77
71 module ClassMethods
78 module ClassMethods
72 end
79 end
73 end
80 end
74 end
81 end
75 end
82 end
76 end
83 end
General Comments 0
You need to be logged in to leave comments. Login now