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