radiant-forum-extension 1.2.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. data/README.md +37 -56
  2. data/VERSION +1 -1
  3. data/app/controllers/forum_base_controller.rb +78 -0
  4. data/app/controllers/forums_controller.rb +5 -34
  5. data/app/controllers/posts_controller.rb +61 -153
  6. data/app/controllers/topics_controller.rb +6 -63
  7. data/app/helpers/forum_helper.rb +24 -48
  8. data/app/models/forum.rb +5 -18
  9. data/app/models/post.rb +53 -55
  10. data/app/models/post_attachment.rb +9 -6
  11. data/app/models/topic.rb +20 -113
  12. data/app/views/admin/reader_configuration/_edit_forum.html.haml +4 -2
  13. data/app/views/admin/reader_configuration/_forum.html.haml +6 -2
  14. data/app/views/forums/_forum.html.haml +14 -20
  15. data/app/views/forums/_latest.html.haml +12 -0
  16. data/app/views/forums/_standard_parts.html.haml +49 -0
  17. data/app/views/forums/index.html.haml +16 -24
  18. data/app/views/forums/show.html.haml +18 -28
  19. data/app/views/pages/_comment.html.haml +1 -1
  20. data/app/views/posts/_attachments.html.haml +13 -0
  21. data/app/views/posts/_confirm_delete.html.haml +10 -0
  22. data/app/views/posts/_context.html.haml +16 -0
  23. data/app/views/posts/_edit_links.html.haml +11 -0
  24. data/app/views/posts/_form.html.haml +40 -2
  25. data/app/views/posts/_latest.html.haml +10 -17
  26. data/app/views/posts/_new_attachment.html.haml +2 -0
  27. data/app/views/posts/_post.html.haml +25 -60
  28. data/app/views/posts/{_search.html.haml → _search_form.html.haml} +1 -1
  29. data/app/views/posts/_uploader.html.haml +2 -2
  30. data/app/views/posts/edit.html.haml +26 -13
  31. data/app/views/posts/index.html.haml +19 -27
  32. data/app/views/posts/new.html.haml +27 -7
  33. data/app/views/posts/remove.html.haml +27 -0
  34. data/app/views/posts/show.html.haml +20 -7
  35. data/app/views/readers/_forum_messages.html.haml +20 -0
  36. data/app/views/readers/_messages_summary.html.haml +3 -0
  37. data/app/views/topics/_context.html.haml +12 -0
  38. data/app/views/topics/_latest.html.haml +14 -16
  39. data/app/views/topics/_locked.html.haml +1 -1
  40. data/app/views/topics/_replies.html.haml +6 -0
  41. data/app/views/topics/_reply.html.haml +23 -0
  42. data/app/views/topics/_topic.html.haml +14 -43
  43. data/app/views/topics/_voices.html.haml +5 -0
  44. data/app/views/topics/index.html.haml +11 -24
  45. data/app/views/topics/show.html.haml +25 -38
  46. data/config/initializers/radiant_config.rb +5 -1
  47. data/config/locales/en.yml +73 -27
  48. data/config/routes.rb +3 -4
  49. data/db/migrate/20101222160900_page_posts.rb +21 -0
  50. data/db/migrate/20101222163605_no_comment_forum.rb +10 -0
  51. data/db/migrate/20110105103827_topic_merely_associative.rb +23 -0
  52. data/db/migrate/20110111080550_detach_observer.rb +11 -0
  53. data/db/migrate/20110127113852_import_attachments.rb +9 -0
  54. data/forum_extension.rb +12 -13
  55. data/lib/commentable_model.rb +98 -0
  56. data/lib/forum_page.rb +2 -22
  57. data/lib/forum_reader_sessions_controller.rb +14 -0
  58. data/lib/forum_readers_controller.rb +2 -9
  59. data/lib/forum_red_cloth3.rb +23 -4
  60. data/lib/forum_red_cloth4.rb +23 -4
  61. data/lib/forum_tags.rb +298 -194
  62. data/lib/sanitize/config/forum.rb +47 -0
  63. data/public/images/furniture/blank.png +0 -0
  64. data/public/images/furniture/emoticons.png +0 -0
  65. data/public/javascripts/forum.js +349 -93
  66. data/public/javascripts/jquery.tools.min.js +195 -0
  67. data/public/punymce/blank.htm +1 -0
  68. data/public/punymce/css/content.css +4 -0
  69. data/public/punymce/css/editor.css +58 -0
  70. data/public/punymce/i18n/sv.js +28 -0
  71. data/public/punymce/img/icons.gif +0 -0
  72. data/public/punymce/img/icons_uncompressed.png +0 -0
  73. data/public/punymce/plugins/bbcode.js +1 -0
  74. data/public/punymce/plugins/bbcode_src.js +50 -0
  75. data/public/punymce/plugins/editsource/css/editor.css +3 -0
  76. data/public/punymce/plugins/editsource/editsource.js +1 -0
  77. data/public/punymce/plugins/editsource/editsource_src.js +81 -0
  78. data/public/punymce/plugins/editsource/img/icons.gif +0 -0
  79. data/public/punymce/plugins/emoticons/css/content.css +13 -0
  80. data/public/punymce/plugins/emoticons/css/editor.css +17 -0
  81. data/public/punymce/plugins/emoticons/emoticons.js +1 -0
  82. data/public/punymce/plugins/emoticons/emoticons_src.js +303 -0
  83. data/public/punymce/plugins/emoticons/img/emoticons.gif +0 -0
  84. data/public/punymce/plugins/emoticons/img/emoticons.png +0 -0
  85. data/public/punymce/plugins/emoticons/img/trans.gif +0 -0
  86. data/public/punymce/plugins/entities.js +1 -0
  87. data/public/punymce/plugins/entities_src.js +37 -0
  88. data/public/punymce/plugins/forceblocks.js +1 -0
  89. data/public/punymce/plugins/forceblocks_src.js +465 -0
  90. data/public/punymce/plugins/forcenl.js +1 -0
  91. data/public/punymce/plugins/forcenl_src.js +26 -0
  92. data/public/punymce/plugins/image/css/editor.css +1 -0
  93. data/public/punymce/plugins/image/image.js +1 -0
  94. data/public/punymce/plugins/image/image_src.js +30 -0
  95. data/public/punymce/plugins/image/img/icons.gif +0 -0
  96. data/public/punymce/plugins/link/css/editor.css +2 -0
  97. data/public/punymce/plugins/link/img/icons.gif +0 -0
  98. data/public/punymce/plugins/link/link.js +1 -0
  99. data/public/punymce/plugins/link/link_src.js +36 -0
  100. data/public/punymce/plugins/paste.js +1 -0
  101. data/public/punymce/plugins/paste_src.js +169 -0
  102. data/public/punymce/plugins/protect.js +1 -0
  103. data/public/punymce/plugins/protect_src.js +30 -0
  104. data/public/punymce/plugins/safari2x.js +1 -0
  105. data/public/punymce/plugins/safari2x_src.js +284 -0
  106. data/public/punymce/plugins/tabfocus.js +1 -0
  107. data/public/punymce/plugins/tabfocus_src.js +45 -0
  108. data/public/punymce/plugins/textcolor/css/editor.css +7 -0
  109. data/public/punymce/plugins/textcolor/img/icons.gif +0 -0
  110. data/public/punymce/plugins/textcolor/textcolor.js +1 -0
  111. data/public/punymce/plugins/textcolor/textcolor_src.js +73 -0
  112. data/public/punymce/puny_mce.js +1 -0
  113. data/public/punymce/puny_mce_full.js +1 -0
  114. data/public/punymce/puny_mce_src.js +1460 -0
  115. data/public/stylesheets/sass/forum.sass +175 -169
  116. data/radiant-forum-extension.gemspec +81 -19
  117. data/spec/controllers/admin/forums_controller_spec.rb +2 -2
  118. data/spec/controllers/forums_controller_spec.rb +3 -6
  119. data/spec/controllers/posts_controller_spec.rb +76 -59
  120. data/spec/controllers/topics_controller_spec.rb +4 -95
  121. data/spec/datasets/forum_readers_dataset.rb +1 -0
  122. data/spec/datasets/forums_dataset.rb +91 -10
  123. data/spec/lib/commentable_model_spec.rb +88 -0
  124. data/spec/lib/forum_page_spec.rb +2 -34
  125. data/spec/lib/forum_site_spec.rb +2 -3
  126. data/spec/lib/forum_tags_spec.rb +35 -0
  127. data/spec/models/forum_spec.rb +31 -20
  128. data/spec/models/post_spec.rb +40 -39
  129. data/spec/models/topic_spec.rb +29 -71
  130. data/spec/spec_helper.rb +10 -1
  131. metadata +84 -22
  132. data/app/views/posts/_reply.html.haml +0 -35
  133. data/app/views/posts/_upload.html.haml +0 -2
  134. data/app/views/posts/preview.html.haml +0 -32
  135. data/app/views/posts/search.html.haml +0 -63
  136. data/app/views/posts/search.rss.builder +0 -14
  137. data/app/views/topics/_form.html.haml +0 -30
  138. data/app/views/topics/_help.html.haml +0 -8
  139. data/app/views/topics/comments.html.haml +0 -6
  140. data/app/views/topics/edit.html.haml +0 -26
  141. data/app/views/topics/new.html.haml +0 -56
  142. data/spec/datasets/forum_pages_dataset.rb +0 -11
  143. data/spec/datasets/posts_dataset.rb +0 -31
  144. data/spec/datasets/topics_dataset.rb +0 -37
