content_viewer_controller.rb
7.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
class ContentViewerController < ApplicationController
  needs_profile
  before_filter :comment_author, :only => :edit_comment
  helper ProfileHelper
  helper TagsHelper
  def view_page
    path = params[:page].join('/')
    if path.blank?
      @page = profile.home_page
      if @page.nil?
        redirect_to :controller => 'profile', :action => 'index', :profile => profile.identifier
        return
      end
    else
      @page = profile.articles.find_by_path(path)
      unless @page
        page_from_old_path = profile.articles.find_by_old_path(path)
        if page_from_old_path
          redirect_to profile.url.merge(:page => page_from_old_path.explode_path)
          return
        end
      end
      # page not found, give error
      if @page.nil?
        render_not_found(@path)
        return
      end
    end
    if !@page.display_to?(user)
      if profile.display_info_to?(user) || !profile.visible?
        message = _('You are not allowed to view this content. You can contact the owner of this profile to request access then.')
        render_access_denied(message)
      elsif !profile.public?
        redirect_to :controller => 'profile', :action => 'index', :profile => profile.identifier
      end
      return
    end
    if request.xhr? && params[:toolbar]
      render :partial => 'article_toolbar'
      return
    end
    redirect_to_translation if @page.profile.redirect_l10n
    # At this point the page will be showed
    @page.hit
    unless @page.mime_type == 'text/html' || (@page.image? && params[:view])
      headers['Content-Type'] = @page.mime_type
      data = @page.data
      # TODO test the condition
      if data.nil?
        raise "No data for file"
      end
      render :text => data, :layout => false
      return
    end
    @form_div = params[:form]
    if params[:comment] && params[:confirm] == 'true'
      @comment = Comment.new(params[:comment])
      if request.post? && @page.accept_comments?
        add_comment
      end
    else
      @comment = Comment.new
    end
    if request.post?
      if params[:remove_comment]
        remove_comment
        return
      elsif params[:mark_comment_as_spam]
        mark_comment_as_spam
        return
      end
    end
    
    if @page.has_posts?
      posts = if params[:year] and params[:month]
        filter_date = DateTime.parse("#{params[:year]}-#{params[:month]}-01")
        @page.posts.by_range(filter_date..filter_date.at_end_of_month)
      else
        @page.posts
      end
      if @page.blog? && @page.display_posts_in_current_language?
        posts = posts.native_translations.all(Article.display_filter(user, profile)).map{ |p| p.get_translation_to(FastGettext.locale) }.compact
      end
      @posts = posts.paginate({ :page => params[:npage], :per_page => @page.posts_per_page }.merge(Article.display_filter(user, profile)))
    end
    if @page.folder? && @page.gallery?
      @images = @page.images
      @images = @images.paginate(:per_page => per_page, :page => params[:npage]) unless params[:slideshow]
    end
    @unfollow_form = params[:unfollow] && params[:unfollow] == 'true'
    if params[:unfollow] && params[:unfollow] == 'commit' && request.post?
      @page.followers -= [params[:email]]
      if @page.save
        session[:notice] = _("Notification of new comments to '%s' was successfully canceled") % params[:email]
      end
    end
    comments = @page.comments.without_spam
    @comments = comments.as_thread
    @comments_count = comments.count
    if params[:slideshow]
      render :action => 'slideshow', :layout => 'slideshow'
    end
  end
  def edit_comment
    path = params[:page].join('/')
    @page = profile.articles.find_by_path(path)
    @form_div = 'opened'
    @comment = @page.comments.find_by_id(params[:id])
    if @comment
      if request.post?
        begin
          @comment.update_attributes(params[:comment])
          session[:notice] = _('Comment succesfully updated')
          redirect_to :action => 'view_page', :profile => profile.identifier, :page => @comment.article.explode_path
        rescue
          session[:notice] = _('Comment could not be updated')
        end
      end
    else
      redirect_to @page.view_url
      session[:notice] = _('Could not find the comment in the article')
    end
  end
  protected
  def add_comment
    @comment.author = user if logged_in?
    @comment.article = @page
    @comment.ip_address = request.remote_ip
    @comment.user_agent = request.user_agent
    @comment.referrer = request.referrer
    plugins_filter_comment(@comment)
    return if @comment.rejected?
    if (pass_without_comment_captcha? || verify_recaptcha(:model => @comment, :message => _('Please type the words correctly'))) && @comment.save
      @page.touch
      @comment = nil # clear the comment form
      redirect_to :action => 'view_page', :profile => params[:profile], :page => @page.explode_path, :view => params[:view]
    else
      @form_div = 'opened' if params[:comment][:reply_of_id].blank?
    end
  end
  def plugins_filter_comment(comment)
    @plugins.each do |plugin|
      plugin.filter_comment(comment)
    end
  end
  def pass_without_comment_captcha?
    logged_in? && !environment.enabled?('captcha_for_logged_users')
  end
  helper_method :pass_without_comment_captcha?
  def remove_comment
    @comment = @page.comments.find(params[:remove_comment])
    if (user == @comment.author || user == @page.profile || user.has_permission?(:moderate_comments, @page.profile))
      @comment.destroy
    end
    finish_comment_handling
  end
  def mark_comment_as_spam
    @comment = @page.comments.find(params[:mark_comment_as_spam])
    if logged_in? && (user == @page.profile || user.has_permission?(:moderate_comments, @page.profile))
      @comment.spam!
    end
    finish_comment_handling
  end
  def finish_comment_handling
    if request.xhr?
      render :text => {'ok' => true}.to_json, :content_type => 'application/json'
    else
      redirect_to :action => 'view_page', :profile => params[:profile], :page => @page.explode_path, :view => params[:view]
    end
  end
  def per_page
    12
  end
  def redirect_to_translation
    locale = FastGettext.locale
    if !@page.language.nil? && @page.language != locale
      translations = [@page.native_translation] + @page.native_translation.translations
      urls = translations.map{ |t| URI.parse(url_for(t.url)).path }
      urls << URI.parse(url_for(profile.admin_url.merge({ :controller => 'cms', :action => 'edit', :id => @page.id }))).path
      urls << URI.parse(url_for(profile.admin_url.merge(:controller => 'cms', :action => 'new'))).path
      referer = URI.parse(url_for(request.referer)).path unless request.referer.blank?
      unless urls.include?(referer)
        translations.each do |translation|
          if translation.language == locale
            @page = translation
            redirect_to :profile => @page.profile.identifier, :page => @page.explode_path
          end
        end
      end
    end
  end
  def comment_author
    comment = Comment.find_by_id(params[:id])
    if comment
      render_access_denied if comment.author.blank? || comment.author != user
    else
      render_not_found
    end
  end
end