radiant-forum-extension 1.1.2 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/VERSION +1 -1
  2. data/app/controllers/admin/forums_controller.rb +3 -4
  3. data/app/controllers/admin/posts_controller.rb +10 -0
  4. data/app/controllers/admin/topics_controller.rb +10 -0
  5. data/app/controllers/posts_controller.rb +3 -27
  6. data/app/controllers/topics_controller.rb +3 -17
  7. data/app/helpers/forum_helper.rb +2 -2
  8. data/app/models/forum.rb +2 -24
  9. data/app/models/post.rb +12 -9
  10. data/app/models/post_attachment.rb +13 -13
  11. data/app/models/topic.rb +28 -55
  12. data/app/views/admin/forums/edit.html.haml +2 -1
  13. data/app/views/admin/forums/index.html.haml +42 -39
  14. data/app/views/admin/posts/_form.html.haml +25 -0
  15. data/app/views/admin/posts/edit.html.haml +6 -0
  16. data/app/views/admin/posts/index.html.haml +49 -0
  17. data/app/views/admin/reader_configuration/_edit_forum.html.haml +3 -3
  18. data/app/views/admin/reader_configuration/_forum.html.haml +19 -14
  19. data/app/views/admin/topics/_form.html.haml +24 -0
  20. data/app/views/admin/topics/edit.html.haml +6 -0
  21. data/app/views/admin/topics/index.html.haml +49 -0
  22. data/app/views/forums/index.html.haml +0 -7
  23. data/app/views/forums/show.html.haml +4 -3
  24. data/app/views/posts/_attachment.html.haml +4 -0
  25. data/app/views/posts/_form.html.haml +1 -3
  26. data/app/views/posts/_post.html.haml +50 -51
  27. data/app/views/posts/_reply.html.haml +16 -17
  28. data/app/views/posts/_search.html.haml +13 -17
  29. data/app/views/posts/_upload.html.haml +2 -0
  30. data/app/views/posts/_uploader.html.haml +15 -15
  31. data/app/views/posts/edit.html.haml +5 -7
  32. data/app/views/posts/index.html.haml +1 -8
  33. data/app/views/posts/search.html.haml +54 -45
  34. data/app/views/posts/show.html.haml +14 -6
  35. data/app/views/topics/_form.html.haml +15 -11
  36. data/app/views/topics/_latest.html.haml +0 -2
  37. data/app/views/topics/_locked.html.haml +2 -2
  38. data/app/views/topics/_topic.html.haml +50 -31
  39. data/app/views/topics/comments.html.haml +2 -1
  40. data/app/views/topics/index.html.haml +1 -9
  41. data/app/views/topics/new.html.haml +29 -18
  42. data/app/views/topics/show.html.haml +14 -14
  43. data/config/initializers/radiant_config.rb +12 -0
  44. data/config/locales/en.yml +81 -12
  45. data/forum_extension.rb +11 -16
  46. data/lib/forum_admin_ui.rb +47 -5
  47. data/radiant-forum-extension.gemspec +12 -4
  48. metadata +14 -6
  49. data/app/views/readers/_extra_controls.html.haml +0 -5
  50. data/app/views/readers/show_with_posts.html.haml +0 -47
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.2
1
+ 1.2.1
@@ -1,11 +1,10 @@
1
1
  class Admin::ForumsController < Admin::ResourceController
2
-
3
- # # I have no idea where this default is being overridden
4
- # skip_before_filter :verify_authenticity_token if ENV["RAILS_ENV"] == "test"
2
+ helper :forum
3
+ paginate_models
5
4
 
6
5
  only_allow_access_to :new, :create, :edit, :update, :remove, :destroy,
7
6
  :when => :admin,
8
7
  :denied_url => { :controller => 'pages', :action => 'index' },
9
- :denied_message => 'You must be an administrator to add or change discussion categories.'
8
+ :denied_message => 'You must be an administrator to edit topics.'
10
9
 
11
10
  end
@@ -0,0 +1,10 @@
1
+ class Admin::PostsController < Admin::ResourceController
2
+ helper :forum
3
+ paginate_models
4
+
5
+ only_allow_access_to :new, :create, :edit, :update, :remove, :destroy,
6
+ :when => :admin,
7
+ :denied_url => { :controller => 'pages', :action => 'index' },
8
+ :denied_message => 'You must be an administrator to edit posts.'
9
+
10
+ end
@@ -0,0 +1,10 @@
1
+ class Admin::TopicsController < Admin::ResourceController
2
+ helper :forum
3
+ paginate_models
4
+
5
+ only_allow_access_to :new, :create, :edit, :update, :remove, :destroy,
6
+ :when => :admin,
7
+ :denied_url => { :controller => 'pages', :action => 'index' },
8
+ :denied_message => 'You must be an administrator to add or change discussion categories.'
9
+
10
+ end
@@ -6,7 +6,7 @@ class PostsController < ReaderActionController
6
6
  before_filter :require_activated_reader, :except => [:index, :show, :search]