@@ -1,71 +1,14 @@
1
- class TopicsController < ReaderActionController
2
- include Radiant::Pagination::Controller
3
- helper :forum
1
+ class TopicsController < ForumBaseController
4
2
 
5
- before_filter :private_forum
6
- before_filter :find_forum_and_topic, :except => :index
7
- before_filter :require_activated_reader, :except => [:index, :show]
8
-
9
- radiant_layout { |controller| Radiant::Config['forum.layout'] || Radiant::Config['reader.layout'] }
10
-
11
3
  def index
12
- params[:per_page] ||= 20
13
- @topics = Topic.paginate(:all, pagination_parameters.merge(:order => "topics.sticky desc, topics.replied_at desc", :include => [:forum, :reader]))
4
+ @topics = Topic.bydate.paginate(pagination_parameters)
14
5
  render_page_or_feed
15
6
  end
16
7
 
17
- def new
18
- @topic = Topic.new
19
- @topic.forum = @forum || Forum.find_by_name(Radiant::Config['forum.default_forum'])
20
- end
21
-
22
8
  def show
23
- if @page && request.format == 'text/html'
24
- redirect_to "#{@page.url}#forum"
25
- return false
26
- end
27
- @topic.hit! unless current_reader and @topic.reader == current_reader
28
- store_location((request.format == 'text/html') ? request.request_uri : request.referer)
29
- @first_post = @topic.first_post
30
- @posts = @topic.replies.paginate(pagination_parameters.merge(:include => :reader, :order => 'posts.created_at asc'))
31
- render_page_or_feed(@page ? 'comments' : 'show')
32
- end
33
-
34
- def create
35
- @forum = Forum.find(params[:topic][:forum_id]) if params[:topic][:forum_id]
36
- @topic = @forum.topics.create!(params[:topic])
37
- respond_to do |format|
38
- format.html { redirect_to forum_topic_path(@forum, @topic) }
39
- end
40
- end
41
-
42
- def update
43
- @topic.attributes = params[:topic]
44
- @topic.save!
45
- respond_to do |format|
46
- format.html { redirect_to forum_topic_path(@forum, @topic) }
47
- end
48
- end
49
-
50
- def destroy
51
- @topic.destroy
52
- flash[:notice] = "Topic '{name}' was deleted."[:topic_deleted_message, CGI::escapeHTML(@topic.name)]
53
- respond_to do |format|
54
- format.html { redirect_to forum_path(@forum) }
55
- end
9
+ @topic = Topic.find(params[:id])
10
+ @posts = @topic.replies.paginate(pagination_parameters)
11
+ render_page_or_feed
56
12
  end
