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