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