diff --git a/Changelog.md b/Changelog.md index 309f614e0..b8a4cfad7 100644 --- a/Changelog.md +++ b/Changelog.md @@ -68,6 +68,7 @@ With the port to Bootstrap 3, app/views/terms/default.haml has a new structure. * Extract PostService from PostsController [#6208](https://github.com/diaspora/diaspora/pull/6208) * Drop outdated/unused mbp-respond.min.js and mbp-modernizr-custom.js [#6257](https://github.com/diaspora/diaspora/pull/6257) * Refactor ApplicationController#after\_sign\_out\_path\_for [#6258](https://github.com/diaspora/diaspora/pull/6258) +* Extract StatusMessageService from StatusMessagesController [#6280](https://github.com/diaspora/diaspora/pull/6280) ## Bug fixes * Fix indentation and a link title on the default home page [#6212](https://github.com/diaspora/diaspora/pull/6212) diff --git a/app/controllers/status_messages_controller.rb b/app/controllers/status_messages_controller.rb index e65b0a7c7..2109d3b71 100644 --- a/app/controllers/status_messages_controller.rb +++ b/app/controllers/status_messages_controller.rb @@ -1,36 +1,33 @@ # Copyright (c) 2010-2011, Diaspora Inc. This file is # licensed under the Affero General Public License version 3 or later. See # the COPYRIGHT file. - class StatusMessagesController < ApplicationController before_action :authenticate_user! - before_action :remove_getting_started, :only => [:create] + before_action :remove_getting_started, only: :create - respond_to :html, - :mobile, - :json + respond_to :html, :mobile, :json - layout 'application', only: :bookmarklet + layout "application", only: :bookmarklet # Called when a user clicks "Mention" on a profile page # @param person_id [Integer] The id of the person to be mentioned def new - if params[:person_id] && @person = Person.where(:id => params[:person_id]).first + if params[:person_id] && fetch_person(params[:person_id]) @aspect = :profile @contact = current_user.contact_for(@person) - @aspects_with_person = [] if @contact - @aspects_with_person = @contact.aspects - @aspect_ids = @aspects_with_person.map{|x| x.id} + @aspects_with_person = @contact.aspects.load + @aspect_ids = @aspects_with_person.map(&:id) gon.aspect_ids = @aspect_ids - @contacts_of_contact = @contact.contacts - render :layout => nil + render layout: nil + else + @aspects_with_person = [] end - elsif(request.format == :mobile) + elsif request.format == :mobile @aspect = :all - @aspects = current_user.aspects - @aspect_ids = @aspects.map{ |a| a.id } + @aspects = current_user.aspects.load + @aspect_ids = @aspects.map(&:id) gon.aspect_ids = @aspect_ids else redirect_to stream_path @@ -39,90 +36,61 @@ class StatusMessagesController < ApplicationController def bookmarklet @aspects = current_user.aspects - @aspect_ids = @aspects.map{|x| x.id} + @aspect_ids = current_user.aspect_ids gon.preloads[:bookmarklet] = { content: params[:content], - title: params[:title], - url: params[:url], - notes: params[:notes] + title: params[:title], + url: params[:url], + notes: params[:notes] } end def create - params[:status_message][:aspect_ids] = [*params[:aspect_ids]] - normalize_public_flag! - services = [*params[:services]].compact - - @status_message = current_user.build_post(:status_message, params[:status_message]) - @status_message.build_location(:address => params[:location_address], :coordinates => params[:location_coords]) if params[:location_address].present? - if params[:poll_question].present? - @status_message.build_poll(:question => params[:poll_question]) - [*params[:poll_answers]].each do |poll_answer| - @status_message.poll.poll_answers.build(:answer => poll_answer) - end - end - - - @status_message.attach_photos_by_ids(params[:photos]) - - if @status_message.save - aspects = current_user.aspects_from_ids(destination_aspect_ids) - current_user.add_to_streams(@status_message, aspects) - receiving_services = Service.titles(services) - - current_user.dispatch_post(@status_message, :url => short_post_url(@status_message.guid), :service_types => receiving_services) - - current_user.participate!(@status_message) - - if coming_from_profile_page? && !own_profile_page? # if this is a post coming from a profile page - flash[:notice] = successful_mention_message - end - - respond_to do |format| - format.html { redirect_to :back } - format.mobile { redirect_to stream_path } - format.json { render :json => PostPresenter.new(@status_message, current_user), :status => 201 } - end - else - respond_to do |format| - format.html { redirect_to :back } - format.mobile { redirect_to stream_path } - #there are some errors, so we report the first one to the user - format.json { render :text => @status_message.errors.messages.values.first.to_sentence, :status => 403 } - end + @status_message = StatusMessageCreationService.new(params, current_user).status_message + handle_mention_feedback + respond_to do |format| + format.html { redirect_to :back } + format.mobile { redirect_to stream_path } + format.json { render json: PostPresenter.new(@status_message, current_user), status: 201 } end + rescue StandardError => error + handle_create_error(error) end private - def destination_aspect_ids - if params[:status_message][:public] || params[:status_message][:aspect_ids].first == "all_aspects" - current_user.aspect_ids - else - params[:aspect_ids] + def fetch_person(person_id) + @person = Person.where(id: person_id).first + end + + def handle_create_error(error) + respond_to do |format| + format.html { redirect_to :back } + format.mobile { redirect_to stream_path } + format.json { render text: error.message, status: 403 } end end - def successful_mention_message - t('status_messages.create.success', :names => @status_message.mentioned_people_names) + def handle_mention_feedback + return unless comes_from_others_profile_page? + flash[:notice] = successful_mention_message + end + + def comes_from_others_profile_page? + coming_from_profile_page? && !own_profile_page? end def coming_from_profile_page? - request.env['HTTP_REFERER'].include?("people") + request.env["HTTP_REFERER"].include?("people") end def own_profile_page? - request.env['HTTP_REFERER'].include?("/people/" + params[:status_message][:author][:guid].to_s) + request.env["HTTP_REFERER"].include?("/people/" + params[:status_message][:author][:guid].to_s) end - def normalize_public_flag! - # mobile || desktop conditions - sm = params[:status_message] - public_flag = (sm[:aspect_ids] && sm[:aspect_ids].first == 'public') || sm[:public] - public_flag.to_s.match(/(true)|(on)/) ? public_flag = true : public_flag = false - params[:status_message][:public] = public_flag - public_flag + def successful_mention_message + t("status_messages.create.success", names: @status_message.mentioned_people_names) end def remove_getting_started diff --git a/app/services/status_message_creation_service.rb b/app/services/status_message_creation_service.rb new file mode 100644 index 000000000..3f0093bca --- /dev/null +++ b/app/services/status_message_creation_service.rb @@ -0,0 +1,89 @@ +class StatusMessageCreationService + include Rails.application.routes.url_helpers + + attr_reader :status_message + + def initialize(params, user) + normalize_params(params, user) + status_message_initial = user.build_post(:status_message, params[:status_message]) + @status_message = add_attachments(params, status_message_initial) + @status_message.save + process_status_message(user) + end + + private + + attr_reader :services, :destination_aspect_ids + + def normalize_params(params, user) + normalize_aspect_ids(params) + normalize_public_flag!(params) + @services = [*params[:services]].compact + @destination_aspect_ids = destination_aspect_ids(params, user) + end + + def normalize_aspect_ids(params) + params[:status_message][:aspect_ids] = [*params[:aspect_ids]] + end + + def normalize_public_flag!(params) + sm = params[:status_message] + public_flag_string = (sm[:aspect_ids] && sm[:aspect_ids].first == "public") || sm[:public] + public_flag = public_flag_string.to_s.match(/(true)|(on)/) ? true : false + params[:status_message][:public] = public_flag + end + + def destination_aspect_ids(params, user) + if params[:status_message][:public] || params[:status_message][:aspect_ids].first == "all_aspects" + user.aspect_ids + else + params[:aspect_ids] + end + end + + def add_attachments(params, status_message_initial) + status_message_with_location = add_location(params, status_message_initial) + status_message_with_poll = add_poll(params, status_message_with_location) + add_photos(params, status_message_with_poll) + end + + def add_location(params, status_message) + address = params[:location_address] + coordinates = params[:location_coords] + status_message.build_location(address: address, coordinates: coordinates) if address.present? + status_message + end + + def add_poll(params, status_message) + if params[:poll_question].present? + status_message.build_poll(question: params[:poll_question]) + [*params[:poll_answers]].each do |poll_answer| + status_message.poll.poll_answers.build(answer: poll_answer) + end + end + status_message + end + + def add_photos(params, status_message) + status_message.attach_photos_by_ids(params[:photos]) + status_message + end + + def process_status_message(user) + add_status_message_to_streams(user) + dispatch_status_message(user) + user.participate!(@status_message) + end + + def add_status_message_to_streams(user) + aspects = user.aspects_from_ids(@destination_aspect_ids) + user.add_to_streams(@status_message, aspects) + end + + def dispatch_status_message(user) + receiving_services = Service.titles(@services) + user.dispatch_post(@status_message, + url: short_post_url(@status_message.guid, host: AppConfig.environment.url), + service_types: receiving_services) + end +end