7
7
  before_filter :find_topic_or_page, :except => [:index, :search]
8
8
  before_filter :require_unlocked_topic_and_page, :only => [:new, :create]
9
- before_filter :find_post, :except => [:index, :search]
9
+ before_filter :find_post, :except => [:index, :search, :new, :create]
10
10
  before_filter :build_post, :only => [:new]
11
11
  before_filter :require_authority, :only => [:edit, :update, :destroy]
12
12
 
@@ -42,19 +42,7 @@ class PostsController < ReaderActionController
42
42
  @forums = @posts.collect(&:forum).uniq
43
43
  @topics = @posts.collect(&:topic).uniq
44
44
  @readers = @posts.collect(&:reader).uniq
45
-
46
- if @searching
47
- @title = "Search Results"
48
- @description = "Posts"
49
- @description << " matching '#{params[:q]}'" unless params[:q].blank?
50
- @description << " from #{@reader.name}" if @reader
51
- if @topic
52
- @description << " under #{@topic.name}"
53
- elsif @forum
54
- @description << " in #{@forum.name}"
55
- end
56
- end
57
-
45
+
58
46
  render_page_or_feed
59
47
  end
60
48
 
@@ -88,29 +76,17 @@ class PostsController < ReaderActionController
88
76
  def create
89
77
  if @topic.new_record?
90
78
  # only happens if it's a page comment and the topic has just been built
91
- # in that case we can let the topic-creation routines do the post work
92
- @topic.body = params[:post][:body]
93
79
  @topic.reader = current_reader
94
80
  @topic.save!
95
- @post = @topic.first_post
96
- else
97
- @post = @topic.posts.create!(params[:post])
98
81
  end
82
+ @post = @topic.posts.create!(params[:post])
99
83
 
100
- @post.save_attachments(params[:files]) unless @page && !Radiant::Config['forum.comments_have_attachments']
101
84
  Radiant::Cache.clear if @page
102
85
 
103
86
  respond_to do |format|
104
87
  format.html { redirect_to_page_or_topic }
105
88
  format.js { render :action => 'show', :layout => false }
106
89
  end
107
-
108
- rescue ActiveRecord::RecordInvalid
109
- flash[:error] = 'Problem!'
110
- respond_to do |format|
111
- format.html { render :action => 'new' }
112
- format.js { render :action => 'new', :layout => false }
113
- end
114
90
  end
115
91
 
116
92
  def topic_locked
@@ -10,13 +10,12 @@ class TopicsController < ReaderActionController
10
10
 
11
11
  def index
12
12
  params[:per_page] ||= 20
13
- @topics = Topic.visible.paginate(:all, pagination_parameters.merge(:order => "topics.sticky desc, topics.replied_at desc", :include => [:forum, :reader]))
13
+ @topics = Topic.paginate(:all, pagination_parameters.merge(:order => "topics.sticky desc, topics.replied_at desc", :include => [:forum, :reader]))
14
14
  render_page_or_feed
15
15
  end
16
16
 
17
17
  def new
18
18
  @topic = Topic.new
19
- @topic.first_post = @topic.posts.build
20
19
  @topic.forum = @forum || Forum.find_by_name(Radiant::Config['forum.default_forum'])
21
20
  end
22
21
 
@@ -27,33 +26,20 @@ class TopicsController < ReaderActionController
27
26
  end
28
27
  @topic.hit! unless current_reader and @topic.reader == current_reader
29
28
  store_location((request.format == 'text/html') ? request.request_uri : request.referer)
30
-
31
- params[:per_page] ||= 20
32
- params[:page] = 1 if params[:page] == 'first'
33
- params[:page] = (@topic.posts.count.to_f / params[:per_page].to_f).ceil if params[:page] == 'last'
34
- @posts = Post.paginate_by_topic_id(@topic.id, :page => params[:page], :per_page => params[:per_page], :include => :reader, :order => 'posts.created_at asc')
29
+ @first_post = @topic.first_post
30
+ @posts = @topic.replies.paginate(pagination_parameters.merge(:include => :reader, :order => 'posts.created_at asc'))
35
31
  render_page_or_feed(@page ? 'comments' : 'show')