57
-
58
- protected
59
-
60
- def private_forum
61
- return false unless Radiant::Config['forum.public?'] || require_reader && require_activated_reader
62
- end
63
-
64
- def find_forum_and_topic
65
- @topic = Topic.find(params[:id]) if params[:id]
66
- @page = @topic.page if @topic
67
- @forum = @topic.forum if @topic
68
- @forum ||= Forum.find(params[:forum_id]) if params[:forum_id]
69
- end
70
-
13
+
71
14
  end
@@ -1,10 +1,7 @@
1
1
  require 'sanitize'
2
- module ForumHelper
2
+ require "sanitize/config/forum"
3
3
 
4
- def home_page_link(options={})
5
- home_page = (defined? Site && Site.current) ? Site.current.home_page : Page.find_by_parent_id(nil)
6
- link_to home_page.title, home_page.url, options
7
- end
4
+ module ForumHelper
8
5
 
9
6
  def feed_tag(text, url, options={})
10
7
  link_to text, url, options.merge(:class => 'floating feedlink')
@@ -20,7 +17,7 @@ module ForumHelper
20
17
  else
21
18
  textilized = RedCloth.new(text, [ :hard_breaks ])
22
19
  textilized.hard_breaks = true if textilized.respond_to?("hard_breaks=")
