Initial commit
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
module Carto
|
||||
module Api
|
||||
class WidgetsController < ::Api::ApplicationController
|
||||
include Carto::ControllerHelper
|
||||
|
||||
ssl_required :show, :create, :update, :destroy, :update_many
|
||||
|
||||
before_filter :load_map
|
||||
before_filter :load_layer, :load_widget_id, except: [:update_many]
|
||||
before_filter :load_widget, only: [:show, :update, :destroy]
|
||||
|
||||
rescue_from Carto::LoadError, with: :rescue_from_carto_error
|
||||
rescue_from Carto::UnauthorizedError, with: :rescue_from_carto_error
|
||||
rescue_from Carto::UnprocesableEntityError, with: :rescue_from_carto_error
|
||||
|
||||
def show
|
||||
render_jsonp(WidgetPresenter.new(@widget).to_poro)
|
||||
end
|
||||
|
||||
def create
|
||||
order_param = params[:order]
|
||||
order = if order_param.present?
|
||||
order_param
|
||||
else
|
||||
@map.visualization.widgets.count
|
||||
end
|
||||
widget = Carto::Widget.new(
|
||||
layer_id: @layer_id,
|
||||
order: order,
|
||||
type: params[:type],
|
||||
title: params[:title],
|
||||
options: params[:options],
|
||||
style: params[:style],
|
||||
source_id: source_id_from_params)
|
||||
widget.save!
|
||||
|
||||
Carto::Tracking::Events::CreatedWidget.new(current_viewer.id,
|
||||
user_id: current_viewer.id,
|
||||
visualization_id: @layer.visualization.id,
|
||||
widget_id: widget.id).report
|
||||
|
||||
render_jsonp(WidgetPresenter.new(widget).to_poro, 201)
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
render json: { errors: widget.errors }, status: 422
|
||||
rescue => e
|
||||
CartoDB::Logger.error(exception: e, message: "Error creating widget", widget: (widget ? widget : 'not created'))
|
||||
render json: { errors: e.message }, status: 500
|
||||
end
|
||||
|
||||
def update
|
||||
update_widget!(@widget, params)
|
||||
|
||||
render_jsonp(WidgetPresenter.new(@widget).to_poro)
|
||||
rescue => e
|
||||
CartoDB::Logger.error(exception: e, message: "Error updating widget", widget: @widget)
|
||||
render json: { errors: e.message }, status: 500
|
||||
end
|
||||
|
||||
def update_many
|
||||
entries = params[:_json].map do |json_widget|
|
||||
{ widget: widget_with_validations(json_widget[:id]), json: json_widget }
|
||||
end
|
||||
result = ActiveRecord::Base.transaction do
|
||||
entries.map { |entry| update_widget!(entry[:widget], entry[:json]) }
|
||||
end
|
||||
render_jsonp(result.map { |widget| WidgetPresenter.new(widget).to_poro })
|
||||
end
|
||||
|
||||
def destroy
|
||||
@widget.destroy
|
||||
|
||||
render_jsonp(WidgetPresenter.new(@widget).to_poro)
|
||||
rescue => e
|
||||
CartoDB::Logger.error(exception: e, message: "Error destroying widget", widget: @widget)
|
||||
render json: { errors: e.message }, status: 500
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_widget!(widget, json_params)
|
||||
update_params = json_params.permit(:order, :type, :title)
|
||||
update_params[:source_id] = source_id_from_params(json_params) if source_id_from_params(json_params)
|
||||
widget.update_attributes(update_params)
|
||||
widget.options = json_params[:options]
|
||||
widget.style = json_params[:style]
|
||||
widget.save!
|
||||
widget
|
||||
end
|
||||
|
||||
def load_map
|
||||
@map_id = params[:map_id]
|
||||
@map = Carto::Map.where(id: @map_id).first
|
||||
raise LoadError.new("Map not found: #{@map_id}") unless @map
|
||||
raise Carto::UnauthorizedError.new("Not authorized for map #{@map.id}") unless @map.writable_by_user?(current_user)
|
||||
end
|
||||
|
||||
def load_layer
|
||||
@layer_id = params[:map_layer_id]
|
||||
payload_layer_id = params['layer_id']
|
||||
|
||||
if [payload_layer_id, @layer_id].compact.uniq.length >= 2
|
||||
raise UnprocesableEntityError.new("URL layer id (#{@layer_id}) and payload layer id (#{payload_layer_id}) don't match")
|
||||
end
|
||||
|
||||
@layer = Carto::Layer.where(id: @layer_id).first
|
||||
raise LoadError.new("Layer not found: #{@layer_id}") unless @layer
|
||||
|
||||
raise UnprocesableEntityError.new("Layer #{@layer_id} doesn't belong to map #{@map_id}") unless @map.contains_layer?(@layer)
|
||||
end
|
||||
|
||||
def load_widget_id
|
||||
@widget_id = params[:id]
|
||||
if [@widget_id, params[:id]].compact.uniq.length >= 2
|
||||
raise UnprocesableEntityError.new("URL id (#{@widget_id}) and payload id (#{params[:id]}) don't match")
|
||||
end
|
||||
end
|
||||
|
||||
def source_id_from_params(parameters = params)
|
||||
parameters[:source] ? parameters[:source][:id] : nil
|
||||
end
|
||||
|
||||
def load_widget
|
||||
@widget = widget_with_validations(@widget_id, @layer_id)
|
||||
end
|
||||
|
||||
def widget_with_validations(widget_id, layer_id = nil)
|
||||
widget = Carto::Widget.find(widget_id)
|
||||
|
||||
raise Carto::LoadError.new("Widget not found: #{@widget_id}") unless widget
|
||||
|
||||
if layer_id && widget.layer_id != layer_id
|
||||
raise Carto::LoadError.new("Widget not found: #{@widget_id}")
|
||||
end
|
||||
|
||||
unless widget.belongs_to_map?(@map_id)
|
||||
raise Carto::LoadError.new("Widget not found: #{@widget_id} for that map (#{@map_id})")
|
||||
end
|
||||
|
||||
unless widget.writable_by_user?(current_user)
|
||||
raise Carto::UnauthorizedError.new("Not authorized for widget #{@widget_id}")
|
||||
end
|
||||
|
||||
widget
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user