36
32
  end
37
33
 
38
34
  def create
39
- # post creation is handled by a before_create in the topic model
40
- # and then calls back to set initial reply data in the topic
41
35
  @forum = Forum.find(params[:topic][:forum_id]) if params[:topic][:forum_id]
42
36
  @topic = @forum.topics.create!(params[:topic])
43
- @topic.first_post.save_attachments(params[:files]) unless @topic.page && !Radiant::Config['forum.comments_have_attachments']
44
-
45
37
  respond_to do |format|
46
38
  format.html { redirect_to forum_topic_path(@forum, @topic) }
47
39
  end
48
- rescue ActiveRecord::RecordInvalid => invalid
49
- flash[:error] = "Sorry: #{invalid}. Please check the form"
50
- respond_to do |format|
51
- format.html { render :action => 'new' }
52
- end
53
40
  end
54
41
 
55
42
  def update
56
- # post update is handled by a before_update in the topic model
57
43
  @topic.attributes = params[:topic]
58
44
  @topic.save!
59
45
  respond_to do |format|
@@ -62,7 +62,7 @@ module ForumHelper
62
62
  elsif (date.to_datetime == Date.yesterday)
63
63
  format = t('time_yesterday')
64
64
  elsif (date.to_datetime > 6.days.ago)
65
- format = t('time_recently')
65
+ format = t('date_recently')
66
66
  elsif (date.year == Date.today.year)
67
67
  format = t('date_this_year')
68
68
  else
@@ -101,5 +101,5 @@ module ForumHelper
101
101
  end
102
102
  end
103
103
  end
104
-
104
+
105
105
  end
data/app/models/forum.rb CHANGED
@@ -1,34 +1,12 @@
1
1
  class Forum < ActiveRecord::Base
2
- is_site_scoped if defined? ActiveRecord::SiteNotFound
2
+ has_site if respond_to? :has_site
3
3
  default_scope :order => 'name ASC'
4
4
  belongs_to :created_by, :class_name => 'User'
5
5
  belongs_to :updated_by, :class_name => 'User'
6
6
  validates_presence_of :name
7
7
  named_scope :visible, {}
8
8
 
9
- has_many :topics, :order => 'sticky desc, replied_at desc', :dependent => :destroy do
10
- def first
11
- @first_topic ||= find(:first)
12
- end
13
- end
14
-
15
- has_many :recent_topics, :class_name => 'Topic', :order => 'replied_at desc' do
16
- def first
17
- @first_recent_topic ||= find(:first)
18
- end
19
- def latest
20
- @latest_topics ||= find(:all, :limit => 5)
21
- end
22
- end
23
-
24
- has_many :posts, :order => 'posts.created_at desc' do
25
- def last
26
- @last_post ||= find(:first, :include => :reader)
27
- end
28
- def latest
29
- @latest_posts ||= find(:all, :limit => 5)
30
- end
31
- end
9
+ has_many :topics, :order => 'topics.sticky desc, topics.replied_at desc', :dependent => :destroy
32
10
 
33
11
  def self.find_or_create_comments_forum