23
- Sanitize.clean(textilized.to_html(:textile, :smilies), Sanitize::Config::RELAXED)
20
+ Sanitize.clean(textilized.to_html(:textile, :smilies), Sanitize::Config::FORUM)
24
21
  end
25
22
  end
26
23
 
@@ -38,13 +35,20 @@ module ForumHelper
38
35
  end
39
36
  end
40
37
 
41
- def paged_post_url(post)
42
- if post.first?
43
- topic_post_url(post.topic, post, :page => post.topic_page, :anchor => post.dom_id)
38
+ def paginated_post_url(post)
39
+ param_name = WillPaginate::ViewHelpers.pagination_options[:param_name]
40
+ if post.page
41
+ "post.page.url?#{param_name}=#{post.page_when_paginated}##{post.dom_id}"
42
+ elsif post.first?
43
+ topic_post_url(post.topic, post)
44
44
  else
45
- topic_post_url(post.topic, post, :page => post.topic_page, :anchor => post.dom_id)
45
+ topic_post_url(post.topic, post, {param_name => post.page_when_paginated, :anchor => post.dom_id})
46
46
  end
47
47
  end
48
+
49
+ def link_to_post(post, options={})
50
+ link_to post.holder.title, paginated_post_url(post), options
51
+ end
48
52
 
49
53
  def edit_link(post)
50
54
  link_to t('edit'), edit_topic_post_url(post.topic, post), :class => 'edit_post', :id => "edit_post_#{post.id}", :title => t("edit_post")
@@ -55,49 +59,21 @@ module ForumHelper
55
59
  end
56
60
 
57
61
  def friendly_date(datetime)
58
- if datetime
59
- date = datetime.to_date
62
+ I18n.l(datetime, :format => friendly_date_format(datetime)) if datetime
63
+ end
64
+
65
+ def friendly_date_format(datetime)
66
+ if datetime && date = datetime.to_date
60
67
  if (date.to_datetime == Date.today)
