commontator 1.1.3 → 2.0.0
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/app/controllers/commontator/comments_controller.rb +3 -2
- data/app/controllers/commontator/comments_controller.rb~ +136 -0
- data/app/models/commontator/comment.rb +53 -36
- data/app/models/commontator/comment.rb~ +108 -0
- data/app/models/commontator/subscription.rb +8 -6
- data/app/models/commontator/subscription.rb~ +21 -0
- data/app/models/commontator/thread.rb +48 -44
- data/app/models/commontator/thread.rb~ +48 -47
- data/app/views/commontator/comments/_body.html.erb +1 -1
- data/app/views/commontator/comments/_body.html.erb~ +8 -0
- data/app/views/commontator/comments/_form.html.erb +1 -1
- data/app/views/commontator/comments/_form.html.erb~ +38 -0
- data/app/views/commontator/comments/_show.html.erb +1 -1
- data/app/views/commontator/comments/_show.html.erb~ +44 -0
- data/app/views/commontator/comments/_votes.html.erb +1 -1
- data/app/views/commontator/comments/_votes.html.erb~ +57 -0
- data/app/views/commontator/comments/delete.js.erb +1 -1
- data/app/views/commontator/comments/delete.js.erb~ +17 -0
- data/config/initializers/commontator.rb +11 -4
- data/config/initializers/commontator.rb~ +171 -0
- data/db/migrate/0_install.rb +23 -21
- data/db/migrate/0_install.rb~ +23 -21
- data/lib/commontator.rb +2 -0
- data/lib/commontator.rb~ +1 -1
- data/lib/commontator/acts_as_commontable.rb +7 -6
- data/lib/commontator/acts_as_commontable.rb~ +8 -6
- data/lib/commontator/acts_as_commontator.rb +4 -3
- data/lib/commontator/acts_as_commontator.rb~ +31 -0
- data/lib/commontator/version.rb +1 -1
- data/lib/commontator/version.rb~ +1 -1
- data/spec/app/controllers/commontator/comments_controller_spec.rb +61 -20
- data/spec/app/controllers/commontator/comments_controller_spec.rb~ +58 -21
- data/spec/app/models/commontator/comment_spec.rb +8 -7
- data/spec/app/models/commontator/comment_spec.rb~ +9 -8
- data/spec/app/models/commontator/thread_spec.rb +1 -1
- data/spec/app/models/commontator/thread_spec.rb~ +1 -1
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +16 -16
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +724 -0
- data/spec/dummy/log/test.log +41005 -0
- metadata +12 -2
@@ -1,47 +1,51 @@
|
|
1
1
|
module Commontator
|
2
2
|
class Thread < ActiveRecord::Base
|
3
3
|
belongs_to :closer, :polymorphic => true
|
4
|
+
|
4
5
|
belongs_to :commontable, :polymorphic => true
|
5
6
|
|
6
7
|
has_many :comments, :dependent => :destroy
|
8
|
+
|
7
9
|
has_many :subscriptions, :dependent => :destroy
|
8
10
|
|
9
|
-
validates_presence_of :commontable, :on => :create
|
10
|
-
|
11
11
|
attr_accessible :is_closed
|
12
|
-
|
12
|
+
|
13
|
+
validates_presence_of :commontable, :unless => :is_closed?
|
14
|
+
|
15
|
+
validates_uniqueness_of :commontable_id, :scope => :commontable_type, :allow_nil => true
|
16
|
+
|
13
17
|
def config
|
14
|
-
commontable.try(:commontable_config)
|
18
|
+
commontable.try(:commontable_config) || Commontator
|
15
19
|
end
|
16
|
-
|
20
|
+
|
17
21
|
def ordered_comments
|
18
|
-
(
|
22
|
+
(config.can_vote_on_comments && config.comments_ordered_by_votes) ? \
|
19
23
|
comments.order("cached_votes_down - cached_votes_up") : comments
|
20
24
|
end
|
21
|
-
|
25
|
+
|
26
|
+
def is_closed?
|
27
|
+
!closed_at.blank?
|
28
|
+
end
|
29
|
+
|
22
30
|
def subscribers
|
23
31
|
subscriptions.collect{|s| s.subscriber}
|
24
32
|
end
|
25
|
-
|
33
|
+
|
26
34
|
def active_subscribers
|
27
|
-
subscribers.select{|s| s.commontator_config.subscription_email_enable_proc.call(s)}
|
35
|
+
subscribers.select{|s| s.is_commontator && s.commontator_config.subscription_email_enable_proc.call(s)}
|
28
36
|
end
|
29
|
-
|
37
|
+
|
30
38
|
def subscription_for(subscriber)
|
31
|
-
return nil if subscriber.nil?
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
def is_closed?
|
36
|
-
!closed_at.blank?
|
39
|
+
return nil if subscriber.nil? || !subscriber.is_commontator
|
40
|
+
subscriber.subscriptions.where(:thread_id => self.id).first
|
37
41
|
end
|
38
|
-
|
42
|
+
|
39
43
|
def is_subscribed?(subscriber)
|
40
44
|
!subscription_for(subscriber).blank?
|
41
45
|
end
|
42
46
|
|
43
47
|
def subscribe(subscriber)
|
44
|
-
return false if is_subscribed?(subscriber)
|
48
|
+
return false if is_subscribed?(subscriber) || !subscriber.is_commontator
|
45
49
|
subscription = Subscription.create(
|
46
50
|
:subscriber => subscriber, :thread => self)
|
47
51
|
end
|
@@ -52,58 +56,57 @@ module Commontator
|
|
52
56
|
subscription.destroy
|
53
57
|
end
|
54
58
|
|
55
|
-
def mark_as_read_for(subscriber)
|
56
|
-
return if !subscription_for(subscriber)
|
57
|
-
subscription_for(subscriber).mark_as_read
|
58
|
-
end
|
59
|
-
|
60
59
|
def add_unread_except_for(subscriber)
|
61
60
|
Subscription.transaction do
|
62
61
|
subscriptions.each{|s| s.add_unread unless s.subscriber == subscriber}
|
63
62
|
end
|
64
63
|
end
|
65
|
-
|
64
|
+
|
65
|
+
def mark_as_read_for(subscriber)
|
66
|
+
return if !subscription_for(subscriber)
|
67
|
+
subscription_for(subscriber).mark_as_read
|
68
|
+
end
|
69
|
+
|
66
70
|
def close(user = nil)
|
67
71
|
return false if is_closed?
|
68
72
|
self.closed_at = Time.now
|
69
73
|
self.closer = user
|
70
|
-
|
74
|
+
save
|
71
75
|
end
|
72
|
-
|
76
|
+
|
73
77
|
def reopen
|
74
|
-
return false unless is_closed?
|
78
|
+
return false unless is_closed? && !commontable.nil?
|
75
79
|
self.closed_at = nil
|
76
|
-
|
80
|
+
save
|
77
81
|
end
|
78
|
-
|
82
|
+
|
79
83
|
# Creates a new empty thread and assigns it to the commontable
|
80
84
|
# The old thread is kept in the database for archival purposes
|
81
|
-
|
82
85
|
def clear(user = nil)
|
83
86
|
return if commontable.blank?
|
84
87
|
new_thread = Thread.new
|
85
88
|
new_thread.commontable = commontable
|
86
|
-
|
89
|
+
with_lock do
|
90
|
+
self.commontable = nil
|
91
|
+
self.closed_at = Time.now
|
92
|
+
self.closer = user
|
93
|
+
save!
|
87
94
|
new_thread.save!
|
88
|
-
commontable.thread = new_thread
|
89
|
-
commontable.save!
|
90
95
|
subscriptions.each do |s|
|
91
96
|
s.thread = new_thread
|
92
97
|
s.save!
|
93
98
|
s.mark_as_read
|
94
99
|
end
|
95
|
-
self.commontable = nil
|
96
|
-
self.close(user)
|
97
100
|
end
|
98
101
|
end
|
99
102
|
|
100
|
-
|
101
|
-
# Access
|
102
|
-
|
103
|
-
|
103
|
+
##################
|
104
|
+
# Access Control #
|
105
|
+
##################
|
106
|
+
|
104
107
|
# Reader and poster capabilities
|
105
108
|
def can_be_read_by?(user)
|
106
|
-
(!commontable.
|
109
|
+
(!commontable.nil? && \
|
107
110
|
(!is_closed? || config.closed_threads_are_readable) && \
|
108
111
|
config.can_read_thread_proc.call(self, user)) || \
|
109
112
|
can_be_edited_by?(user)
|
@@ -111,13 +114,14 @@ module Commontator
|
|
111
114
|
|
112
115
|
# Thread moderator capabilities
|
113
116
|
def can_be_edited_by?(user)
|
114
|
-
!commontable.
|
115
|
-
|
116
|
-
(!user.nil? && user.
|
117
|
+
(!commontable.nil? && \
|
118
|
+
config.can_edit_thread_proc.call(self, user)) || \
|
119
|
+
(!user.nil? && user.is_commontator && \
|
120
|
+
user.commontator_config.user_admin_proc.call(user))
|
117
121
|
end
|
118
122
|
|
119
123
|
def can_subscribe?(user)
|
120
|
-
!commontable.
|
124
|
+
!commontable.nil? && config.can_subscribe_to_thread && !is_closed? && can_be_read_by?(user)
|
121
125
|
end
|
122
126
|
end
|
123
127
|
end
|
@@ -1,49 +1,50 @@
|
|
1
|
-
puts 'b'
|
2
|
-
|
3
1
|
module Commontator
|
4
2
|
class Thread < ActiveRecord::Base
|
5
3
|
belongs_to :closer, :polymorphic => true
|
4
|
+
|
6
5
|
belongs_to :commontable, :polymorphic => true
|
7
6
|
|
8
7
|
has_many :comments, :dependent => :destroy
|
8
|
+
|
9
9
|
has_many :subscriptions, :dependent => :destroy
|
10
10
|
|
11
|
-
validates_presence_of :commontable, :on => :create
|
12
|
-
|
13
11
|
attr_accessible :is_closed
|
14
|
-
|
12
|
+
|
13
|
+
validates_presence_of :commontable, :unless => :is_closed?
|
14
|
+
|
15
|
+
validates_uniqueness_of :commontable_id, :scope => :commontable_type, :allow_nil => true
|
16
|
+
|
15
17
|
def config
|
16
|
-
commontable.try(:commontable_config)
|
18
|
+
commontable.try(:commontable_config) || Commontator
|
17
19
|
end
|
18
|
-
|
20
|
+
|
19
21
|
def ordered_comments
|
20
|
-
(
|
22
|
+
(config.can_vote_on_comments && config.comments_ordered_by_votes) ? \
|
21
23
|
comments.order("cached_votes_down - cached_votes_up") : comments
|
22
24
|
end
|
23
|
-
|
25
|
+
|
26
|
+
def is_closed?
|
27
|
+
!closed_at.blank?
|
28
|
+
end
|
29
|
+
|
24
30
|
def subscribers
|
25
|
-
subscriptions.collect{|s| s.subscriber}
|
26
31
|
end
|
27
|
-
|
32
|
+
|
28
33
|
def active_subscribers
|
29
|
-
subscribers.select{|s| s.commontator_config.subscription_email_enable_proc.call(s)}
|
34
|
+
subscribers.select{|s| s.is_commontator && s.commontator_config.subscription_email_enable_proc.call(s)}
|
30
35
|
end
|
31
|
-
|
36
|
+
|
32
37
|
def subscription_for(subscriber)
|
33
|
-
return nil if subscriber.nil?
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
def is_closed?
|
38
|
-
!closed_at.blank?
|
38
|
+
return nil if subscriber.nil? || !subscriber.is_commontator
|
39
|
+
subscriber.subscriptions.where(:thread_id => self.id).first
|
39
40
|
end
|
40
|
-
|
41
|
+
|
41
42
|
def is_subscribed?(subscriber)
|
42
43
|
!subscription_for(subscriber).blank?
|
43
44
|
end
|
44
45
|
|
45
46
|
def subscribe(subscriber)
|
46
|
-
return false if is_subscribed?(subscriber)
|
47
|
+
return false if is_subscribed?(subscriber) || !subscriber.is_commontator
|
47
48
|
subscription = Subscription.create(
|
48
49
|
:subscriber => subscriber, :thread => self)
|
49
50
|
end
|
@@ -54,58 +55,57 @@ module Commontator
|
|
54
55
|
subscription.destroy
|
55
56
|
end
|
56
57
|
|
57
|
-
def mark_as_read_for(subscriber)
|
58
|
-
return if !subscription_for(subscriber)
|
59
|
-
subscription_for(subscriber).mark_as_read
|
60
|
-
end
|
61
|
-
|
62
58
|
def add_unread_except_for(subscriber)
|
63
59
|
Subscription.transaction do
|
64
60
|
subscriptions.each{|s| s.add_unread unless s.subscriber == subscriber}
|
65
61
|
end
|
66
62
|
end
|
67
|
-
|
63
|
+
|
64
|
+
def mark_as_read_for(subscriber)
|
65
|
+
return if !subscription_for(subscriber)
|
66
|
+
subscription_for(subscriber).mark_as_read
|
67
|
+
end
|
68
|
+
|
68
69
|
def close(user = nil)
|
69
70
|
return false if is_closed?
|
70
71
|
self.closed_at = Time.now
|
71
72
|
self.closer = user
|
72
|
-
|
73
|
+
save
|
73
74
|
end
|
74
|
-
|
75
|
+
|
75
76
|
def reopen
|
76
|
-
return false unless is_closed?
|
77
|
+
return false unless is_closed? && !commontable.nil?
|
77
78
|
self.closed_at = nil
|
78
|
-
|
79
|
+
save
|
79
80
|
end
|
80
|
-
|
81
|
+
|
81
82
|
# Creates a new empty thread and assigns it to the commontable
|
82
83
|
# The old thread is kept in the database for archival purposes
|
83
|
-
|
84
84
|
def clear(user = nil)
|
85
85
|
return if commontable.blank?
|
86
86
|
new_thread = Thread.new
|
87
87
|
new_thread.commontable = commontable
|
88
|
-
|
88
|
+
with_lock do
|
89
|
+
self.commontable = nil
|
90
|
+
self.closed_at = Time.now
|
91
|
+
self.closer = user
|
92
|
+
save!
|
89
93
|
new_thread.save!
|
90
|
-
commontable.thread = new_thread
|
91
|
-
commontable.save!
|
92
94
|
subscriptions.each do |s|
|
93
95
|
s.thread = new_thread
|
94
96
|
s.save!
|
95
97
|
s.mark_as_read
|
96
98
|
end
|
97
|
-
self.commontable = nil
|
98
|
-
self.close(user)
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
|
-
|
103
|
-
# Access
|
104
|
-
|
105
|
-
|
102
|
+
##################
|
103
|
+
# Access Control #
|
104
|
+
##################
|
105
|
+
|
106
106
|
# Reader and poster capabilities
|
107
107
|
def can_be_read_by?(user)
|
108
|
-
(!commontable.
|
108
|
+
(!commontable.nil? && \
|
109
109
|
(!is_closed? || config.closed_threads_are_readable) && \
|
110
110
|
config.can_read_thread_proc.call(self, user)) || \
|
111
111
|
can_be_edited_by?(user)
|
@@ -113,13 +113,14 @@ module Commontator
|
|
113
113
|
|
114
114
|
# Thread moderator capabilities
|
115
115
|
def can_be_edited_by?(user)
|
116
|
-
!commontable.
|
117
|
-
|
118
|
-
(!user.nil? && user.
|
116
|
+
(!commontable.nil? && \
|
117
|
+
config.can_edit_thread_proc.call(self, user)) || \
|
118
|
+
(!user.nil? && user.is_commontator && \
|
119
|
+
user.commontator_config.user_admin_proc.call(user))
|
119
120
|
end
|
120
121
|
|
121
122
|
def can_subscribe?(user)
|
122
|
-
!commontable.
|
123
|
+
!commontable.nil? && config.can_subscribe_to_thread && !is_closed? && can_be_read_by?(user)
|
123
124
|
end
|
124
125
|
end
|
125
126
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<% # Clients of this partial must provide the following variables:
|
2
|
+
# comment
|
3
|
+
#
|
4
|
+
# Additionally, they can override the following variables:
|
5
|
+
thread ||= nil
|
6
|
+
no_remote ||= false
|
7
|
+
%>
|
8
|
+
|
9
|
+
<% config = comment.thread.config %>
|
10
|
+
|
11
|
+
<% if comment.errors.any? %>
|
12
|
+
<div class="comment_error_explanation">
|
13
|
+
<h3>This <%= config.comment_name %> could not be
|
14
|
+
<%= comment.id.blank? ? config.comment_create_verb_past : 'updated' %> because of the following error<%= comment.errors.count == 1 ? '' : 's' %>:</h3>
|
15
|
+
|
16
|
+
<ul>
|
17
|
+
<% comment.errors.full_messages.each do |msg| %>
|
18
|
+
<li><%= msg %></li>
|
19
|
+
<% end %>
|
20
|
+
</ul>
|
21
|
+
</div>
|
22
|
+
<% end %>
|
23
|
+
|
24
|
+
<%= form_for([commontator, thread, comment],
|
25
|
+
:remote => !no_remote) do |f| %>
|
26
|
+
|
27
|
+
<div class="comment_form_field">
|
28
|
+
<%= f.text_area :body, :rows => '7' %>
|
29
|
+
</div>
|
30
|
+
|
31
|
+
<div class="comment_form_actions">
|
32
|
+
<%= f.submit (comment.id.blank? ? \
|
33
|
+
config.comment_create_verb_present : \
|
34
|
+
'update').capitalize + \
|
35
|
+
' ' + config.comment_name %>
|
36
|
+
</div>
|
37
|
+
|
38
|
+
<% end %>
|
@@ -12,7 +12,7 @@
|
|
12
12
|
<% end %>
|
13
13
|
|
14
14
|
<span id="comment_<%= comment.id.to_s %>_timestamp_span" class="comment_timestamp">
|
15
|
-
<%= comment.timestamp %>
|
15
|
+
<%= comment.timestamp %><%= " by #{commontator_name(comment.editor)}" if comment.is_modified? %>
|
16
16
|
</span>
|
17
17
|
</span>
|
18
18
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
<% # Clients of this partial must supply the following variables:
|
2
|
+
# comment
|
3
|
+
# user
|
4
|
+
%>
|
5
|
+
|
6
|
+
<div id="comment_<%= comment.id.to_s %>_div" class="comment">
|
7
|
+
<span id="comment_<%= comment.id.to_s %>_commontator_span" class="comment_commontator">
|
8
|
+
<% if !user.nil? && user.commontator_config.user_name_clickable %>
|
9
|
+
<%= link_to commontator_name(comment.creator), main_app.polymorphic_path(comment.creator) %>
|
10
|
+
<% else %>
|
11
|
+
<%= commontator_name(comment.creator) %>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<span id="comment_<%= comment.id.to_s %>_timestamp_span" class="comment_timestamp">
|
15
|
+
<%= comment.timestamp %><%= " by #{commontator_name(comment.editor)}" %>
|
16
|
+
</span>
|
17
|
+
</span>
|
18
|
+
|
19
|
+
<span id="comment_<%= comment.id.to_s %>_actions_span" class="comment_actions">
|
20
|
+
<%= render :partial => 'commontator/comments/actions',
|
21
|
+
:locals => {:comment => comment,
|
22
|
+
:user => user} %>
|
23
|
+
</span>
|
24
|
+
|
25
|
+
<br clear="all"/>
|
26
|
+
|
27
|
+
<span id="comment_<%= comment.id.to_s %>_gravatar_image_span" class="comment_gravatar_image">
|
28
|
+
<%= commontator_gravatar_image comment.creator %>
|
29
|
+
</span>
|
30
|
+
|
31
|
+
<span id="comment_<%= comment.id.to_s %>_votes_span" class="comment_votes">
|
32
|
+
<%= render :partial => 'commontator/comments/votes',
|
33
|
+
:locals => {:comment => comment,
|
34
|
+
:user => user} %>
|
35
|
+
</span>
|
36
|
+
|
37
|
+
<div id="comment_<%= comment.id.to_s %>_body_div" class="comment_body">
|
38
|
+
<%= render :partial => 'commontator/comments/body',
|
39
|
+
:locals => {:comment => comment} %>
|
40
|
+
</div>
|
41
|
+
|
42
|
+
</div>
|
43
|
+
|
44
|
+
<br clear="all"/>
|