update last target after editing comments
[shapado:cantonics-shapado.git] / app / controllers / answers_controller.rb
1 class AnswersController < ApplicationController
2   before_filter :login_required, :except => [:show, :create]
3   before_filter :check_permissions, :only => [:destroy]
4   before_filter :check_update_permissions, :only => [:edit, :update, :rollback]
5
6   helper :votes
7
8   def history
9     @answer = Answer.find(params[:id])
10     @question = @answer.question
11
12     respond_to do |format|
13       format.html
14       format.json { render :json => @answer.versions.to_json }
15     end
16   end
17
18   def diff
19     @answer = Answer.find(params[:id])
20     @question = @answer.question
21     @prev = params[:prev]
22     @curr = params[:curr]
23     if @prev.blank? || @curr.blank? || @prev == @curr
24       flash[:error] = "please, select two versions"
25       render :history
26     else
27       if @prev
28         @prev = (@prev == "current" ? :current : @prev.to_i)
29       end
30
31       if @curr
32         @curr = (@curr == "current" ? :current : @curr.to_i)
33       end
34     end
35   end
36
37   def rollback
38     @question = @answer.question
39     @question.updated_by = current_user
40
41     if @answer.rollback!(params[:version].to_i)
42       flash[:notice] = t(:flash_notice, :scope => "answers.update")
43       Magent.push("actors.judge", :on_rollback, @answer.id)
44     end
45
46     respond_to do |format|
47       format.html { redirect_to history_question_answer_path(@question, @answer) }
48     end
49   end
50
51   def show
52     @answer = Answer.find(params[:id])
53     @question = @answer.question
54     respond_to do |format|
55       format.html
56       format.json  { render :json => @answer.to_json }
57     end
58   end
59
60   def create
61     @answer = Answer.new
62     @answer.safe_update(%w[body wiki], params[:answer])
63     @question = Question.find_by_slug_or_id(params[:question_id])
64     @answer.question = @question
65     @answer.group_id = @question.group_id
66
67     # workaround, seems like mm default values are broken
68     @answer.votes_count = 0
69     @answer.votes_average = 0
70     @answer.flags_count = 0
71
72     if !logged_in?
73       draft = Draft.create(:answer => @answer)
74       session[:draft] = draft.id
75       login_required
76     else # TODO: put a return statement and remove this else block
77       @answer.user = current_user
78       respond_to do |format|
79         if @question && @answer.save
80           Question.update_last_target(@question.id, @answer)
81
82           current_user.stats.add_answer_tags(*@question.tags)
83
84           @question.answer_added!
85
86           current_group.on_activity(:answer_question)
87           current_user.on_activity(:answer_question, current_group)
88
89           # TODO: use magent to do it
90           search_opts = {"notification_opts.#{current_group.id}.new_answer" => {:$in => ["1", true]},
91                           :_id => {:$ne => current_user.id},
92                           :select => ["email"]}
93
94           users = User.find(@question.watchers, search_opts)
95           users.push(@question.user) if @question.user != current_user
96           followers = []
97
98           if current_group.private || current_group.isolate
99             followers = @answer.user.followers(:group_id => current_group.id, :languages => [@question.language])
100           else
101             followers = @answer.user.followers(:languages => [@question.language])
102           end
103
104           (users - followers).each do |u|
105             if !u.email.blank? && u.notification_opts.new_answer
106               Notifier.deliver_new_answer(u, current_group, @answer, false)
107             end
108           end
109
110           followers.each do |u|
111             if !u.email.blank? && u.notification_opts.new_answer
112               Notifier.deliver_new_answer(u, current_group, @answer, true)
113             end
114           end
115
116           flash[:notice] = t(:flash_notice, :scope => "answers.create")
117           format.html{redirect_to question_path(@question)}
118           format.json { render :json => @answer.to_json(:except => %w[_keywords]) }
119           format.js do
120             render(:json => {:success => true, :message => flash[:notice],
121               :html => render_to_string(:partial => "questions/answer",
122                                         :object => @answer,
123                                         :locals => {:question => @question})}.to_json)
124           end
125         else
126           flash[:error] = t(:flash_error, :scope => "answers.create")
127           format.html{redirect_to question_path(@question)}
128           format.json { render :json => @answer.errors, :status => :unprocessable_entity }
129           format.js {render :json => {:success => false, :message => flash[:error] }.to_json }
130         end
131       end
132     end
133   end
134
135   def edit
136     @question = @answer.question
137   end
138
139   def update
140     respond_to do |format|
141       @question = @answer.question
142       @answer.safe_update(%w[body], params[:answer])
143       @answer.updated_by = current_user
144
145       if @answer.valid? && @answer.save
146         Question.update_last_target(@question.id, @answer)
147
148         flash[:notice] = t(:flash_notice, :scope => "answers.update")
149
150         Magent.push("actors.judge", :on_update_answer, @answer.id)
151         format.html { redirect_to(question_path(@answer.question)) }
152         format.json { head :ok }
153       else
154         format.html { render :action => "edit" }
155         format.json { render :json => @answer.errors, :status => :unprocessable_entity }
156       end
157     end
158   end
159
160   def destroy
161     @question = @answer.question
162     @answer.user.update_reputation(:delete_answer, current_group)
163     @answer.destroy
164     @question.answer_removed!
165
166     Magent.push("actors.judge", :on_destroy_answer, current_user.id, @answer.attributes)
167
168     respond_to do |format|
169       format.html { redirect_to(question_path(@question)) }
170       format.json  { head :ok }
171     end
172   end
173
174   def flag
175     @answer = Answer.find(params[:id])
176     @flag = Flag.new
177     @flag.flaggeable_type = @answer.class.name
178     @flag.flaggeable_id = @answer.id
179     respond_to do |format|
180       format.html
181       format.json
182     end
183   end
184
185   protected
186   def check_permissions
187     @answer = Answer.find(params[:id])
188     if @answer.nil? || !current_user.can_modify?(@answer)
189       flash[:error] = t("global.permission_denied")
190       redirect_to questions_path
191     end
192   end
193
194   def check_update_permissions
195     @answer = Answer.find(params[:id])
196
197     if @answer.nil?
198       redirect_to questions_path
199     elsif !((current_user.can_edit_others_posts_on?(@answer.group)) ||
200           current_user.can_modify?(@answer) || @answer.wiki)
201       reputation = @answer.group.reputation_constrains["edit_others_posts"]
202       flash[:error] = I18n.t("users.messages.errors.reputation_needed",
203                                     :min_reputation => reputation,
204                                     :action => I18n.t("users.actions.edit_others_posts"))
205       redirect_to questions_path
206     end
207   end
208 end