module Scrivito class ObjsController < WebserviceController around_action :authorize_selected_workspace_read, only: [:details, :page_class_selection, :widget_class_selection, :search] around_action :authorize_selected_workspace_write, only: [:create, :update, :destroy, :destroy_widget, :revert, :restore, :mark_resolved, :copy, :duplicate] before_filter :ensure_identical_selected_and_visible_workspace, only: [:create, :update, :copy, :duplicate, :page_class_selection, :widget_class_selection] def create created_obj = task_unaware_request(:post, "workspaces/#{selected_workspace.id}/objs", {obj: obj_params} ) render json: created_obj end def details load_object render json: {markup: render_to_string(@obj.details_view_path, layout: false)} end def update load_object changed_obj = task_unaware_request(:put, "workspaces/#{selected_workspace.id}/objs/#{params[:id]}", {obj: obj_params} ) render json: changed_obj end def destroy in_selected_workspace { load_object.destroy } render_empty_json end def destroy_widget raise ScrivitoError, "no widget_id param specified" if params[:widget_id].blank? in_selected_workspace do widget = load_object.widget_from_pool(params[:widget_id]) unless widget raise ScrivitoError, "widget with ID '#{params[:widget_id]}' not found in obj with ID '#{@obj.id}'" end widget.destroy end render_empty_json end def revert in_selected_workspace { load_object.revert } render_empty_json end def restore in_selected_workspace { Obj.restore(params[:id]) } render_empty_json end def mark_resolved in_selected_workspace { load_object.mark_resolved } render_empty_json end def copy render json: copy_obj(load_object, params[:parent_path]) end def duplicate load_object render json: copy_obj(@obj, parent_path(@obj.path)) end def page_class_selection valid_page_classes = Obj.valid_page_classes_beneath(params[:parent_path]) || Obj.descendants valid_page_classes.map!(&:to_s) page_class_names = valid_page_classes.map do |page_class_name| begin markup = render_to_string("#{page_class_name.underscore}/thumbnail") {name: page_class_name, markup: markup} rescue ActionView::MissingTemplate end end render json: page_class_names.compact end def widget_class_selection load_object valid_widget_classes = @obj.valid_widget_classes_for(params[:field_name]) || Widget.descendants valid_widget_classes.map!(&:to_s) widgets_classes = valid_widget_classes.map do |widget_class_name| template_path = "#{widget_class_name.underscore}/thumbnail" markup = begin render_to_string(template_path, layout: false) rescue ActionView::MissingTemplate render_to_string('scrivito/widget_thumbnail', layout: false, locals: {widget_class_name: widget_class_name, template_path: template_path}) end {name: widget_class_name, markup: markup} end render json: widgets_classes end def search in_selected_workspace do query = MultiJson.decode(params[:query]).with_indifferent_access search_builder = ObjSearchBuilder.new(query) enumerator = search_builder.build formatter = fetch_formatter(query[:format]) if params[:query_action] == 'size' render json: { total: enumerator.size } elsif formatter batch = enumerator.load_batch result = { total: enumerator.size, hits: batch.map { |obj| formatter.call(obj, scrivito_user) } } render json: result else render json: { error: format_missing_message(query[:format]) }, status: :not_found end end end private def load_object @obj = Obj.find(params[:id]) end def ensure_identical_selected_and_visible_workspace if selected_workspace != editing_context.visible_workspace raise ScrivitoError, "selected and visible workspace are not identical" end end def obj_params @obj_params ||= ObjParamsParser.new(request.host, request.port).parse(@obj, params[:obj]) end def copy_obj(obj, target_path) id = SecureRandom.hex(8) copied_obj = obj.copy(_id: id, _path: "#{target_path}/#{id}") dumped_last_changed = CmsRestApi::AttributeSerializer .convert_time(copied_obj[:_last_changed]) { _id: copied_obj[:_id], _last_changed: dumped_last_changed, _obj_class: copied_obj[:_obj_class_name], _path: copied_obj[:_path], } end def get_obj_attributes(id) task_unaware_request(:get, "workspaces/#{selected_workspace.id}/objs/#{id}") end def parent_path(path) path.split('/')[0..-2].join('/') end def current_page Obj.find(params[:current_page_id]) if params[:current_page_id].present? end helper_method :current_page delegate :task_unaware_request, to: CmsRestApi private def authorize_selected_workspace_read(&block) authorize_workspace_access(:read, selected_workspace, &block) end def authorize_selected_workspace_write(&block) authorize_workspace_access(:write, selected_workspace, &block) end def in_selected_workspace(&block) selected_workspace.as_current(&block) end def selected_workspace @selected_workspace ||= editing_context.selected_workspace end def render_empty_json render json: {} end def fetch_formatter(name) if name Configuration.obj_formats[name] else proc { |obj, _| obj.id } end end def format_missing_message(format_name) "The format with the name '#{format_name}' is not registered" end end end