]> git.openstreetmap.org Git - rails.git/blob - app/controllers/diary_entries_controller.rb
Merge remote-tracking branch 'upstream/pull/4241'
[rails.git] / app / controllers / diary_entries_controller.rb
1 class DiaryEntriesController < ApplicationController
2   include UserMethods
3
4   layout "site", :except => :rss
5
6   before_action :authorize_web
7   before_action :set_locale
8   before_action :check_database_readable
9
10   authorize_resource
11
12   before_action :lookup_user, :only => [:show, :comments]
13   before_action :check_database_writable, :only => [:new, :create, :edit, :update, :comment, :hide, :hidecomment, :subscribe, :unsubscribe]
14   before_action :allow_thirdparty_images, :only => [:new, :create, :edit, :update, :index, :show, :comments]
15
16   def index
17     if params[:display_name]
18       @user = User.active.find_by(:display_name => params[:display_name])
19
20       if @user
21         @title = t ".user_title", :user => @user.display_name
22         entries = @user.diary_entries
23       else
24         render_unknown_user params[:display_name]
25         return
26       end
27     elsif params[:friends]
28       if current_user
29         @title = t ".title_friends"
30         entries = DiaryEntry.where(:user => current_user.friends)
31       else
32         require_user
33         return
34       end
35     elsif params[:nearby]
36       if current_user
37         @title = t ".title_nearby"
38         entries = DiaryEntry.where(:user => current_user.nearby)
39       else
40         require_user
41         return
42       end
43     else
44       entries = DiaryEntry.joins(:user).where(:users => { :status => %w[active confirmed] })
45
46       if params[:language]
47         @title = t ".in_language_title", :language => Language.find(params[:language]).english_name
48         entries = entries.where(:language_code => params[:language])
49       else
50         @title = t ".title"
51       end
52     end
53
54     entries = entries.visible unless can? :unhide, DiaryEntry
55
56     @params = params.permit(:display_name, :friends, :nearby, :language)
57
58     @entries = if params[:before]
59                  entries.where("diary_entries.id < ?", params[:before]).order(:id => :desc)
60                elsif params[:after]
61                  entries.where("diary_entries.id > ?", params[:after]).order(:id => :asc)
62                else
63                  entries.order(:id => :desc)
64                end
65
66     @entries = @entries.limit(20)
67     @entries = @entries.includes(:user, :language)
68     @entries = @entries.sort.reverse
69
70     @newer_entries = @entries.count.positive? && entries.exists?(["diary_entries.id > ?", @entries.first.id])
71     @older_entries = @entries.count.positive? && entries.exists?(["diary_entries.id < ?", @entries.last.id])
72   end
73
74   def show
75     entries = @user.diary_entries
76     entries = entries.visible unless can? :unhide, DiaryEntry
77     @entry = entries.where(:id => params[:id]).first
78     if @entry
79       @title = t ".title", :user => params[:display_name], :title => @entry.title
80       @comments = can?(:unhidecomment, DiaryEntry) ? @entry.comments : @entry.visible_comments
81     else
82       @title = t "diary_entries.no_such_entry.title", :id => params[:id]
83       render :action => "no_such_entry", :status => :not_found
84     end
85   end
86
87   def new
88     @title = t ".title"
89
90     default_lang = current_user.preferences.where(:k => "diary.default_language").first
91     lang_code = default_lang ? default_lang.v : current_user.preferred_language
92     @diary_entry = DiaryEntry.new(entry_params.merge(:language_code => lang_code))
93     set_map_location
94     render :action => "new"
95   end
96
97   def edit
98     @title = t ".title"
99     @diary_entry = DiaryEntry.find(params[:id])
100
101     redirect_to diary_entry_path(@diary_entry.user, @diary_entry) if current_user != @diary_entry.user
102
103     set_map_location
104   rescue ActiveRecord::RecordNotFound
105     render :action => "no_such_entry", :status => :not_found
106   end
107
108   def create
109     @title = t "diary_entries.new.title"
110
111     @diary_entry = DiaryEntry.new(entry_params)
112     @diary_entry.user = current_user
113
114     if @diary_entry.save
115       default_lang = current_user.preferences.where(:k => "diary.default_language").first
116       if default_lang
117         default_lang.v = @diary_entry.language_code
118         default_lang.save!
119       else
120         current_user.preferences.create(:k => "diary.default_language", :v => @diary_entry.language_code)
121       end
122
123       # Subscribe user to diary comments
124       @diary_entry.subscriptions.create(:user => current_user)
125
126       redirect_to :action => "index", :display_name => current_user.display_name
127     else
128       render :action => "new"
129     end
130   end
131
132   def update
133     @title = t "diary_entries.edit.title"
134     @diary_entry = DiaryEntry.find(params[:id])
135
136     if current_user != @diary_entry.user ||
137        (params[:diary_entry] && @diary_entry.update(entry_params))
138       redirect_to diary_entry_path(@diary_entry.user, @diary_entry)
139     else
140       set_map_location
141       render :action => "edit"
142     end
143   rescue ActiveRecord::RecordNotFound
144     render :action => "no_such_entry", :status => :not_found
145   end
146
147   def comment
148     @entry = DiaryEntry.find(params[:id])
149     @comments = @entry.visible_comments
150     @diary_comment = @entry.comments.build(comment_params)
151     @diary_comment.user = current_user
152     if @diary_comment.save
153
154       # Notify current subscribers of the new comment
155       @entry.subscribers.visible.each do |user|
156         UserMailer.diary_comment_notification(@diary_comment, user).deliver_later if current_user != user
157       end
158
159       # Add the commenter to the subscribers if necessary
160       @entry.subscriptions.create(:user => current_user) unless @entry.subscribers.exists?(current_user.id)
161
162       redirect_to diary_entry_path(@entry.user, @entry)
163     else
164       render :action => "show"
165     end
166   rescue ActiveRecord::RecordNotFound
167     render :action => "no_such_entry", :status => :not_found
168   end
169
170   def subscribe
171     diary_entry = DiaryEntry.find(params[:id])
172
173     diary_entry.subscriptions.create(:user => current_user) unless diary_entry.subscribers.exists?(current_user.id)
174
175     redirect_to diary_entry_path(diary_entry.user, diary_entry)
176   rescue ActiveRecord::RecordNotFound
177     render :action => "no_such_entry", :status => :not_found
178   end
179
180   def unsubscribe
181     diary_entry = DiaryEntry.find(params[:id])
182
183     diary_entry.subscriptions.where(:user => current_user).delete_all if diary_entry.subscribers.exists?(current_user.id)
184
185     redirect_to diary_entry_path(diary_entry.user, diary_entry)
186   rescue ActiveRecord::RecordNotFound
187     render :action => "no_such_entry", :status => :not_found
188   end
189
190   def rss
191     if params[:display_name]
192       user = User.active.find_by(:display_name => params[:display_name])
193
194       if user
195         @entries = user.diary_entries
196         @title = t("diary_entries.feed.user.title", :user => user.display_name)
197         @description = t("diary_entries.feed.user.description", :user => user.display_name)
198         @link = url_for :action => "index", :display_name => user.display_name, :host => Settings.server_url, :protocol => Settings.server_protocol
199       else
200         head :not_found
201         return
202       end
203     else
204       @entries = DiaryEntry.joins(:user).where(:users => { :status => %w[active confirmed] })
205
206       # Items can't be flagged as deleted in the RSS format.
207       # For the general feeds, allow a delay before publishing, to help spam fighting
208       @entries = @entries.where("created_at < :time", :time => Settings.diary_feed_delay.hours.ago)
209
210       if params[:language]
211         @entries = @entries.where(:language_code => params[:language])
212         @title = t("diary_entries.feed.language.title", :language_name => Language.find(params[:language]).english_name)
213         @description = t("diary_entries.feed.language.description", :language_name => Language.find(params[:language]).english_name)
214         @link = url_for :action => "index", :language => params[:language], :host => Settings.server_url, :protocol => Settings.server_protocol
215       else
216         @title = t("diary_entries.feed.all.title")
217         @description = t("diary_entries.feed.all.description")
218         @link = url_for :action => "index", :host => Settings.server_url, :protocol => Settings.server_protocol
219       end
220     end
221     @entries = @entries.visible.includes(:user).order("created_at DESC").limit(20)
222   end
223
224   def hide
225     entry = DiaryEntry.find(params[:id])
226     entry.update(:visible => false)
227     redirect_to :action => "index", :display_name => entry.user.display_name
228   end
229
230   def unhide
231     entry = DiaryEntry.find(params[:id])
232     entry.update(:visible => true)
233     redirect_to :action => "index", :display_name => entry.user.display_name
234   end
235
236   def hidecomment
237     comment = DiaryComment.find(params[:comment])
238     comment.update(:visible => false)
239     redirect_to diary_entry_path(comment.diary_entry.user, comment.diary_entry)
240   end
241
242   def unhidecomment
243     comment = DiaryComment.find(params[:comment])
244     comment.update(:visible => true)
245     redirect_to diary_entry_path(comment.diary_entry.user, comment.diary_entry)
246   end
247
248   def comments
249     @title = t ".title", :user => @user.display_name
250
251     conditions = { :user_id => @user }
252
253     conditions[:visible] = true unless can? :unhidecomment, DiaryEntry
254
255     @comment_pages, @comments = paginate(:diary_comments,
256                                          :conditions => conditions,
257                                          :order => "created_at DESC",
258                                          :per_page => 20)
259     @page = (params[:page] || 1).to_i
260   end
261
262   private
263
264   ##
265   # return permitted diary entry parameters
266   def entry_params
267     params.require(:diary_entry).permit(:title, :body, :language_code, :latitude, :longitude)
268   rescue ActionController::ParameterMissing
269     ActionController::Parameters.new.permit(:title, :body, :language_code, :latitude, :longitude)
270   end
271
272   ##
273   # return permitted diary comment parameters
274   def comment_params
275     params.require(:diary_comment).permit(:body)
276   end
277
278   ##
279   # decide on a location for the diary entry map
280   def set_map_location
281     if @diary_entry.latitude && @diary_entry.longitude
282       @lon = @diary_entry.longitude
283       @lat = @diary_entry.latitude
284       @zoom = 12
285     elsif !current_user.home_location?
286       @lon = params[:lon] || -0.1
287       @lat = params[:lat] || 51.5
288       @zoom = params[:zoom] || 4
289     else
290       @lon = current_user.home_lon
291       @lat = current_user.home_lat
292       @zoom = 12
293     end
294   end
295 end