34
12
  @comments_forum = self.find_by_for_comments(true) || self.create(
data/app/models/post.rb CHANGED
@@ -1,24 +1,22 @@
1
1
  require 'sanitize'
2
2
  class Post < ActiveRecord::Base
3
+ has_site if respond_to? :has_site
3
4
 
4
- is_site_scoped if defined? ActiveRecord::SiteNotFound
5
-
6
- belongs_to :forum, :counter_cache => true
7
5
  belongs_to :reader, :counter_cache => true
8
6
  belongs_to :topic, :counter_cache => true
9
7
  belongs_to :created_by, :class_name => 'User'
10
8
  belongs_to :updated_by, :class_name => 'User'
11
9
  has_many :attachments, :class_name => 'PostAttachment', :order => :position, :dependent => :destroy
12
-
13
- attr_writer :name
10
+ accepts_nested_attributes_for :attachments, :allow_destroy => true
14
11
 
15
12
  before_validation :set_reader
16
- before_create :set_forum
17
13
  after_create :update_topic_reply_data
18
14
  after_destroy :revert_topic_reply_data
19
15
 
20
- validates_presence_of :reader, :topic, :body
16
+ validates_presence_of :reader, :body
17
+ # validates_presence_of :topic
21
18
 
19
+ default_scope :order => "created_at DESC"
22
20
  named_scope :visible, {}
23
21
  named_scope :latest, lambda { |count|
24
22
  {
@@ -26,6 +24,11 @@ class Post < ActiveRecord::Base
26
24
  :limit => count
27
25
  }
28
26
  }
27
+ named_scope :except, lambda { |post|
28
+ {
29
+ :conditions => ["NOT posts.id = ?", post.id]
30
+ }
31
+ }
29
32
 
30
33
  def topic_page
31
34
  self.topic.page_for(self)
@@ -112,11 +115,11 @@ protected
112
115
  end
113
116
 
114
117
  def update_topic_reply_data
115
- self.topic.refresh_reply_data(self)
118
+ self.topic.refresh_reply_data if self.topic # topic association not set during initial topic creation because of nested create
116
119
  end
117
120
 
118
121
  def revert_topic_reply_data
119
- self.topic.refresh_reply_data
122
+ self.topic.refresh_reply_data if self.topic # topic association not set during initial topic creation because of nested create
120
123
  end
121
124
 
122
125
  end
@@ -25,21 +25,21 @@ class PostAttachment < ActiveRecord::Base
25
25
  belongs_to :reader
26
26
  acts_as_list :scope => :post_id
27
27
  has_attached_file :file,
28
- :styles => lambda { |attachment|
29
- if image_content_types.include? attachment.instance_read(:content_type)
30
- thumbnail_sizes
31
- else
32
- {}
33
- end
34
- },
35
- :whiny_thumbnails => false,
36
- :url => "/:class/:id/:basename:no_original_style.:extension",
37
- :path => ":rails_root/public/:class/:id/:basename:no_original_style.:extension"
28
+ :styles => lambda { |attachment|
29
+ if image_content_types.include? attachment.instance_read(:content_type)
30
+ thumbnail_sizes
31
+ else
32
+ {}
33
+ end
34
+ },
35
+ :whiny_thumbnails => false,
36
+ :url => "/:class/:id/:basename:no_original_style.:extension",
37
+ :path => ":rails_root/public/:class/:id/:basename:no_original_style.:extension"
38
38
 
39
39
  attr_protected :file_file_name, :file_content_type, :file_file_size
40
- validates_attachment_presence :file, :message => "You must choose a file to upload!"
41
- validates_attachment_content_type :file, :content_type => Radiant::Config["forum.attachment_content_types"].split(', ') if Radiant::Config.table_exists? && Radiant::Config["forum.attachment_content_types"]
42
- validates_attachment_size :file, :less_than => Radiant::Config["forum.max_attachment_size"].to_i.megabytes if Radiant::Config.table_exists? && Radiant::Config["forum.max_attachment_size"]
40
+ validates_attachment_presence :file, :message => t('no_file')
41
+ validates_attachment_content_type :file, :content_type => Radiant::Config["forum.attachment.content_types"].split(', ') if Radiant::Config.table_exists? && !Radiant::Config["forum.attachment.content_types"].blank?
42
+ validates_attachment_size :file, :less_than => Radiant::Config["forum.attachment.max_size"].to_i.megabytes if Radiant::Config.table_exists? && Radiant::Config["forum.attachment.max_size"]
43
43
 
44
44
  named_scope :images, :conditions => ["file_content_type IN (#{image_content_types.map{'?'}.join(',')})", *image_content_types]
45
45
  named_scope :non_images, :conditions => ["file_content_type NOT IN (#{image_content_types.map{'?'}.join(',')})", *image_content_types]
data/app/models/topic.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  class Topic < ActiveRecord::Base
2
- is_site_scoped if defined? ActiveRecord::SiteNotFound
2
+ has_site if respond_to? :has_site
3
3
 
4
4
  belongs_to :forum, :counter_cache => true
5
5
  belongs_to :page
@@ -7,10 +7,12 @@ class Topic < ActiveRecord::Base
7
7
  belongs_to :created_by, :class_name => 'User'
8
8
  belongs_to :updated_by, :class_name => 'User'
9
9
 
10
- belongs_to :first_post, :class_name => 'Post', :include => :reader # aka topic.body. should not change
11
- belongs_to :last_post, :class_name => 'Post', :include => :reader # this is just for display efficiency.
12
- belongs_to :replied_by, :class_name => 'Reader' # this too.
13
- has_many :posts, :order => 'posts.created_at', :include => :reader, :dependent => :destroy do
10
+ belongs_to :first_post, :class_name => 'Post'
11
+ accepts_nested_attributes_for :first_post
12
+
13
+ belongs_to :last_post, :class_name => 'Post', :include => :reader
14
+ belongs_to :replied_by, :class_name => 'Reader'
15
+ has_many :posts, :order => 'posts.created_at ASC', :include => :reader, :dependent => :destroy do
14
16
  def last
15
17
  @last_post ||= find(:last)
16
18
  end
@@ -20,21 +22,23 @@ class Topic < ActiveRecord::Base
20
22
  validates_uniqueness_of :old_id, :allow_nil => true
21
23
 
22
24
  before_validation :set_reader
25
+ before_validation :echo_inspection
23
26
  before_create :set_defaults
24
- before_update :check_for_changing_forums
25
- before_validation_on_create :post_valid?
26
- after_create :save_post
27
- before_update :update_post
27
+ after_create :capture_first_post
28
28
 
29
29
  attr_accessor :body
30
30
 
31
- named_scope :visible, {}
31
+ default_scope :order => "replied_at DESC, created_at DESC"
32
32
  named_scope :latest, lambda { |count|
33
33
  {
34
34
  :order => 'replied_at DESC',
35
35
  :limit => count
36
36
  }
37
37
  }
38
+
39
+ def replies
40
+ page ? posts : posts.except(first_post)
41
+ end
38
42
 
39
43
  def voice_count
40
44
  posts.count(:select => "DISTINCT reader_id")
@@ -44,6 +48,10 @@ class Topic < ActiveRecord::Base
44
48
  # TODO - move into sql
45
49
  posts.map { |p| p.reader }.uniq
46
50
  end
51
+
52
+ def other_voices
53
+ replies.map { |p| p.reader }.uniq
54
+ end
47
55
 
48
56
  def hit!
49
57
  self.class.increment_counter :hits, id
@@ -75,14 +83,11 @@ class Topic < ActiveRecord::Base
75
83
  end
76
84
 
77
85
  def has_posts?
78
- posts_count > (page ? 0 : 1)
86
+ replies.any?
79
87
  end
80
88
 
81
- def refresh_reply_data(post=nil)
82
- if !post && posts.empty?
83
- self.destroy
84
- elsif has_posts?
85
- post ||= posts.last
89
+ def refresh_reply_data
90
+ if post = posts.last
86
91
  self.last_post = post
87
92
  self.replied_by = post.reader
88
93
  self.replied_at = post.created_at
@@ -113,50 +118,18 @@ protected
113
118
  def set_reader
114
119
  self.reader ||= Reader.current
115
120
  end
121
+
122
+ def echo_inspection
123
+ Rails.logger.warn "+++ creating new topic: #{self.inspect}."
124
+ end
116
125
 
117
126
  def set_defaults
118
127
  self.sticky ||= 0
119
128
  self.locked ||= 0
120
129
  end
121
130
 
122
- def check_for_changing_forums
123
- old = Topic.find(id)
124
- if old.forum_id != forum_id
125
- set_posts_forum_id
126
- Forum.update_all ["posts_count = posts_count - ?", posts_count], ["id = ?", old.forum_id]
127
- Forum.update_all ["posts_count = posts_count + ?", posts_count], ["id = ?", forum_id]
128
- end
129
- end
130
-
131
- def set_posts_forum_id
132
- Post.update_all ['forum_id = ?', forum_id], ['topic_id = ?', id]
131
+ def capture_first_post
132
+ self.first_post.topic = self
133
+ self.first_post.save
133
134
  end
134
-
135
- def post_valid?
136
- post = Post.new(:body => self.body, :reader => self.reader, :topic => self)
137
- unless post.valid?
138
- self.errors.add(:body, post.errors.on(:body))
139
- self.errors.add(:reader, post.errors.on(:reader))
140
- raise ActiveRecord::RecordInvalid.new(self)
141
- end
142
- true
143
- end
144
-
145
- def save_post
146
- self.first_post = self.posts.create!(:body => self.body, :created_at => self.created_at, :reader => self.reader)
147
- self.replied_at ||= Time.now();
148
- self.save(false)
149
- end
150
-
151
- def update_post
152
- post = self.first_post
153
- if !self.body.nil? && self.body != post.body
154
- post.body = self.body
155
- post.save!
156
- end
157
- rescue ActiveRecord::RecordInvalid => ow
158
- self.errors.add(:body, post.errors.on(:body))
159
- raise
160
- end
161
-
162
135
  end
@@ -1,5 +1,6 @@
1
1
  - render_region :main do |main|
2
2
  - main.edit_header do
3
- %h1 Edit Forum
3
+ %h1
4
+ = t('edit_forum').titlecase
4
5
  - main.edit_form do
5
6
  = render :partial => 'form'