commontator 4.6.0 → 4.6.1
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 +4 -4
- data/README.md +3 -7
- data/app/views/commontator/threads/_show.html.erb +3 -3
- data/lib/commontator/version.rb +1 -1
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +36 -0
- data/spec/dummy/log/test.log +24750 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/{e1f674c11941d62aac1764ef3a7134e4 → 72b63dddbc5c995f79af8e3c94904fd9} +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/{c69ee3cc5796188d873574179290a6ef → a473b3873e554893372a53d71f5e9879} +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/{e85565206c3e5fdf9dfeb367c85557b1 → a77b1a9223d168112e1705c29220116f} +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/{a3fb9025f90ff05a6fd4afc7ded2692c → afa63eb365bdf4f42584b17ac9176b9d} +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/{0f196a1a50363b0a076ec6e1ee5417f6 → d2244ccef8e05bb993f75715af0344cc} +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/decb63cac838a5314aa0c22a979f5ac9 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/{02d4b791eb831cf2057bf4703a1218d1 → f721383d531f067d82b071e14aed7a92} +0 -0
- metadata +131 -151
- data/app/assets/stylesheets/commontator/threads.css~ +0 -71
- data/app/controllers/commontator/application_controller.rb~ +0 -35
- data/app/controllers/commontator/comments_controller.rb~ +0 -153
- data/app/mailers/commontator/subscriptions_mailer.rb~ +0 -44
- data/app/models/commontator/comment.rb~ +0 -119
- data/app/models/commontator/thread.rb~ +0 -159
- data/app/views/commontator/comments/_form.html.erb~ +0 -39
- data/app/views/commontator/comments/_show.html.erb~ +0 -49
- data/app/views/commontator/comments/_votes.html.erb~ +0 -69
- data/app/views/commontator/comments/create.js.erb~ +0 -14
- data/app/views/commontator/comments/new.js.erb~ +0 -13
- data/app/views/commontator/subscriptions/_link.html.erb~ +0 -16
- data/app/views/commontator/threads/_reply.html.erb~ +0 -19
- data/app/views/commontator/threads/_show.html.erb~ +0 -95
- data/config/initializers/commontator.rb~ +0 -238
- data/config/locales/commontator/en.yml~ +0 -104
- data/db/migrate/0_install_commontator.rb~ +0 -54
- data/lib/commontator.rb~ +0 -142
- data/spec/app/models/commontator/comment_spec.rb~ +0 -74
- data/spec/dummy/app/models/dummy_user.rb~ +0 -16
- data/spec/dummy/config/initializers/commontator.rb~ +0 -15
- data/spec/dummy/tmp/cache/assets/test/sprockets/a41c8be5379abec3c0d0d98e2f0d5609 +0 -0
@@ -1,71 +0,0 @@
|
|
1
|
-
.thread {
|
2
|
-
display: block !important;
|
3
|
-
}
|
4
|
-
|
5
|
-
.thread_actions {
|
6
|
-
float: right;
|
7
|
-
}
|
8
|
-
|
9
|
-
.thread_header {
|
10
|
-
font-size: 16px;
|
11
|
-
font-weight: bold;
|
12
|
-
font-style: normal;
|
13
|
-
margin-top: 5px;
|
14
|
-
margin-bottom: 5px;
|
15
|
-
display: block;
|
16
|
-
}
|
17
|
-
|
18
|
-
.thread_new_comment {
|
19
|
-
display: none;
|
20
|
-
}
|
21
|
-
|
22
|
-
.thread_new_comment_link {
|
23
|
-
display: block;
|
24
|
-
}
|
25
|
-
|
26
|
-
/* Modified from:
|
27
|
-
http://www.strangerstudios.com/sandbox/pagination/diggstyle.php */
|
28
|
-
.thread_page_entries_info {
|
29
|
-
margin-top: 10px;
|
30
|
-
margin-bottom: 10px;
|
31
|
-
}
|
32
|
-
|
33
|
-
.thread_will_paginate {
|
34
|
-
margin-top: 10px;
|
35
|
-
margin-bottom: 10px;
|
36
|
-
}
|
37
|
-
|
38
|
-
.thread_pagination a {
|
39
|
-
padding: 2px 5px 2px 5px;
|
40
|
-
margin-right: 4px;
|
41
|
-
border: 1px solid #999;
|
42
|
-
|
43
|
-
text-decoration: none;
|
44
|
-
color: #666;
|
45
|
-
}
|
46
|
-
|
47
|
-
.thread_pagination a:hover,
|
48
|
-
.thread_pagination a:active {
|
49
|
-
border: 1px solid #555;
|
50
|
-
|
51
|
-
color: #000;
|
52
|
-
}
|
53
|
-
|
54
|
-
.thread_pagination em {
|
55
|
-
padding: 2px 5px 2px 5px;
|
56
|
-
margin-right: 4px;
|
57
|
-
border: 1px solid #555;
|
58
|
-
|
59
|
-
font-weight: bold;
|
60
|
-
background-color: #555;
|
61
|
-
color: #FFF;
|
62
|
-
}
|
63
|
-
|
64
|
-
.thread_pagination span {
|
65
|
-
padding: 2px 5px 2px 5px;
|
66
|
-
margin: 2px;
|
67
|
-
border: 1px solid #EEE;
|
68
|
-
|
69
|
-
color: #DDD;
|
70
|
-
}
|
71
|
-
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module Commontator
|
2
|
-
class ApplicationController < ActionController::Base
|
3
|
-
cattr_reader :app_routes
|
4
|
-
|
5
|
-
before_filter :get_user, :ensure_user, :set_app_routes
|
6
|
-
|
7
|
-
rescue_from SecurityTransgression, :with => lambda { head(:forbidden) }
|
8
|
-
|
9
|
-
protected
|
10
|
-
|
11
|
-
def security_transgression_unless(check)
|
12
|
-
raise SecurityTransgression unless check
|
13
|
-
end
|
14
|
-
|
15
|
-
def get_user
|
16
|
-
@user = Commontator.current_user_proc.call(self)
|
17
|
-
end
|
18
|
-
|
19
|
-
def ensure_user
|
20
|
-
security_transgression_unless(@user && @user.is_commontator)
|
21
|
-
end
|
22
|
-
|
23
|
-
def get_thread
|
24
|
-
@thread = params[:thread_id].blank? ? \
|
25
|
-
Commontator::Thread.find(params[:id]) : \
|
26
|
-
Commontator::Thread.find(params[:thread_id])
|
27
|
-
security_transgression_unless @thread.can_be_read_by? @user
|
28
|
-
end
|
29
|
-
|
30
|
-
def set_app_routes
|
31
|
-
@@app_routes = main_app
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
@@ -1,153 +0,0 @@
|
|
1
|
-
module Commontator
|
2
|
-
class CommentsController < Commontator::ApplicationController
|
3
|
-
before_filter :get_thread, :only => [:new, :create]
|
4
|
-
before_filter :get_comment_and_thread, :except => [:new, :create]
|
5
|
-
|
6
|
-
# GET /threads/1/comments/new
|
7
|
-
def new
|
8
|
-
@comment = Comment.new
|
9
|
-
@comment.thread = @thread
|
10
|
-
@comment.creator = @user
|
11
|
-
|
12
|
-
security_transgression_unless @comment.can_be_created_by?(@user)
|
13
|
-
|
14
|
-
@per_page = params[:per_page] || thread.config.comments_per_page
|
15
|
-
|
16
|
-
respond_to do |format|
|
17
|
-
format.html { redirect_to @thread }
|
18
|
-
format.js
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
# POST /threads/1/comments
|
24
|
-
def create
|
25
|
-
@comment = Comment.new
|
26
|
-
@comment.body = params[:comment].nil? ? nil : params[:comment][:body]
|
27
|
-
@comment.thread = @thread
|
28
|
-
@comment.creator = @user
|
29
|
-
|
30
|
-
security_transgression_unless @comment.can_be_created_by?(@user)
|
31
|
-
|
32
|
-
respond_to do |format|
|
33
|
-
if !params[:cancel].nil?
|
34
|
-
format.html { redirect_to @thread }
|
35
|
-
format.js { render :cancel }
|
36
|
-
elsif @comment.save
|
37
|
-
sub = @thread.config.thread_subscription.to_sym
|
38
|
-
@thread.subscribe(@user) if sub == :a || sub == :b
|
39
|
-
Subscription.comment_created(@comment)
|
40
|
-
|
41
|
-
@per_page = params[:per_page] || @thread.config.comments_per_page
|
42
|
-
|
43
|
-
format.html { redirect_to @thread }
|
44
|
-
format.js
|
45
|
-
else
|
46
|
-
format.html { redirect_to @thread }
|
47
|
-
format.js { render :new }
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# GET /comments/1/edit
|
53
|
-
def edit
|
54
|
-
security_transgression_unless @comment.can_be_edited_by?(@user)
|
55
|
-
|
56
|
-
respond_to do |format|
|
57
|
-
format.html { redirect_to @thread }
|
58
|
-
format.js
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
# PUT /comments/1
|
63
|
-
def update
|
64
|
-
security_transgression_unless @comment.can_be_edited_by?(@user)
|
65
|
-
@comment.body = params[:comment].nil? ? nil : params[:comment][:body]
|
66
|
-
@comment.editor = @user
|
67
|
-
|
68
|
-
respond_to do |format|
|
69
|
-
if !params[:cancel].nil?
|
70
|
-
format.html { redirect_to @thread }
|
71
|
-
format.js { render :cancel }
|
72
|
-
elsif @comment.save
|
73
|
-
format.html { redirect_to @thread }
|
74
|
-
format.js
|
75
|
-
else
|
76
|
-
format.html { redirect_to @thread }
|
77
|
-
format.js { render :edit }
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
# PUT /comments/1/delete
|
83
|
-
def delete
|
84
|
-
security_transgression_unless @comment.can_be_deleted_by?(@user)
|
85
|
-
|
86
|
-
@comment.errors.add(:base, t('commontator.comment.errors.already_deleted')) \
|
87
|
-
unless @comment.delete_by(@user)
|
88
|
-
|
89
|
-
respond_to do |format|
|
90
|
-
format.html { redirect_to @thread }
|
91
|
-
format.js { render :delete }
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
# PUT /comments/1/undelete
|
96
|
-
def undelete
|
97
|
-
security_transgression_unless @comment.can_be_deleted_by?(@user)
|
98
|
-
|
99
|
-
@comment.errors.add(:base, t('commontator.comment.errors.not_deleted')) \
|
100
|
-
unless @comment.undelete_by(@user)
|
101
|
-
|
102
|
-
respond_to do |format|
|
103
|
-
format.html { redirect_to @thread }
|
104
|
-
format.js { render :delete }
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
# PUT /comments/1/upvote
|
109
|
-
def upvote
|
110
|
-
security_transgression_unless @comment.can_be_voted_on_by?(@user)
|
111
|
-
|
112
|
-
@comment.upvote_from @user
|
113
|
-
|
114
|
-
respond_to do |format|
|
115
|
-
format.html { redirect_to @thread }
|
116
|
-
format.js { render :vote }
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
# PUT /comments/1/downvote
|
121
|
-
def downvote
|
122
|
-
security_transgression_unless @comment.can_be_voted_on_by?(@user) &&\
|
123
|
-
@comment.thread.config.comment_voting.to_sym == :ld
|
124
|
-
|
125
|
-
@comment.downvote_from @user
|
126
|
-
|
127
|
-
respond_to do |format|
|
128
|
-
format.html { redirect_to @thread }
|
129
|
-
format.js { render :vote }
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
# PUT /comments/1/unvote
|
134
|
-
def unvote
|
135
|
-
security_transgression_unless @comment.can_be_voted_on_by?(@user)
|
136
|
-
|
137
|
-
@comment.unvote :voter => @user
|
138
|
-
|
139
|
-
respond_to do |format|
|
140
|
-
format.html { redirect_to @thread }
|
141
|
-
format.js { render :vote }
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
protected
|
146
|
-
|
147
|
-
def get_comment_and_thread
|
148
|
-
@comment = Comment.find(params[:id])
|
149
|
-
@thread = @comment.thread
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
@@ -1,44 +0,0 @@
|
|
1
|
-
module Commontator
|
2
|
-
class SubscriptionsMailer < ActionMailer::Base
|
3
|
-
def comment_created(comment, recipients)
|
4
|
-
setup_variables(comment, recipients)
|
5
|
-
|
6
|
-
mail :to => @to,
|
7
|
-
:bcc => @bcc,
|
8
|
-
:from => @from,
|
9
|
-
:subject => t('commontator.email.comment_created.subject',
|
10
|
-
:creator_name => @creator_name,
|
11
|
-
:commontable_name => @commontable_name,
|
12
|
-
:commontable_url => @commontable_url)
|
13
|
-
end
|
14
|
-
|
15
|
-
protected
|
16
|
-
|
17
|
-
def setup_variables(comment, recipients)
|
18
|
-
@comment = comment
|
19
|
-
@thread = @comment.thread
|
20
|
-
@creator = @comment.creator
|
21
|
-
|
22
|
-
@creator_name = Commontator.commontator_name(@creator)
|
23
|
-
|
24
|
-
@commontable_name = Commontator.commontable_name(@thread)
|
25
|
-
|
26
|
-
@commontable_url = Commontator.commontable_url(@thread)
|
27
|
-
|
28
|
-
params = Hash.new
|
29
|
-
params[:comment] = @comment
|
30
|
-
params[:thread] = @thread
|
31
|
-
params[:creator] = @creator
|
32
|
-
params[:creator_name] = @creator_name
|
33
|
-
params[:commontable_name] = @commontable_name
|
34
|
-
params[:commontable_url] = @commontable_url
|
35
|
-
|
36
|
-
@to = t('commontator.email.undisclosed_recipients')
|
37
|
-
@bcc = recipients.collect{|s| Commontator.commontator_email(s, self)}
|
38
|
-
@from = @config.email_from_proc.call(@thread)
|
39
|
-
end
|
40
|
-
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
@@ -1,119 +0,0 @@
|
|
1
|
-
module Commontator
|
2
|
-
class Comment < ActiveRecord::Base
|
3
|
-
belongs_to :creator, :polymorphic => true
|
4
|
-
belongs_to :editor, :polymorphic => true
|
5
|
-
belongs_to :thread
|
6
|
-
|
7
|
-
has_one :commontable, :through => :thread
|
8
|
-
|
9
|
-
validates_presence_of :creator, :on => :create
|
10
|
-
validates_presence_of :editor, :on => :update
|
11
|
-
validates_presence_of :thread
|
12
|
-
validates_presence_of :body
|
13
|
-
|
14
|
-
validates_uniqueness_of :body,
|
15
|
-
:scope => [:creator_type, :creator_id, :thread_id],
|
16
|
-
:message => I18n.t('commontator.comment.errors.double_posted')
|
17
|
-
|
18
|
-
protected
|
19
|
-
|
20
|
-
cattr_accessor :acts_as_votable_initialized
|
21
|
-
|
22
|
-
public
|
23
|
-
|
24
|
-
def is_modified?
|
25
|
-
!editor.nil?
|
26
|
-
end
|
27
|
-
|
28
|
-
def is_latest?
|
29
|
-
thread.comments.last == self
|
30
|
-
end
|
31
|
-
|
32
|
-
def is_votable?
|
33
|
-
return true if acts_as_votable_initialized
|
34
|
-
return false unless self.class.respond_to?(:acts_as_votable)
|
35
|
-
self.class.acts_as_votable
|
36
|
-
self.class.acts_as_votable_initialized = true
|
37
|
-
end
|
38
|
-
|
39
|
-
def get_vote_by(user)
|
40
|
-
return nil unless is_votable? && user && user.is_commontator
|
41
|
-
votes.where(:voter_type => user.class.name, :voter_id => user.id).first
|
42
|
-
end
|
43
|
-
|
44
|
-
def update_cached_votes(vote_scope = nil)
|
45
|
-
self.update_column(:cached_votes_up, count_votes_up(true)
|
46
|
-
self.update_column(:cached_votes_down, count_votes_down(true)
|
47
|
-
end
|
48
|
-
|
49
|
-
def is_deleted?
|
50
|
-
!deleted_at.blank?
|
51
|
-
end
|
52
|
-
|
53
|
-
def delete_by(user)
|
54
|
-
return false if is_deleted?
|
55
|
-
self.deleted_at = Time.now
|
56
|
-
self.editor = user
|
57
|
-
self.save
|
58
|
-
end
|
59
|
-
|
60
|
-
def undelete_by(user)
|
61
|
-
return false unless is_deleted?
|
62
|
-
self.deleted_at = nil
|
63
|
-
self.editor = user
|
64
|
-
self.save
|
65
|
-
end
|
66
|
-
|
67
|
-
def created_timestamp
|
68
|
-
I18n.t 'commontator.comment.status.created_at',
|
69
|
-
:created_at => I18n.l(created_at, :format => :commontator)
|
70
|
-
end
|
71
|
-
|
72
|
-
def updated_timestamp
|
73
|
-
I18n.t 'commontator.comment.status.updated_at',
|
74
|
-
:editor_name => Commontator.commontator_name(editor || creator),
|
75
|
-
:updated_at => I18n.l(updated_at, :format => :commontator)
|
76
|
-
end
|
77
|
-
|
78
|
-
##################
|
79
|
-
# Access Control #
|
80
|
-
##################
|
81
|
-
|
82
|
-
def can_be_created_by?(user)
|
83
|
-
user == creator && user.is_commontator &&\
|
84
|
-
!thread.is_closed? && thread.can_be_read_by?(user)
|
85
|
-
end
|
86
|
-
|
87
|
-
def can_be_edited_by?(user)
|
88
|
-
return true if thread.can_be_edited_by?(user) &&\
|
89
|
-
thread.config.moderator_permissions.to_sym == :e
|
90
|
-
comment_edit = thread.config.comment_editing.to_sym
|
91
|
-
!thread.is_closed? && !is_deleted? && user == creator &&\
|
92
|
-
comment_edit != :n && (is_latest? || comment_edit == :a) &&\
|
93
|
-
thread.can_be_read_by?(user)
|
94
|
-
end
|
95
|
-
|
96
|
-
def can_be_deleted_by?(user)
|
97
|
-
mod_perm = thread.config.moderator_permissions.to_sym
|
98
|
-
return true if thread.can_be_edited_by?(user) &&\
|
99
|
-
(mod_perm == :e ||\
|
100
|
-
mod_perm == :d)
|
101
|
-
comment_del = thread.config.comment_deletion.to_sym
|
102
|
-
!thread.is_closed? && (!is_deleted? || editor == user) &&\
|
103
|
-
user == creator && comment_del != :n &&\
|
104
|
-
(is_latest? || comment_del == :a) &&\
|
105
|
-
thread.can_be_read_by?(user)
|
106
|
-
end
|
107
|
-
|
108
|
-
def can_be_voted_on?
|
109
|
-
!thread.is_closed? && !is_deleted? &&\
|
110
|
-
thread.config.comment_voting.to_sym != :n && is_votable?
|
111
|
-
end
|
112
|
-
|
113
|
-
def can_be_voted_on_by?(user)
|
114
|
-
!user.nil? && user.is_commontator && user != creator &&\
|
115
|
-
thread.can_be_read_by?(user) && can_be_voted_on?
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
@@ -1,159 +0,0 @@
|
|
1
|
-
module Commontator
|
2
|
-
class Thread < ActiveRecord::Base
|
3
|
-
belongs_to :closer, :polymorphic => true
|
4
|
-
belongs_to :commontable, :polymorphic => true
|
5
|
-
|
6
|
-
has_many :comments, :dependent => :destroy
|
7
|
-
has_many :subscriptions, :dependent => :destroy
|
8
|
-
|
9
|
-
validates_presence_of :commontable, :unless => :is_closed?
|
10
|
-
validates_uniqueness_of :commontable_id,
|
11
|
-
:scope => :commontable_type,
|
12
|
-
:allow_nil => true
|
13
|
-
|
14
|
-
def config
|
15
|
-
@config ||= commontable.try(:commontable_config) || Commontator
|
16
|
-
end
|
17
|
-
|
18
|
-
def will_paginate?
|
19
|
-
return false if config.comments_per_page.nil? || !comments.respond_to?(:paginate)
|
20
|
-
require 'commontator/link_renderer'
|
21
|
-
true
|
22
|
-
end
|
23
|
-
|
24
|
-
def is_filtered?
|
25
|
-
will_paginate? || config.comment_filter
|
26
|
-
end
|
27
|
-
|
28
|
-
def filtered_comments
|
29
|
-
cf = config.comment_filter
|
30
|
-
return comments if cf.nil?
|
31
|
-
comments.where(cf)
|
32
|
-
end
|
33
|
-
|
34
|
-
def ordered_comments(override = false)
|
35
|
-
vc = override ? comments : filtered_comments
|
36
|
-
case config.comment_order.to_sym
|
37
|
-
when :l then vc.order('id DESC')
|
38
|
-
when :ve then vc.order('cached_votes_down - cached_votes_up')
|
39
|
-
when :vl then vc.order('cached_votes_down - cached_votes_up', 'id DESC')
|
40
|
-
else vc
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def paginated_comments(page = 1, per_page = config.comments_per_page)
|
45
|
-
oc = ordered_comments
|
46
|
-
return oc unless will_paginate?
|
47
|
-
oc.paginate(:page => page, :per_page => per_page)
|
48
|
-
end
|
49
|
-
|
50
|
-
def new_comment_page(per_page = config.comments_per_page)
|
51
|
-
return 1 if per_page.nil? || per_page.to_i <= 0
|
52
|
-
comment_index = \
|
53
|
-
case config.comment_order.to_sym
|
54
|
-
when :l
|
55
|
-
1 # First comment
|
56
|
-
when :ve
|
57
|
-
comment_arel = Comment.arel_table
|
58
|
-
# Last comment with rating = 0
|
59
|
-
filtered_comments.where((comment_arel[:cached_votes_up] - comment_arel[:cached_votes_down]).gteq 0).count
|
60
|
-
when :vl
|
61
|
-
comment_arel = Comment.arel_table
|
62
|
-
# First comment with rating = 0
|
63
|
-
filtered_comments.where((comment_arel[:cached_votes_up] - comment_arel[:cached_votes_down]).gt 0).count + 1
|
64
|
-
else
|
65
|
-
filtered_comments.count # Last comment
|
66
|
-
end
|
67
|
-
(comment_index.to_f/per_page.to_i).ceil
|
68
|
-
end
|
69
|
-
|
70
|
-
def is_closed?
|
71
|
-
!closed_at.blank?
|
72
|
-
end
|
73
|
-
|
74
|
-
def close(user = nil)
|
75
|
-
return false if is_closed?
|
76
|
-
self.closed_at = Time.now
|
77
|
-
self.closer = user
|
78
|
-
save
|
79
|
-
end
|
80
|
-
|
81
|
-
def reopen
|
82
|
-
return false unless is_closed? && !commontable.nil?
|
83
|
-
self.closed_at = nil
|
84
|
-
save
|
85
|
-
end
|
86
|
-
|
87
|
-
def subscribers
|
88
|
-
subscriptions.collect{|s| s.subscriber}
|
89
|
-
end
|
90
|
-
|
91
|
-
def subscription_for(subscriber)
|
92
|
-
return nil if !subscriber || !subscriber.is_commontator
|
93
|
-
subscriber.subscriptions.where(:thread_id => self.id).first
|
94
|
-
end
|
95
|
-
|
96
|
-
def subscribe(subscriber)
|
97
|
-
return false unless subscriber.is_commontator && !subscription_for(subscriber)
|
98
|
-
subscription = Subscription.new
|
99
|
-
subscription.subscriber = subscriber
|
100
|
-
subscription.thread = self
|
101
|
-
subscription.save
|
102
|
-
end
|
103
|
-
|
104
|
-
def unsubscribe(subscriber)
|
105
|
-
subscription = subscription_for(subscriber)
|
106
|
-
return false unless subscription
|
107
|
-
subscription.destroy
|
108
|
-
end
|
109
|
-
|
110
|
-
def mark_as_read_for(subscriber)
|
111
|
-
subscription = subscription_for(subscriber)
|
112
|
-
return false unless subscription
|
113
|
-
subscription.touch
|
114
|
-
end
|
115
|
-
|
116
|
-
# Creates a new empty thread and assigns it to the commontable
|
117
|
-
# The old thread is kept in the database for archival purposes
|
118
|
-
def clear
|
119
|
-
return if commontable.blank? || !is_closed?
|
120
|
-
new_thread = Thread.new
|
121
|
-
new_thread.commontable = commontable
|
122
|
-
|
123
|
-
with_lock do
|
124
|
-
self.commontable = nil
|
125
|
-
save!
|
126
|
-
new_thread.save!
|
127
|
-
subscriptions.each do |s|
|
128
|
-
s.thread = new_thread
|
129
|
-
s.save!
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
##################
|
135
|
-
# Access Control #
|
136
|
-
##################
|
137
|
-
|
138
|
-
# Reader capabilities (user can be nil or false)
|
139
|
-
def can_be_read_by?(user)
|
140
|
-
return true if can_be_edited_by?(user)
|
141
|
-
!commontable.nil? &&\
|
142
|
-
config.thread_read_proc.call(self, user)
|
143
|
-
end
|
144
|
-
|
145
|
-
# Thread moderator capabilities
|
146
|
-
def can_be_edited_by?(user)
|
147
|
-
!commontable.nil? && !user.nil? && user.is_commontator &&\
|
148
|
-
config.thread_moderator_proc.call(self, user)
|
149
|
-
end
|
150
|
-
|
151
|
-
def can_subscribe?(user)
|
152
|
-
thread_sub = config.thread_subscription.to_sym
|
153
|
-
!is_closed? && !user.nil? && user.is_commontator &&\
|
154
|
-
(thread_sub == :m || thread_sub == :b) &&\
|
155
|
-
can_be_read_by?(user)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|