commontator 0.1.46
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.
- data/MIT-LICENSE +20 -0
- data/README.md +35 -0
- data/Rakefile +40 -0
- data/app/assets/images/commontator/downvote.png +0 -0
- data/app/assets/images/commontator/downvote_hover.png +0 -0
- data/app/assets/images/commontator/upvote.png +0 -0
- data/app/assets/images/commontator/upvote_hover.png +0 -0
- data/app/assets/stylesheets/commontator/application.css +13 -0
- data/app/assets/stylesheets/commontator/application.css~ +88 -0
- data/app/assets/stylesheets/commontator/comments.css +86 -0
- data/app/assets/stylesheets/commontator/comments.css~ +90 -0
- data/app/assets/stylesheets/commontator/threads.css +13 -0
- data/app/assets/stylesheets/commontator/threads.css~ +13 -0
- data/app/controllers/commontator/application_controller.rb +18 -0
- data/app/controllers/commontator/application_controller.rb~ +16 -0
- data/app/controllers/commontator/comments_controller.rb +143 -0
- data/app/controllers/commontator/comments_controller.rb~ +143 -0
- data/app/controllers/commontator/subscriptions_controller.rb +42 -0
- data/app/controllers/commontator/subscriptions_controller.rb~ +40 -0
- data/app/controllers/commontator/threads_controller.rb +42 -0
- data/app/controllers/commontator/threads_controller.rb~ +43 -0
- data/app/helpers/commontator/application_helper.rb +11 -0
- data/app/helpers/commontator/application_helper.rb~ +11 -0
- data/app/helpers/commontator/comments_helper.rb +47 -0
- data/app/helpers/commontator/comments_helper.rb~ +58 -0
- data/app/helpers/commontator/commontable_helper.rb~ +9 -0
- data/app/helpers/commontator/commontator_helper.rb +8 -0
- data/app/helpers/commontator/commontator_helper.rb~ +8 -0
- data/app/helpers/commontator/subscriptions_helper.rb +8 -0
- data/app/helpers/commontator/subscriptions_helper.rb~ +8 -0
- data/app/helpers/commontator/threads_helper.rb +21 -0
- data/app/helpers/commontator/threads_helper.rb~ +32 -0
- data/app/mailers/commontator/subscription_mailer.rb~ +38 -0
- data/app/mailers/commontator/subscriptions_mailer.rb +51 -0
- data/app/mailers/commontator/subscriptions_mailer.rb~ +51 -0
- data/app/models/commontator/comment.rb +84 -0
- data/app/models/commontator/comment.rb~ +84 -0
- data/app/models/commontator/subscription.rb +21 -0
- data/app/models/commontator/subscription.rb~ +21 -0
- data/app/models/commontator/thread.rb +138 -0
- data/app/models/commontator/thread.rb~ +141 -0
- data/app/views/commontator/comments/_actions.html.erb +32 -0
- data/app/views/commontator/comments/_actions.html.erb~ +33 -0
- data/app/views/commontator/comments/_body.html.erb +7 -0
- data/app/views/commontator/comments/_body.html.erb~ +8 -0
- data/app/views/commontator/comments/_form.html.erb +20 -0
- data/app/views/commontator/comments/_form.html.erb~ +21 -0
- data/app/views/commontator/comments/_show.html.erb +41 -0
- data/app/views/commontator/comments/_show.html.erb~ +45 -0
- data/app/views/commontator/comments/_votes.html.erb +60 -0
- data/app/views/commontator/comments/_votes.html.erb~ +62 -0
- data/app/views/commontator/comments/create.js.erb +15 -0
- data/app/views/commontator/comments/create.js.erb~ +15 -0
- data/app/views/commontator/comments/delete.js.erb +15 -0
- data/app/views/commontator/comments/delete.js.erb~ +15 -0
- data/app/views/commontator/comments/destroy.js.erb~ +1 -0
- data/app/views/commontator/comments/edit.html.erb +6 -0
- data/app/views/commontator/comments/edit.html.erb~ +6 -0
- data/app/views/commontator/comments/edit.js.erb +5 -0
- data/app/views/commontator/comments/edit.js.erb~ +5 -0
- data/app/views/commontator/comments/new.html.erb +8 -0
- data/app/views/commontator/comments/new.html.erb~ +8 -0
- data/app/views/commontator/comments/new.js.erb +12 -0
- data/app/views/commontator/comments/new.js.erb~ +12 -0
- data/app/views/commontator/comments/update.js.erb +7 -0
- data/app/views/commontator/comments/update.js.erb~ +7 -0
- data/app/views/commontator/comments/vote.js.erb +5 -0
- data/app/views/commontator/comments/vote.js.erb~ +5 -0
- data/app/views/commontator/commontator/_thread.html.erb +14 -0
- data/app/views/commontator/commontator/_thread.html.erb~ +15 -0
- data/app/views/commontator/subscriptions/_subscription_link.html.erb +12 -0
- data/app/views/commontator/subscriptions/_subscription_link.html.erb~ +12 -0
- data/app/views/commontator/subscriptions/create.js.erb +5 -0
- data/app/views/commontator/subscriptions/create.js.erb~ +3 -0
- data/app/views/commontator/subscriptions/destroy.js.erb +5 -0
- data/app/views/commontator/subscriptions/destroy.js.erb~ +3 -0
- data/app/views/commontator/subscriptions/index.html.erb +16 -0
- data/app/views/commontator/subscriptions/index.html.erb~ +16 -0
- data/app/views/commontator/subscriptions_mailer/comment_created_email.html.erb +14 -0
- data/app/views/commontator/subscriptions_mailer/comment_created_email.html.erb~ +14 -0
- data/app/views/commontator/threads/_show.html.erb +26 -0
- data/app/views/commontator/threads/_show.html.erb~ +26 -0
- data/app/views/commontator/threads/show.html.erb +3 -0
- data/app/views/commontator/threads/show.js.erb +6 -0
- data/app/views/layouts/commontator/application.html.erb +14 -0
- data/config/initializers/commontator.rb +7 -0
- data/config/routes.rb +24 -0
- data/config/routes.rb~ +22 -0
- data/db/migrate/0_install_commontator.rb +40 -0
- data/db/migrate/0_install_commontator.rb~ +40 -0
- data/lib/commontator.rb +66 -0
- data/lib/commontator.rb~ +66 -0
- data/lib/commontator/acts_as_commontable.rb +39 -0
- data/lib/commontator/acts_as_commontable.rb~ +42 -0
- data/lib/commontator/acts_as_commontator.rb +28 -0
- data/lib/commontator/acts_as_commontator.rb~ +37 -0
- data/lib/commontator/commontable_config.rb +13 -0
- data/lib/commontator/commontator_config.rb +13 -0
- data/lib/commontator/engine.rb +5 -0
- data/lib/commontator/routes.rb~ +37 -0
- data/lib/commontator/version.rb +3 -0
- data/lib/commontator/version.rb~ +3 -0
- data/test/commontator_test.rb +7 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +16 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +204 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/functional/comment_thread_subscriptions_controller_test.rb~ +125 -0
- data/test/functional/comments_controller_test.rb +181 -0
- data/test/functional/comments_controller_test.rb~ +184 -0
- data/test/functional/subscriptions_controller_test.rb +122 -0
- data/test/functional/subscriptions_controller_test.rb~ +122 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +15 -0
- data/test/unit/comment_test.rb +35 -0
- data/test/unit/comment_test.rb~ +38 -0
- data/test/unit/comment_thread_subscription_test.rb~ +18 -0
- data/test/unit/comment_thread_test.rb~ +60 -0
- data/test/unit/helpers/comment_thread_subscriptions_helper_test.rb~ +7 -0
- data/test/unit/helpers/comments_helper_test.rb +4 -0
- data/test/unit/helpers/comments_helper_test.rb~ +7 -0
- data/test/unit/helpers/subscriptions_helper_test.rb +4 -0
- data/test/unit/helpers/subscriptions_helper_test.rb~ +4 -0
- data/test/unit/subscription_test.rb +15 -0
- data/test/unit/subscription_test.rb~ +15 -0
- data/test/unit/thread_test.rb +57 -0
- data/test/unit/thread_test.rb~ +57 -0
- metadata +301 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
module Commontator
|
|
2
|
+
class Comment < ActiveRecord::Base
|
|
3
|
+
|
|
4
|
+
belongs_to :commontator, :polymorphic => true
|
|
5
|
+
belongs_to :deleter, :polymorphic => true
|
|
6
|
+
belongs_to :thread
|
|
7
|
+
|
|
8
|
+
has_one :commontable, :through => :thread
|
|
9
|
+
#has_one :subthread, :class_name => "Commontator::Thread",
|
|
10
|
+
# :as => :commontable,
|
|
11
|
+
# :dependent => :destroy
|
|
12
|
+
|
|
13
|
+
#before_validation :build_subthread, :on => :create
|
|
14
|
+
validates_presence_of :commontator, :thread#, :subthread
|
|
15
|
+
#validates_uniqueness_of :subthread
|
|
16
|
+
|
|
17
|
+
attr_accessible :body
|
|
18
|
+
|
|
19
|
+
cattr_accessor :is_votable
|
|
20
|
+
if respond_to?(:acts_as_votable)
|
|
21
|
+
acts_as_votable if respond_to?(:acts_as_votable)
|
|
22
|
+
self.is_votable = true
|
|
23
|
+
else
|
|
24
|
+
self.is_votable = false
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def is_modified?
|
|
28
|
+
updated_at != created_at
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def is_deleted?
|
|
32
|
+
!deleted_at.blank?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def delete(user = nil)
|
|
36
|
+
self.deleted_at = Time.now
|
|
37
|
+
self.deleter = user
|
|
38
|
+
self.save!
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def undelete
|
|
42
|
+
self.deleted_at = nil
|
|
43
|
+
self.save!
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
##########################
|
|
47
|
+
# Access control methods #
|
|
48
|
+
##########################
|
|
49
|
+
|
|
50
|
+
def can_be_read_by?(user)
|
|
51
|
+
(thread.can_be_read_by?(user) && (!is_deleted? ||\
|
|
52
|
+
thread.config.deleted_comments_are_visible)) ||\
|
|
53
|
+
thread.can_be_edited_by?(user)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def can_be_created_by?(user)
|
|
57
|
+
!thread.is_closed? && thread.can_be_read_by?(user) && user == commontator
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def can_be_edited_by?(user)
|
|
61
|
+
!thread.is_closed? && !is_deleted? &&\
|
|
62
|
+
((user == commontator && thread.config.can_edit_own_comments) ||\
|
|
63
|
+
(thread.can_be_edited_by?(user) && thread.config.admin_can_edit_comments)) &&\
|
|
64
|
+
(thread.comments.last == self || thread.config.can_edit_old_comments)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def can_be_deleted_by?(user)
|
|
68
|
+
!thread.is_closed? && !is_deleted? &&\
|
|
69
|
+
((user == commontator && thread.config.can_delete_own_comments) &&\
|
|
70
|
+
(thread.comments.last == self || thread.config.can_delete_old_comments)) ||\
|
|
71
|
+
thread.can_be_edited_by?(user)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def can_be_voted_on?
|
|
75
|
+
is_votable && !is_deleted? && thread.config.comments_can_be_voted_on
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def can_be_voted_on_by?(user)
|
|
79
|
+
can_be_voted_on? && !thread.is_closed? &&\
|
|
80
|
+
thread.can_be_read_by?(user) && user != commontator
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Commontator
|
|
2
|
+
class Subscription < ActiveRecord::Base
|
|
3
|
+
|
|
4
|
+
belongs_to :subscriber, :polymorphic => true
|
|
5
|
+
belongs_to :thread
|
|
6
|
+
|
|
7
|
+
validates_presence_of :subscriber, :thread
|
|
8
|
+
validates_uniqueness_of :thread_id, :scope => [:subscriber_id, :subscriber_type]
|
|
9
|
+
|
|
10
|
+
attr_accessible :subscriber, :thread
|
|
11
|
+
|
|
12
|
+
def mark_as_read
|
|
13
|
+
self.update_attribute(:is_unread, false)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def mark_as_unread
|
|
17
|
+
self.update_attribute(:is_unread, true)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Commontator
|
|
2
|
+
class Subscription < ActiveRecord::Base
|
|
3
|
+
|
|
4
|
+
belongs_to :subscriber, :polymorphic => true
|
|
5
|
+
belongs_to :thread
|
|
6
|
+
|
|
7
|
+
attr_accessible :subscriber, :thread
|
|
8
|
+
|
|
9
|
+
validates_presence_of :subscriber, :thread
|
|
10
|
+
validates_uniqueness_of :thread_id, :scope => [:subscriber_id, :subscriber_type]
|
|
11
|
+
|
|
12
|
+
def mark_as_read
|
|
13
|
+
self.update_attribute(:is_unread, false)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def mark_as_unread
|
|
17
|
+
self.update_attribute(:is_unread, true)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
module Commontator
|
|
2
|
+
class Thread < ActiveRecord::Base
|
|
3
|
+
|
|
4
|
+
belongs_to :closer, :polymorphic => true
|
|
5
|
+
belongs_to :commontable, :polymorphic => true
|
|
6
|
+
|
|
7
|
+
has_many :comments, :dependent => :destroy
|
|
8
|
+
has_many :subscriptions, :dependent => :destroy
|
|
9
|
+
|
|
10
|
+
validates_presence_of :commontable, :allow_nil => true
|
|
11
|
+
|
|
12
|
+
attr_accessible :is_closed
|
|
13
|
+
|
|
14
|
+
def subscribers
|
|
15
|
+
subscriptions.collect{|s| s.subscriber}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def subscription_for(user)
|
|
19
|
+
Subscription.find_by_thread_id_and_subscriber_id_and_subscriber_type(self.id, user.id, user.class.name)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def is_closed?
|
|
23
|
+
!closed_at.blank?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def config
|
|
27
|
+
commontable.commontable_config
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def is_subscribed?(user)
|
|
31
|
+
!subscription_for(subscriber).blank?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def subscribe(subscriber)
|
|
35
|
+
return false if is_subscribed?(user)
|
|
36
|
+
subscription = Subscription.create(
|
|
37
|
+
:subscriber => subscriber, :thread => self)
|
|
38
|
+
subscribe_callback(subscriber)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def unsubscribe(subscriber)
|
|
42
|
+
subscription = subscription_for(subscriber)
|
|
43
|
+
return false if subscription.blank?
|
|
44
|
+
subscription.destroy
|
|
45
|
+
unsubscribe_callback(subscriber)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def mark_as_read_for(subscriber)
|
|
49
|
+
return if !subscription_for(subscriber)
|
|
50
|
+
subscription_for(subscriber).mark_as_read
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def mark_as_unread_except_for(subscriber)
|
|
54
|
+
Subscription.transaction do
|
|
55
|
+
subscriptions.each{|s| s.mark_as_unread unless s.subscriber == subscriber}
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def close(user = nil)
|
|
60
|
+
self.closed_at = Time.now
|
|
61
|
+
self.closer = user
|
|
62
|
+
self.save!
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def reopen
|
|
66
|
+
self.closed_at = nil
|
|
67
|
+
self.save!
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Creates a new empty thread and assigns it to the commontable
|
|
71
|
+
# The old thread is kept in the database for archival purposes
|
|
72
|
+
def clear(user = nil)
|
|
73
|
+
new_thread = Thread.new
|
|
74
|
+
new_thread.commontable = commontable
|
|
75
|
+
self.with_lock do
|
|
76
|
+
new_thread.save!
|
|
77
|
+
commontable.thread = new_thread
|
|
78
|
+
commontable.save!
|
|
79
|
+
subscriptions.each do |s|
|
|
80
|
+
s.thread = new_thread
|
|
81
|
+
s.save!
|
|
82
|
+
s.mark_as_read
|
|
83
|
+
end
|
|
84
|
+
self.commontable = nil
|
|
85
|
+
self.close(user)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
####################
|
|
90
|
+
# Callback methods #
|
|
91
|
+
####################
|
|
92
|
+
|
|
93
|
+
def comment_created_callback(user, comment)
|
|
94
|
+
commontable.send(config.comment_created_callback, user, comment) unless config.comment_created_callback.blank?
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def comment_edited_callback(user, comment)
|
|
98
|
+
commontable.send(config.comment_edited_callback, user, comment) unless config.comment_edited_callback.blank?
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def comment_deleted_callback(user, comment)
|
|
102
|
+
commontable.send(config.comment_deleted_callback, user, comment) unless config.comment_deleted_callback.blank?
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def thread_closed_callback(user)
|
|
106
|
+
commontable.send(config.thread_closed_callback, user) unless config.thread_closed_callback.blank?
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def subscribe_callback(user)
|
|
110
|
+
commontable.send(config.subscribe_callback, user) unless config.subscribe_callback.blank?
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def unsubscribe_callback(user)
|
|
114
|
+
commontable.send(config.unsubscribe_callback, user) unless config.unsubscribe_callback.blank?
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
##########################
|
|
118
|
+
# Access control methods #
|
|
119
|
+
##########################
|
|
120
|
+
|
|
121
|
+
def can_be_read_by?(user) # Reader and poster capabilities
|
|
122
|
+
((!is_closed? || config.closed_threads_are_readable) &&\
|
|
123
|
+
config.can_read_thread_method.blank? ? true : commontable.send(config.can_read_thread_method, user)) ||\
|
|
124
|
+
can_be_edited_by?(user)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def can_be_edited_by?(user) # Thread admin capabilities
|
|
128
|
+
config.can_edit_thread_method.blank? ?
|
|
129
|
+
(user.commontator_config.is_admin_method.blank? ? false : user.send(user.commontator_config.is_admin_method)) :
|
|
130
|
+
commontable.send(config.can_edit_thread_method, user)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def can_subscribe?(user)
|
|
134
|
+
config.can_subscribe_to_thread && can_be_read_by?(user)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
end
|
|
138
|
+
end
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
module Commontator
|
|
2
|
+
class Thread < ActiveRecord::Base
|
|
3
|
+
|
|
4
|
+
belongs_to :closer, :polymorphic => true
|
|
5
|
+
belongs_to :commontable, :polymorphic => true
|
|
6
|
+
|
|
7
|
+
has_many :comments, :dependent => :destroy
|
|
8
|
+
has_many :subscriptions, :dependent => :destroy
|
|
9
|
+
|
|
10
|
+
validates_presence_of :commontable, :allow_nil => true
|
|
11
|
+
|
|
12
|
+
attr_accessible :is_closed
|
|
13
|
+
|
|
14
|
+
def subscribers
|
|
15
|
+
subscriptions.collect{|s| s.subscriber}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def subscription_for(user)
|
|
19
|
+
Subscription.find_by_thread_id_and_subscriber_id_and_subscriber_type(self.id, user.id, user.class.name)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def is_closed?
|
|
23
|
+
!closed_at.blank?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def config
|
|
27
|
+
commontable.commontable_config
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def is_subscribed?(user)
|
|
31
|
+
!subscription_for(subscriber).blank?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def subscribe(subscriber)
|
|
35
|
+
return false if is_subscribed?(user)
|
|
36
|
+
subscription = Subscription.create(
|
|
37
|
+
:subscriber => subscriber, :thread => self)
|
|
38
|
+
subscribe_callback(subscriber)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def unsubscribe(subscriber)
|
|
42
|
+
subscription = subscription_for(subscriber)
|
|
43
|
+
return false if subscription.blank?
|
|
44
|
+
subscription.destroy
|
|
45
|
+
unsubscribe_callback(subscriber)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def mark_as_read_for(subscriber)
|
|
49
|
+
return if !subscription_for(subscriber)
|
|
50
|
+
subscription_for(subscriber).mark_as_read
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def mark_as_unread_except_for(subscriber)
|
|
54
|
+
Subscription.transaction do
|
|
55
|
+
subscriptions.each{|s| s.mark_as_unread unless s.subscriber == subscriber}
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def close(user = nil)
|
|
60
|
+
self.closed_at = Time.now
|
|
61
|
+
self.closer = user
|
|
62
|
+
self.save!
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def reopen
|
|
66
|
+
self.closed_at = nil
|
|
67
|
+
self.save!
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Creates a new empty thread and assigns it to the commontable
|
|
71
|
+
# The old thread is kept in the database for archival purposes
|
|
72
|
+
def clear(user = nil)
|
|
73
|
+
new_thread = Thread.new
|
|
74
|
+
new_thread.commontable = commontable
|
|
75
|
+
self.with_lock do
|
|
76
|
+
new_thread.save!
|
|
77
|
+
commontable.thread = new_thread
|
|
78
|
+
commontable.save!
|
|
79
|
+
subscriptions.each do |s|
|
|
80
|
+
s.thread = new_thread
|
|
81
|
+
s.save!
|
|
82
|
+
s.mark_as_read
|
|
83
|
+
end
|
|
84
|
+
self.commontable = nil
|
|
85
|
+
self.close(user)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
####################
|
|
90
|
+
# Callback methods #
|
|
91
|
+
####################
|
|
92
|
+
|
|
93
|
+
def comment_created_callback(user, comment)
|
|
94
|
+
self.subscribe(user) if config.auto_subscribe_on_comment
|
|
95
|
+
self.mark_as_unread_except_for(user)
|
|
96
|
+
SubscriptionMailer.comment_created_email(comment)
|
|
97
|
+
commontable.send(config.comment_created_callback, user, comment) unless config.comment_created_callback.blank?
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def comment_edited_callback(user, comment)
|
|
101
|
+
commontable.send(config.comment_edited_callback, user, comment) unless config.comment_edited_callback.blank?
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def comment_deleted_callback(user, comment)
|
|
105
|
+
commontable.send(config.comment_deleted_callback, user, comment) unless config.comment_deleted_callback.blank?
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def thread_closed_callback(user)
|
|
109
|
+
commontable.send(config.thread_closed_callback, user) unless config.thread_closed_callback.blank?
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def subscribe_callback(user)
|
|
113
|
+
commontable.send(config.subscribe_callback, user) unless config.subscribe_callback.blank?
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def unsubscribe_callback(user)
|
|
117
|
+
commontable.send(config.unsubscribe_callback, user) unless config.unsubscribe_callback.blank?
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
##########################
|
|
121
|
+
# Access control methods #
|
|
122
|
+
##########################
|
|
123
|
+
|
|
124
|
+
def can_be_read_by?(user) # Reader and poster capabilities
|
|
125
|
+
((!is_closed? || config.closed_threads_are_readable) &&\
|
|
126
|
+
config.can_read_thread_method.blank? ? true : commontable.send(config.can_read_thread_method, user)) ||\
|
|
127
|
+
can_be_edited_by?(user)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def can_be_edited_by?(user) # Thread admin capabilities
|
|
131
|
+
config.can_edit_thread_method.blank? ?
|
|
132
|
+
(user.commontator_config.is_admin_method.blank? ? false : user.send(user.commontator_config.is_admin_method)) :
|
|
133
|
+
commontable.send(config.can_edit_thread_method, user)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def can_subscribe?(user)
|
|
137
|
+
config.can_subscribe_to_thread && can_be_read_by?(user)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
end
|
|
141
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<% # Clients of this partial must supply the following variables:
|
|
2
|
+
# comment
|
|
3
|
+
%>
|
|
4
|
+
|
|
5
|
+
<% can_edit = comment.can_be_edited_by?(@commontator)
|
|
6
|
+
can_delete = comment.can_be_deleted_by?(@commontator) %>
|
|
7
|
+
|
|
8
|
+
<% if can_edit %>
|
|
9
|
+
<%= link_to 'Edit', edit_comment_path(comment),
|
|
10
|
+
:id => "edit_comment_#{comment.id.to_s}_link",
|
|
11
|
+
:class => "edit_comment_link",
|
|
12
|
+
:remote => true %>
|
|
13
|
+
<% end %>
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
<% if can_delete %>
|
|
18
|
+
<% if !comment.is_deleted? %>
|
|
19
|
+
<%= link_to('Delete', delete_comment_path(comment),
|
|
20
|
+
:confirm => 'Are you sure you want to delete this ' + @thread.config.comment_name + '?',
|
|
21
|
+
:method => :put,
|
|
22
|
+
:id => "delete_comment_#{comment.id.to_s}_link",
|
|
23
|
+
:class => "delete_comment_link",
|
|
24
|
+
:remote => true) %>
|
|
25
|
+
<% else %>
|
|
26
|
+
<%= link_to('Undelete', undelete_comment_path(comment),
|
|
27
|
+
:method => :put,
|
|
28
|
+
:id => "undelete_comment_#{comment.id.to_s}_link",
|
|
29
|
+
:class => "undelete_comment_link",
|
|
30
|
+
:remote => true) %>
|
|
31
|
+
<% end %>
|
|
32
|
+
<% end %>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<% # Clients of this partial must supply the following variables:
|
|
2
|
+
# comment
|
|
3
|
+
%>
|
|
4
|
+
|
|
5
|
+
<% can_edit = comment.can_be_edited_by?(@commontator)
|
|
6
|
+
can_delete = comment.can_be_deleted_by?(@commontator) %>
|
|
7
|
+
|
|
8
|
+
<% if can_edit %>
|
|
9
|
+
<%= link_to 'Edit', edit_comment_path(comment),
|
|
10
|
+
:id => "edit_comment_#{comment.id.to_s}_link",
|
|
11
|
+
:class => "edit_comment_link",
|
|
12
|
+
:remote => true %>
|
|
13
|
+
<% end %>
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
<% if can_delete %>
|
|
18
|
+
<% if !comment.is_deleted? %>
|
|
19
|
+
<%= link_to('Delete', delete_comment_path(comment),
|
|
20
|
+
:confirm => 'Are you sure you want to delete this ' + @thread.config.comment_name + '?',
|
|
21
|
+
:method => :put,
|
|
22
|
+
:id => "delete_comment_#{comment.id.to_s}_link",
|
|
23
|
+
:class => "delete_comment_link",
|
|
24
|
+
:remote => true) %>
|
|
25
|
+
<% else %>
|
|
26
|
+
<%= link_to('Undelete', undelete_comment_path(comment),
|
|
27
|
+
:confirm => 'Are you sure you want to delete this ' + @thread.config.comment_name + '?',
|
|
28
|
+
:method => :put,
|
|
29
|
+
:id => "delete_comment_#{comment.id.to_s}_link",
|
|
30
|
+
:class => "delete_comment_link",
|
|
31
|
+
:remote => true) %>
|
|
32
|
+
<% end %>
|
|
33
|
+
<% end %>
|