Chris@0: # ActsAsWatchable Chris@0: module Redmine Chris@0: module Acts Chris@0: module Watchable Chris@0: def self.included(base) Chris@0: base.extend ClassMethods Chris@0: end Chris@0: Chris@0: module ClassMethods Chris@0: def acts_as_watchable(options = {}) Chris@0: return if self.included_modules.include?(Redmine::Acts::Watchable::InstanceMethods) Chris@0: send :include, Redmine::Acts::Watchable::InstanceMethods Chris@0: Chris@0: class_eval do Chris@0: has_many :watchers, :as => :watchable, :dependent => :delete_all Chris@0: has_many :watcher_users, :through => :watchers, :source => :user Chris@0: Chris@0: named_scope :watched_by, lambda { |user_id| Chris@0: { :include => :watchers, Chris@0: :conditions => ["#{Watcher.table_name}.user_id = ?", user_id] } Chris@0: } Chris@0: attr_protected :watcher_ids, :watcher_user_ids Chris@0: end Chris@0: end Chris@0: end Chris@0: Chris@0: module InstanceMethods Chris@0: def self.included(base) Chris@0: base.extend ClassMethods Chris@0: end Chris@0: Chris@0: # Returns an array of users that are proposed as watchers Chris@0: def addable_watcher_users Chris@0: self.project.users.sort - self.watcher_users Chris@0: end Chris@0: Chris@0: # Adds user as a watcher Chris@0: def add_watcher(user) Chris@0: self.watchers << Watcher.new(:user => user) Chris@0: end Chris@0: Chris@0: # Removes user from the watchers list Chris@0: def remove_watcher(user) Chris@0: return nil unless user && user.is_a?(User) Chris@0: Watcher.delete_all "watchable_type = '#{self.class}' AND watchable_id = #{self.id} AND user_id = #{user.id}" Chris@0: end Chris@0: Chris@0: # Adds/removes watcher Chris@0: def set_watcher(user, watching=true) Chris@0: watching ? add_watcher(user) : remove_watcher(user) Chris@0: end Chris@0: Chris@0: # Returns true if object is watched by +user+ Chris@0: def watched_by?(user) Chris@0: !!(user && self.watcher_user_ids.detect {|uid| uid == user.id }) Chris@0: end Chris@0: Chris@0: # Returns an array of watchers' email addresses Chris@0: def watcher_recipients Chris@0: notified = watcher_users.active Chris@0: Chris@0: if respond_to?(:visible?) Chris@0: notified.reject! {|user| !visible?(user)} Chris@0: end Chris@0: notified.collect(&:mail).compact Chris@0: end Chris@0: Chris@0: module ClassMethods; end Chris@0: end Chris@0: end Chris@0: end Chris@0: end