61
- format = t('time_today')
68
+ :today
62
69
  elsif (date.to_datetime == Date.yesterday)
63
- format = t('time_yesterday')
70
+ :yesterday
64
71
  elsif (date.to_datetime > 6.days.ago)
65
- format = t('date_recently')
72
+ :recently
66
73
  elsif (date.year == Date.today.year)
67
- format = t('date_this_year')
68
- else
69
- format = t('standard_date')
70
- end
71
- datetime.strftime(format)
72
- else
73
- t("unknown_date")
74
- end
75
- end
76
-
77
- def pagination_and_summary_for(list, name='')
78
- %{<div class="pagination">
79
- #{will_paginate list, :container => false}
80
- <span class="pagination_summary">
81
- #{pagination_summary(list, name)}
82
- </span>
83
- </div>
84
- }
85
- end
86
-
87
- def pagination_summary(list, name='')
88
- total = list.total_entries
89
- if list.empty?
90
- %{#{t('no')} #{name.pluralize}}
91
- else
92
- name ||= t(list.first.class.to_s.underscore.gsub('_', ' '))
93
- if total == 1
94
- %{#{t('showing')} #{t('one')} #{name}}
95
- elsif list.current_page == 1 && total < list.per_page
96
- %{#{t('all')} #{total} #{name.pluralize}}
74
+ :this_year
97
75
  else
98
- start = list.offset + 1
99
- finish = ((list.offset + list.per_page) < list.total_entries) ? list.offset + list.per_page : list.total_entries
100
- %{#{start} #{t('to')} #{finish} #{t('of')} #{total} #{name.pluralize}}
76
+ :standard
101
77
  end
102
78
  end
103
79
  end
data/app/models/forum.rb CHANGED
@@ -1,30 +1,17 @@
1
1
  class Forum < ActiveRecord::Base
2
2
  has_site if respond_to? :has_site
3
- default_scope :order => 'name ASC'
4
- belongs_to :created_by, :class_name => 'User'
5
- belongs_to :updated_by, :class_name => 'User'
6
- validates_presence_of :name
7
- named_scope :visible, {}
3
+ has_many :topics, :dependent => :destroy
8
4
 
9
- has_many :topics, :order => 'topics.sticky desc, topics.replied_at desc', :dependent => :destroy
10
-
11
- def self.find_or_create_comments_forum
12
- @comments_forum = self.find_by_for_comments(true) || self.create(
13
- :name => 'Page Comments',
14
- :description => 'This forum automatically gathers up all comments on pages. You can reply here or on the page.',
15
- :created_by => User.find_by_admin(true),
16
- :position => 999,
17
- :created_at => Time.now,
18
- :for_comments => true
19
- )
20
- end
5
+ default_scope :order => 'position ASC'
6
+ named_scope :imported, :conditions => "old_id IS NOT NULL"
7
+ validates_presence_of :name
21
8
 
22
9
  def dom_id
23
10
  "forum_#{self.id}"
24
11
  end
25
12
 
26
13
  def visible_to?(reader=nil)
27
- true
14
+ return true if reader || Radiant::Config['forum.public?']
28
15
  end
29
16
 
30
17
  end
data/app/models/post.rb CHANGED
@@ -2,62 +2,67 @@ require 'sanitize'
2
2
  class Post < ActiveRecord::Base
3
3
  has_site if respond_to? :has_site
4
4
 
5
- belongs_to :reader, :counter_cache => true
6
- belongs_to :topic, :counter_cache => true
7
- belongs_to :created_by, :class_name => 'User'
8
- belongs_to :updated_by, :class_name => 'User'
5
+ belongs_to :reader
6
+ belongs_to :topic
7
+ belongs_to :page
9
8
  has_many :attachments, :class_name => 'PostAttachment', :order => :position, :dependent => :destroy
10
- accepts_nested_attributes_for :attachments, :allow_destroy => true
11
9
 
12
- before_validation :set_reader
13
- after_create :update_topic_reply_data
14
- after_destroy :revert_topic_reply_data
15
-
10
+ accepts_nested_attributes_for :topic
11
+ accepts_nested_attributes_for :attachments, :allow_destroy => true
16
12
  validates_presence_of :reader, :body
17
- # validates_presence_of :topic
18
13
 
14
+ after_create :notify_holder_of_creation
15
+ after_destroy :notify_holder_of_destruction
16
+
19
17
  default_scope :order => "created_at DESC"
20
- named_scope :visible, {}
21
- named_scope :latest, lambda { |count|
22
- {
23
- :order => 'created_at DESC',
24
- :limit => count
25
- }
26
- }
27
- named_scope :except, lambda { |post|
28
- {
29
- :conditions => ["NOT posts.id = ?", post.id]
18
+
19
+ named_scope :comments, :conditions => "page_id IS NOT NULL"
20
+ named_scope :non_comments, :conditions => "page_id IS NULL"
21
+ named_scope :imported, :conditions => "old_id IS NOT NULL"
22
+ named_scope :in_topic, lambda { |topic| { :conditions => ["topic_id = ?", topic.id] }}
23
+ named_scope :in_topics, lambda { |topics| { :conditions => ["topic_id IN (#{topics.map("?").join(',')})", topics.map(&:id)] }}
24
+ named_scope :in_forum, lambda { |forum| in_topics(forum.topics) }
25
+ named_scope :from, lambda { |reader| { :conditions => ["reader_id = ?", reader.id] }}
26
+ named_scope :latest, lambda { |count| { :order => 'created_at DESC', :limit => count }}
27
+ named_scope :except, lambda { |post| { :conditions => ["NOT posts.id = ?", post.id] }}
28
+ named_scope :distinct_readers, :select => "DISTINCT posts.reader_id" do
29
+ def count
30
+ self.length # replacing a SQL shortcut that omits the distinct clause
31
+ end
32
+ end
33
+ named_scope :containing, lambda { |term|
34
+ {
35
+ :conditions => "posts.body LIKE :term OR topics.name LIKE :term", :term => "%#{term}%",
36
+ :joins => "LEFT OUTER JOIN topics on posts.topic_id = topics.id"
30
37
  }
31
38
  }
32
39
 
33
- def topic_page
34
- self.topic.page_for(self)
40
+ def holder
41
+ page || topic
35
42
  end
36
-
37
- def to_xml(options = {})
38
- options[:except] ||= []
39
- options[:except] << :topic_title << :forum_name
40
- super
43
+
44
+ def comment?
45
+ !!page
41
46
  end
42
47
 
43
- def dom_id
44
- "post_#{self.id}"
48
+ def page_when_paginated
49
+ holder.page_for(self)
45
50
  end
46
51
 
47
- def first?
48
- self.topic.first_post == self
52
+ def forum
53
+ topic.forum unless comment?
49
54
  end
50
55
 
51
- def has_replies?
52
- self.topic.last_post != self
56
+ def first?
57
+ !holder || holder.new_record? || holder.posts.first == self
53
58
  end
54
-
55
- def is_comment?
56
- !self.topic.page.nil?
59
+
60
+ def locked?
61
+ holder && holder.locked?
57
62
  end
58
63
 
59
- def page
60
- return self.topic.page if is_comment?
64
+ def has_replies?
65
+ holder.posts.last != self
61
66
  end
62
67
 
63
68
  def editable_interval
@@ -80,13 +85,12 @@ class Post < ActiveRecord::Base
80
85
  return false unless reader
81
86
  still_editable? && reader && (reader.id == reader_id)
82
87
  end
83
-
88
+
84
89
  def visible_to?(reader=nil)
85
- topic.forum.visible_to?(reader)
90
+ return true if reader || Radiant::Config['forum.public?']
86
91
  end
87
-
88
- # we shouldn't have formatting in here, but page comments need to be rendered from a radius tag
89
92
 
93
+ # so that page comments can be rendered from a radius tag
90
94
  def body_html
91
95
  if body
92
96
  html = RedCloth.new(body, [ :hard_breaks, :filter_html ]).to_html(:textile, :smilies)
@@ -103,23 +107,17 @@ class Post < ActiveRecord::Base
103
107
  def save_attachments(files=nil)
104
108
  files.collect {|file| self.attachments.create(:file => file) unless file.blank? } if files
105
109
  end
106
-
107
- protected
108
110
 
109
- def set_reader
110
- self.reader ||= Reader.current
111
+ def notify_holder_of_destruction
112
+ holder.notice_destruction_of(self)
111
113
  end
112
114
 
113
- def set_forum
114
- self.forum ||= self.topic.forum
115
- end
116
-
117
- def update_topic_reply_data
118
- self.topic.refresh_reply_data if self.topic # topic association not set during initial topic creation because of nested create
115
+ def notify_holder_of_creation
116
+ holder.notice_creation_of(self)
119
117
  end
120
118
 
121
- def revert_topic_reply_data
122
- self.topic.refresh_reply_data if self.topic # topic association not set during initial topic creation because of nested create
119
+ def dom_id
120
+ "post_#{self.id}"
123
121
  end
124
-
122
+
125
123
  end
@@ -1,5 +1,7 @@
1
1
  class PostAttachment < ActiveRecord::Base
2
2
 
3
+ named_scope :imported, :conditions => "old_id IS NOT NULL"
4
+
3
5
  @@image_content_types = ['image/jpeg', 'image/pjpeg', 'image/gif', 'image/png', 'image/x-png', 'image/jpg']
4
6
  cattr_reader :image_content_types
5
7
 
@@ -9,11 +11,12 @@ class PostAttachment < ActiveRecord::Base
9
11
  end
10
12
 
11
13
  def thumbnail_sizes
12
- {
13
- :icon => ['24x24#', :png],
14
- :thumbnail => ['100x100>', :png],
15
- :inline => ['640x640>']
16
- }
14
+ { :icon => ['24x24#', :png], :thumbnail => ['100x100>', :png] }.merge(configured_styles)
15
+ end
16
+
17
+ def configured_styles
18
+ styles = Radiant::Config["assets.additional_thumbnails"].gsub(/\s+/,'').split(',') if Radiant::Config["assets.additional_thumbnails"]
19
+ styles.collect{|s| s.split('=')}.inject({}) {|ha, (k, v)| ha[k.to_sym] = v; ha}
17
20
  end
18
21
 
19
22
  def thumbnail_names
@@ -37,7 +40,7 @@ class PostAttachment < ActiveRecord::Base
37
40
  :path => ":rails_root/public/:class/:id/:basename:no_original_style.:extension"
38
41
 
39
42
  attr_protected :file_file_name, :file_content_type, :file_file_size
40
- validates_attachment_presence :file, :message => t('no_file')
43
+ validates_attachment_presence :file, :message => t('error.no_file')
41
44
  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
45
  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
46
 
data/app/models/topic.rb CHANGED
@@ -1,135 +1,42 @@
1
1
  class Topic < ActiveRecord::Base
2
2
  has_site if respond_to? :has_site
3
-
4
- belongs_to :forum, :counter_cache => true
5
- belongs_to :page
6
- belongs_to :reader
7
- belongs_to :created_by, :class_name => 'User'
8
- belongs_to :updated_by, :class_name => 'User'
9
-
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
3
+ has_comments
4
+
5
+ belongs_to :forum
14
6
  belongs_to :replied_by, :class_name => 'Reader'
15
- has_many :posts, :order => 'posts.created_at ASC', :include => :reader, :dependent => :destroy do
16
- def last
17
- @last_post ||= find(:last)
18
- end
19
- end
20
7
 
21
- validates_presence_of :forum, :reader, :name
8
+ validates_presence_of :name
22
9
  validates_uniqueness_of :old_id, :allow_nil => true
23
10
 
24
- before_validation :set_reader
25
- before_validation :echo_inspection
26
- before_create :set_defaults
27
- after_create :capture_first_post
28
-
29
- attr_accessor :body
30
-
31
- default_scope :order => "replied_at DESC, created_at DESC"
11
+ named_scope :imported, :conditions => "old_id IS NOT NULL"
12
+ named_scope :stickyfirst, :order => "topics.sticky DESC, topics.replied_at DESC"
13
+ named_scope :bydate, :order => 'replied_at DESC'
32
14
  named_scope :latest, lambda { |count|
33
- {
34
- :order => 'replied_at DESC',
35
- :limit => count
36
- }
15
+ { :order => 'replied_at DESC', :limit => count }
37
16
  }
38
-
39
- def replies
40
- page ? posts : posts.except(first_post)
41
- end
42
17
 
43
- def voice_count
44
- posts.count(:select => "DISTINCT reader_id")
45
- end
46
-
47
- def voices
48
- # TODO - move into sql
49
- posts.map { |p| p.reader }.uniq
50
- end
51
-
52
- def other_voices
53
- replies.map { |p| p.reader }.uniq
54
- end
55
-
56
- def hit!
57
- self.class.increment_counter :hits, id
58
- end
59
-
60
- def sticky?() sticky == 1 end
61
-
62
- def views() hits end
63
-
64
- def paged?() posts_count > posts_per_page end
65
-
66
- def posts_per_page
67
- ppp = Radiant::Config['forum.posts_per_page'] || 25
68
- ppp.to_i.to_f
69
- end
70
-
71
- def last_page
72
- (posts_count.to_f/posts_per_page).ceil.to_i
73
- end
74
-
75
- def page_for(post)
76
- return nil unless post.topic == self
77
- return 1 unless paged?
78
- (posts.index(post)/posts_per_page).ceil.to_i
18
+ def dom_id
19
+ "topic_#{self.id}"
79
20
  end
80
21
 
81
- def editable_by?(user)
82
- reader && (reader.id == reader_id)
22
+ def visible_to?(reader=nil)
23
+ return true if reader || Radiant::Config['forum.public?']
83
24
  end
84
25
 
85
- def has_posts?
86
- replies.any?
26
+ def reader
27
+ posts.first.reader
87
28
  end
88
29
 
89
- def refresh_reply_data
90
- if post = posts.last
91
- self.last_post = post
92
- self.replied_by = post.reader
93
- self.replied_at = post.created_at
94
- self.save!
95
- end
30
+ def body
31
+ posts.first.body
96
32
  end
97
33
 
98
- def last_post_with_fetch
99
- if lp = last_post_without_fetch
100
- lp
101
- elsif has_posts? && lp = posts.last
102
- update_attribute(:last_post_id, lp.id)
103
- lp
104
- end
105
- end
106
- alias_method_chain :last_post, :fetch
107
-
108
- def dom_id
109
- "topic_#{self.id}"
34
+ def created_at
35
+ posts.first.created_at if posts.first
110
36
  end
111
37
 
112
- def visible_to?(reader=nil)
113
- forum.visible_to?(reader)
38
+ def title
39
+ name
114
40
  end
115
-
116
- protected
117
41
 
118
- def set_reader
119
- self.reader ||= Reader.current
120
- end
121
-
122
- def echo_inspection
123
- Rails.logger.warn "+++ creating new topic: #{self.inspect}."
124
- end
125
-
126
- def set_defaults
127
- self.sticky ||= 0
128
- self.locked ||= 0
129
- end
130
-
131
- def capture_first_post
132
- self.first_post.topic = self
133
- self.first_post.save
134
- end
135
42
  end