activity_notification 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +56 -0
- data/.rspec +3 -0
- data/.travis.yml +28 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +174 -0
- data/MIT-LICENSE +20 -0
- data/README.md +437 -0
- data/Rakefile +19 -0
- data/activity_notification.gemspec +33 -0
- data/app/controllers/activity_notification/notifications_controller.rb +119 -0
- data/app/controllers/activity_notification/notifications_with_devise_controller.rb +29 -0
- data/app/mailers/activity_notification/mailer.rb +13 -0
- data/app/views/activity_notification/mailer/default/default.html.erb +7 -0
- data/app/views/activity_notification/notifications/default/_default.html.erb +36 -0
- data/app/views/activity_notification/notifications/default/_index.html.erb +9 -0
- data/app/views/activity_notification/notifications/default/destroy.js.erb +2 -0
- data/app/views/activity_notification/notifications/default/index.html.erb +17 -0
- data/app/views/activity_notification/notifications/default/open.js.erb +2 -0
- data/app/views/activity_notification/notifications/default/open_all.js.erb +2 -0
- data/app/views/activity_notification/notifications/default/show.html.erb +2 -0
- data/config/locales/en.yml +8 -0
- data/lib/activity_notification.rb +52 -0
- data/lib/activity_notification/apis/notification_api.rb +147 -0
- data/lib/activity_notification/common.rb +86 -0
- data/lib/activity_notification/config.rb +23 -0
- data/lib/activity_notification/controllers/store_controller.rb +30 -0
- data/lib/activity_notification/helpers/polymorphic_helpers.rb +32 -0
- data/lib/activity_notification/helpers/view_helpers.rb +108 -0
- data/lib/activity_notification/mailers/helpers.rb +97 -0
- data/lib/activity_notification/models/notifiable.rb +136 -0
- data/lib/activity_notification/models/notification.rb +50 -0
- data/lib/activity_notification/models/notifier.rb +11 -0
- data/lib/activity_notification/models/target.rb +104 -0
- data/lib/activity_notification/rails.rb +6 -0
- data/lib/activity_notification/rails/routes.rb +105 -0
- data/lib/activity_notification/renderable.rb +142 -0
- data/lib/activity_notification/roles/acts_as_notifiable.rb +37 -0
- data/lib/activity_notification/roles/acts_as_target.rb +30 -0
- data/lib/activity_notification/version.rb +3 -0
- data/lib/generators/activity_notification/controllers_generator.rb +44 -0
- data/lib/generators/activity_notification/install_generator.rb +45 -0
- data/lib/generators/activity_notification/migration/migration_generator.rb +17 -0
- data/lib/generators/activity_notification/notification/notification_generator.rb +17 -0
- data/lib/generators/activity_notification/views_generator.rb +44 -0
- data/lib/generators/templates/README +53 -0
- data/lib/generators/templates/active_record/migration.rb +18 -0
- data/lib/generators/templates/activity_notification.rb +18 -0
- data/lib/generators/templates/controllers/README +13 -0
- data/lib/generators/templates/controllers/notifications_controller.rb +66 -0
- data/lib/generators/templates/controllers/notifications_with_devise_controller.rb +74 -0
- data/lib/generators/templates/notification/notification.rb +3 -0
- data/lib/tasks/activity_notification_tasks.rake +4 -0
- data/spec/concerns/notification_api_spec.rb +531 -0
- data/spec/factories/articles.rb +5 -0
- data/spec/factories/comments.rb +6 -0
- data/spec/factories/notifications.rb +7 -0
- data/spec/factories/users.rb +5 -0
- data/spec/models/notification_spec.rb +259 -0
- data/spec/rails_app/Rakefile +6 -0
- data/spec/rails_app/app/controllers/application_controller.rb +5 -0
- data/spec/rails_app/app/controllers/concerns/.keep +0 -0
- data/spec/rails_app/app/helpers/application_helper.rb +2 -0
- data/spec/rails_app/app/mailers/.keep +0 -0
- data/spec/rails_app/app/models/.keep +0 -0
- data/spec/rails_app/app/models/article.rb +12 -0
- data/spec/rails_app/app/models/comment.rb +18 -0
- data/spec/rails_app/app/models/concerns/.keep +0 -0
- data/spec/rails_app/app/models/user.rb +8 -0
- data/spec/rails_app/app/views/layouts/application.html.erb +14 -0
- data/spec/rails_app/bin/bundle +3 -0
- data/spec/rails_app/bin/rails +4 -0
- data/spec/rails_app/bin/rake +4 -0
- data/spec/rails_app/bin/setup +29 -0
- data/spec/rails_app/config.ru +4 -0
- data/spec/rails_app/config/application.rb +20 -0
- data/spec/rails_app/config/boot.rb +5 -0
- data/spec/rails_app/config/database.yml +25 -0
- data/spec/rails_app/config/environment.rb +12 -0
- data/spec/rails_app/config/environments/development.rb +44 -0
- data/spec/rails_app/config/environments/production.rb +79 -0
- data/spec/rails_app/config/environments/test.rb +45 -0
- data/spec/rails_app/config/initializers/activity_notification.rb +18 -0
- data/spec/rails_app/config/initializers/assets.rb +11 -0
- data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails_app/config/initializers/cookies_serializer.rb +3 -0
- data/spec/rails_app/config/initializers/devise.rb +274 -0
- data/spec/rails_app/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/rails_app/config/initializers/inflections.rb +16 -0
- data/spec/rails_app/config/initializers/mime_types.rb +4 -0
- data/spec/rails_app/config/initializers/session_store.rb +3 -0
- data/spec/rails_app/config/initializers/wrap_parameters.rb +14 -0
- data/spec/rails_app/config/routes.rb +5 -0
- data/spec/rails_app/config/secrets.yml +22 -0
- data/spec/rails_app/db/migrate/20160715050420_create_notifications.rb +18 -0
- data/spec/rails_app/db/migrate/20160715050433_create_test_tables.rb +36 -0
- data/spec/rails_app/db/schema.rb +73 -0
- data/spec/rails_app/public/404.html +67 -0
- data/spec/rails_app/public/422.html +67 -0
- data/spec/rails_app/public/500.html +66 -0
- data/spec/rails_app/public/favicon.ico +0 -0
- data/spec/spec_helper.rb +34 -0
- metadata +309 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
module ActivityNotification
|
|
2
|
+
|
|
3
|
+
# Used to transform value from metadata to data.
|
|
4
|
+
# Accepts Symbols, which it will send against context.
|
|
5
|
+
# Accepts Procs, which it will execute with controller and context.
|
|
6
|
+
# Both Symbols and Procs will be passed arguments of this method.
|
|
7
|
+
def self.resolve_value(context, thing, *args)
|
|
8
|
+
case thing
|
|
9
|
+
when Symbol
|
|
10
|
+
begin
|
|
11
|
+
context.__send__(thing, *args)
|
|
12
|
+
rescue ArgumentError => e
|
|
13
|
+
context.__send__(thing)
|
|
14
|
+
end
|
|
15
|
+
when Proc
|
|
16
|
+
begin
|
|
17
|
+
thing.call(ActivityNotification.get_controller, context, *args)
|
|
18
|
+
rescue ArgumentError => e
|
|
19
|
+
thing.call(ActivityNotification.get_controller, context)
|
|
20
|
+
end
|
|
21
|
+
when Hash
|
|
22
|
+
thing.dup.tap do |hash|
|
|
23
|
+
hash.each do |key, value|
|
|
24
|
+
hash[key] = ActivityNotification.resolve_value(context, value, *args)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
else
|
|
28
|
+
thing
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module Common
|
|
33
|
+
|
|
34
|
+
# Used to transform value from metadata to data which belongs model instance.
|
|
35
|
+
# Accepts Symbols, which it will send against this instance.
|
|
36
|
+
# Accepts Procs, which it will execute with this instance.
|
|
37
|
+
# Both Symbols and Procs will be passed arguments of this method.
|
|
38
|
+
def resolve_value(thing, *args)
|
|
39
|
+
case thing
|
|
40
|
+
when Symbol
|
|
41
|
+
begin
|
|
42
|
+
__send__(thing, *args)
|
|
43
|
+
rescue ArgumentError => e
|
|
44
|
+
__send__(thing)
|
|
45
|
+
end
|
|
46
|
+
when Proc
|
|
47
|
+
begin
|
|
48
|
+
thing.call(self, *args)
|
|
49
|
+
rescue ArgumentError => e
|
|
50
|
+
thing.call(self)
|
|
51
|
+
end
|
|
52
|
+
when Hash
|
|
53
|
+
thing.dup.tap do |hash|
|
|
54
|
+
hash.each do |key, value|
|
|
55
|
+
hash[key] = resolve_value(value, *args)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
else
|
|
59
|
+
thing
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def to_class_name
|
|
64
|
+
self.class.name
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def to_resource_name
|
|
68
|
+
self.class.name.demodulize.singularize.underscore
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def to_resources_name
|
|
72
|
+
self.class.name.demodulize.pluralize.underscore
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
#TODO Is it the best solution?
|
|
76
|
+
def printable_type
|
|
77
|
+
"#{self.class.name.demodulize.humanize}"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
#TODO Is it the best solution?
|
|
81
|
+
def printable_name
|
|
82
|
+
"#{self.printable_type} (#{id})"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module ActivityNotification
|
|
2
|
+
# Class used to initialize configuration object.
|
|
3
|
+
class Config
|
|
4
|
+
attr_accessor :enabled,
|
|
5
|
+
:table_name,
|
|
6
|
+
:mailer_sender,
|
|
7
|
+
:mailer,
|
|
8
|
+
:parent_mailer,
|
|
9
|
+
:parent_controller,
|
|
10
|
+
:opened_limit
|
|
11
|
+
|
|
12
|
+
def initialize
|
|
13
|
+
@enabled = true
|
|
14
|
+
@table_name = "notifications"
|
|
15
|
+
@mailer_sender = nil
|
|
16
|
+
@mailer = "ActivityNotification::Mailer"
|
|
17
|
+
@parent_mailer = 'ActionMailer::Base'
|
|
18
|
+
@parent_controller = 'ApplicationController'
|
|
19
|
+
@opened_limit = 10
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module ActivityNotification
|
|
2
|
+
class << self
|
|
3
|
+
# Setter for remembering controller instance
|
|
4
|
+
def set_controller(controller)
|
|
5
|
+
Thread.current[:activity_notification_controller] = controller
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# Getter for accessing the controller instance
|
|
9
|
+
def get_controller
|
|
10
|
+
Thread.current[:activity_notification_controller]
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Module included in controllers to allow p_a access to controller instance
|
|
15
|
+
module StoreController
|
|
16
|
+
extend ActiveSupport::Concern
|
|
17
|
+
|
|
18
|
+
included do
|
|
19
|
+
around_action :store_controller_for_activity_notification if respond_to?(:around_action)
|
|
20
|
+
around_filter :store_controller_for_activity_notification unless respond_to?(:around_action)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def store_controller_for_activity_notification
|
|
24
|
+
ActivityNotification.set_controller(self)
|
|
25
|
+
yield
|
|
26
|
+
ensure
|
|
27
|
+
ActivityNotification.set_controller(nil)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module ActivityNotification
|
|
2
|
+
module PolymorphicHelpers
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
class ::String
|
|
7
|
+
def to_model_name
|
|
8
|
+
singularize.camelize
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_model_class
|
|
12
|
+
to_model_name.classify.constantize
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_resource_name
|
|
16
|
+
singularize.underscore
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def to_resources_name
|
|
20
|
+
pluralize.underscore
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def to_boolean(default = nil)
|
|
24
|
+
return true if ['true', '1', 'yes', 'on', 't'].include? self
|
|
25
|
+
return false if ['false', '0', 'no', 'off', 'f'].include? self
|
|
26
|
+
return default
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Provides a shortcut from views to the rendering method.
|
|
2
|
+
module ActivityNotification
|
|
3
|
+
# Module extending ActionView::Base and adding `render_notification` helper.
|
|
4
|
+
module ViewHelpers
|
|
5
|
+
# View helper for rendering an notification, calls {ActivityNotification::Notification#render} internally.
|
|
6
|
+
def render_notification notifications, options = {}
|
|
7
|
+
if notifications.is_a? ActivityNotification::Notification
|
|
8
|
+
notifications.render self, options
|
|
9
|
+
elsif notifications.respond_to?(:map)
|
|
10
|
+
return nil if notifications.empty?
|
|
11
|
+
notifications.map {|notification| notification.render self, options.dup }.join.html_safe
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
alias_method :render_notifications, :render_notification
|
|
15
|
+
|
|
16
|
+
# View helper for rendering embedded partial template of target's notifications
|
|
17
|
+
def render_notification_of target, options = {}
|
|
18
|
+
return unless target.is_a? ActivityNotification::Target
|
|
19
|
+
|
|
20
|
+
partial_path = options.delete(:partial) || "index"
|
|
21
|
+
partial_root = options[:partial_root] ||
|
|
22
|
+
"activity_notification/notifications/#{target.to_resources_name}"
|
|
23
|
+
partial = select_path(partial_path, partial_root)
|
|
24
|
+
layout = options[:layout].present? ?
|
|
25
|
+
select_path(options.delete(:layout), (options[:layout_root] || "layouts")) :
|
|
26
|
+
nil
|
|
27
|
+
locals = (options[:locals] || {}).merge(target: target)
|
|
28
|
+
|
|
29
|
+
# Prepare content for notifications index
|
|
30
|
+
notification_options = options.merge\
|
|
31
|
+
target: target.to_resources_name,
|
|
32
|
+
partial: options[:notification_partial],
|
|
33
|
+
layout: options[:notification_layout]
|
|
34
|
+
case options[:index_content]
|
|
35
|
+
when :simple
|
|
36
|
+
notification_index = target.notification_index
|
|
37
|
+
when :none
|
|
38
|
+
else
|
|
39
|
+
notification_index = target.notification_index_with_attributes
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
if notification_index.present?
|
|
43
|
+
content_for :notification_index do
|
|
44
|
+
begin
|
|
45
|
+
render_notifications notification_index, notification_options
|
|
46
|
+
rescue ActionView::MissingTemplate => e
|
|
47
|
+
notification_options.delete(:target)
|
|
48
|
+
render_notifications notification_index, notification_options
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Render partial index
|
|
54
|
+
begin
|
|
55
|
+
render options.merge(partial: partial, layout: layout, locals: locals)
|
|
56
|
+
rescue ActionView::MissingTemplate => e
|
|
57
|
+
partial_root = "activity_notification/notifications/default"
|
|
58
|
+
partial = select_path(partial_path, partial_root)
|
|
59
|
+
render options.merge(partial: partial, layout: layout, locals: locals)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
alias_method :render_notifications_of, :render_notification_of
|
|
63
|
+
|
|
64
|
+
# Url helper methods
|
|
65
|
+
#TODO Is there any other better solution?
|
|
66
|
+
#TODO Must handle devise namespace
|
|
67
|
+
def notification_path_for(notification, params = {})
|
|
68
|
+
send("#{notification.target.to_resource_name}_notification_path", notification.target, notification, params)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def move_notification_path_for(notification, params = {})
|
|
72
|
+
send("move_#{notification.target.to_resource_name}_notification_path", notification.target, notification, params)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def open_notification_path_for(notification, params = {})
|
|
76
|
+
send("open_#{notification.target.to_resource_name}_notification_path", notification.target, notification, params)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def open_all_notifications_path_for(target, params = {})
|
|
80
|
+
send("open_all_#{target.to_resource_name}_notifications_path", target, params)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def notification_url_for(notification, params = {})
|
|
84
|
+
send("#{notification.target.to_resource_name}_notification_url", notification.target, notification, params)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def move_notification_url_for(notification, params = {})
|
|
88
|
+
send("move_#{notification.target.to_resource_name}_notification_url", notification.target, notification, params)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def open_notification_url_for(notification, params = {})
|
|
92
|
+
send("open_#{notification.target.to_resource_name}_notification_url", notification.target, notification, params)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def open_all_notifications_url_for(target, params = {})
|
|
96
|
+
send("open_all_#{target.to_resource_name}_notifications_url", target, params)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
private
|
|
100
|
+
|
|
101
|
+
def select_path(path, root)
|
|
102
|
+
[root, path].map(&:to_s).join('/')
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
ActionView::Base.class_eval { include ViewHelpers }
|
|
108
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
module ActivityNotification
|
|
2
|
+
module Mailers
|
|
3
|
+
module Helpers
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
protected
|
|
7
|
+
|
|
8
|
+
# Configure default email options
|
|
9
|
+
def notification_mail(notification, options = {})
|
|
10
|
+
initialize_from_notification(notification)
|
|
11
|
+
headers = headers_for(notification.key, options)
|
|
12
|
+
begin
|
|
13
|
+
mail headers
|
|
14
|
+
rescue ActionView::MissingTemplate => e
|
|
15
|
+
mail headers.merge(template_name: 'default')
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def initialize_from_notification(notification)
|
|
20
|
+
@notification, @target, @notifiable = notification, notification.target, notification.notifiable
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def headers_for(key, options)
|
|
24
|
+
if @notifiable.respond_to?(:overriding_notification_email_key) and
|
|
25
|
+
@notifiable.overriding_notification_email_key(@target, key).present?
|
|
26
|
+
key = @notifiable.overriding_notification_email_key(@target, key)
|
|
27
|
+
end
|
|
28
|
+
headers = {
|
|
29
|
+
subject: subject_for(key),
|
|
30
|
+
to: mailer_to(@target),
|
|
31
|
+
from: mailer_sender(@target.to_resource_name),
|
|
32
|
+
reply_to: mailer_reply_to(@target.to_resource_name),
|
|
33
|
+
template_path: template_paths,
|
|
34
|
+
template_name: template_name(key)
|
|
35
|
+
}.merge(options)
|
|
36
|
+
|
|
37
|
+
@email = headers[:to]
|
|
38
|
+
headers
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def mailer_to(target)
|
|
42
|
+
target.mailer_to
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def mailer_reply_to(target_type)
|
|
46
|
+
mailer_sender(target_type, :reply_to)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def mailer_from(target_type)
|
|
50
|
+
mailer_sender(target_type, :from)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def mailer_sender(target_type, sender = :from)
|
|
54
|
+
default_sender = default_params[sender]
|
|
55
|
+
if default_sender.present?
|
|
56
|
+
default_sender.respond_to?(:to_proc) ? instance_eval(&default_sender) : default_sender
|
|
57
|
+
elsif ActivityNotification.config.mailer_sender.is_a?(Proc)
|
|
58
|
+
ActivityNotification.config.mailer_sender.call(target_type)
|
|
59
|
+
else
|
|
60
|
+
ActivityNotification.config.mailer_sender
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def template_paths
|
|
65
|
+
paths = ['activity_notification/mailer/default']
|
|
66
|
+
paths.unshift("activity_notification/mailer/#{@target.to_resources_name}") if @target.present?
|
|
67
|
+
paths
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def template_name(key)
|
|
71
|
+
key.gsub('.', '/')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# Set up a subject doing an I18n lookup.
|
|
76
|
+
# At first, it attempts to set a subject based on the current mapping:
|
|
77
|
+
# en:
|
|
78
|
+
# notification:
|
|
79
|
+
# {target}:
|
|
80
|
+
# {key}:
|
|
81
|
+
# mail_subject: '...'
|
|
82
|
+
#
|
|
83
|
+
# If one does not exist, it fallbacks to default:
|
|
84
|
+
# Notification for #{notification.printable_type}
|
|
85
|
+
#
|
|
86
|
+
def subject_for(key)
|
|
87
|
+
k = key.split('.')
|
|
88
|
+
k.unshift('notification') if k.first != 'notification'
|
|
89
|
+
k.insert(1, @target.to_resource_name)
|
|
90
|
+
k = k.join('.')
|
|
91
|
+
I18n.t(:mail_subject, scope: k,
|
|
92
|
+
default: ["Notification of #{@notifiable.printable_type}"])
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
module ActivityNotification
|
|
2
|
+
module Notifiable
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
include Common
|
|
7
|
+
include ActsAsNotifiable
|
|
8
|
+
include ActionDispatch::Routing::PolymorphicRoutes
|
|
9
|
+
include Rails.application.routes.url_helpers
|
|
10
|
+
class_attribute :_notification_targets,
|
|
11
|
+
:_notification_group,
|
|
12
|
+
:_notifier,
|
|
13
|
+
:_notification_parameters,
|
|
14
|
+
:_notification_email_allowed,
|
|
15
|
+
:_notifiable_path
|
|
16
|
+
set_notifiable_class_defaults
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def default_url_options
|
|
20
|
+
Rails.application.routes.default_url_options
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class_methods do
|
|
24
|
+
def set_notifiable_class_defaults
|
|
25
|
+
self._notification_targets = {}
|
|
26
|
+
self._notification_group = {}
|
|
27
|
+
self._notifier = {}
|
|
28
|
+
self._notification_parameters = {}
|
|
29
|
+
self._notification_email_allowed = {}
|
|
30
|
+
self._notifiable_path = {}
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Methods to be overriden
|
|
35
|
+
|
|
36
|
+
def notification_targets(target_type, key)
|
|
37
|
+
plural_target_type = target_type.to_s.underscore.pluralize
|
|
38
|
+
plural_target_type_sym = plural_target_type.to_sym
|
|
39
|
+
target_typed_method_name = "notification_#{plural_target_type}"
|
|
40
|
+
if respond_to?(target_typed_method_name)
|
|
41
|
+
send(target_typed_method_name, key)
|
|
42
|
+
else
|
|
43
|
+
if _notification_targets[plural_target_type_sym]
|
|
44
|
+
resolve_value(_notification_targets[plural_target_type_sym], key)
|
|
45
|
+
else
|
|
46
|
+
raise NotImplementedError, "You have to implement #{self.class}##{target_typed_method_name} or set :targets in acts_as_notifiable"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def notification_group(target_type, key)
|
|
52
|
+
plural_target_type = target_type.to_s.underscore.pluralize
|
|
53
|
+
plural_target_type_sym = plural_target_type.to_sym
|
|
54
|
+
target_typed_method_name = "notification_group_for_#{plural_target_type}"
|
|
55
|
+
if respond_to?(target_typed_method_name)
|
|
56
|
+
send(target_typed_method_name, key)
|
|
57
|
+
else
|
|
58
|
+
resolve_value(_notification_group[plural_target_type_sym])
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def notification_parameters(target_type, key)
|
|
63
|
+
plural_target_type = target_type.to_s.underscore.pluralize
|
|
64
|
+
plural_target_type_sym = plural_target_type.to_sym
|
|
65
|
+
target_typed_method_name = "notification_parameters_for_#{plural_target_type}"
|
|
66
|
+
if respond_to?(target_typed_method_name)
|
|
67
|
+
send(target_typed_method_name, key)
|
|
68
|
+
else
|
|
69
|
+
resolve_value(_notification_parameters[plural_target_type_sym], key) || {}
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def notifier(target_type, key)
|
|
74
|
+
plural_target_type = target_type.to_s.underscore.pluralize
|
|
75
|
+
plural_target_type_sym = plural_target_type.to_sym
|
|
76
|
+
target_typed_method_name = "notifier_for_#{plural_target_type}"
|
|
77
|
+
if respond_to?(target_typed_method_name)
|
|
78
|
+
send(target_typed_method_name, key)
|
|
79
|
+
else
|
|
80
|
+
resolve_value(_notifier[plural_target_type_sym])
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def notification_email_allowed?(target, key)
|
|
85
|
+
plural_target_type_sym = target.to_resources_name.to_sym
|
|
86
|
+
if _notification_email_allowed[plural_target_type_sym]
|
|
87
|
+
resolve_value(_notification_email_allowed[plural_target_type_sym], target, key)
|
|
88
|
+
else
|
|
89
|
+
true
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def notifiable_path(target_type, key = nil)
|
|
94
|
+
plural_target_type = target_type.to_s.underscore.pluralize
|
|
95
|
+
plural_target_type_sym = plural_target_type.to_sym
|
|
96
|
+
target_typed_method_name = "notifiable_path_for_#{plural_target_type}"
|
|
97
|
+
if respond_to?(target_typed_method_name)
|
|
98
|
+
send(target_typed_method_name, key)
|
|
99
|
+
elsif _notifiable_path[plural_target_type_sym]
|
|
100
|
+
resolve_value(_notifiable_path[plural_target_type_sym])
|
|
101
|
+
else
|
|
102
|
+
begin
|
|
103
|
+
polymorphic_path(self)
|
|
104
|
+
rescue NoMethodError => e
|
|
105
|
+
raise NotImplementedError, "You have to implement #{self.class}##{__method__}, set :notifiable_path in acts_as_notifiable or set polymorphic_path routing for #{self.class}"
|
|
106
|
+
rescue ActionController::UrlGenerationError => e
|
|
107
|
+
raise NotImplementedError, "You have to implement #{self.class}##{__method__}, set :notifiable_path in acts_as_notifiable or set polymorphic_path routing for #{self.class}"
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# TODO docs
|
|
113
|
+
# overriding_notification_render_key(target, key)
|
|
114
|
+
|
|
115
|
+
# TODO docs
|
|
116
|
+
# overriding_notification_email_key(target, key)
|
|
117
|
+
|
|
118
|
+
# Wrapper methods of SimpleNotify class methods
|
|
119
|
+
|
|
120
|
+
def notify(target_type, options = {})
|
|
121
|
+
Notification.notify(target_type, self, options)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def notify_to(target, options = {})
|
|
125
|
+
Notification.notify_to(target, self, options)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def notify_all(targets, options = {})
|
|
129
|
+
Notification.notify_all(targets, self, options)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def default_notification_key
|
|
133
|
+
"#{to_resource_name}.default"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|