commontator 1.1.3 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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"/>
|