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