module Scrivito class CmsRestApi class WidgetExtractor # Extract widgets from a given attribute tree # first return param: a flat hash of widget_like => updated widget attributes # second return param: the updated attributes def self.call(attributes, obj=nil) new(obj).extract_widgets(attributes) end def initialize(obj) @obj = obj end def extract_widgets(attributes) @extracted_widgets = {} updated_attributes = attributes.dup widget_pool = updated_attributes.delete(:_widget_pool) extract_widgets_from_pool(widget_pool) if widget_pool extract_widgets_from_attributes(updated_attributes) Extraction.new(extracted_widgets, updated_attributes) end private attr_reader :obj attr_reader :extracted_widgets def extract_widgets_from_pool(widget_pool) widget_pool.each do |widget, widget_properties| extracted_widgets[widget.id] = [widget, widget_properties] extract_widgets_from_attributes(widget_properties) end end def extract_widgets_from_attributes(attributes) attributes.each do |attribute_name, value| if value.is_a?(Array) && value.all? { |w| w.is_a?(BasicWidget) } value.each do |widget| unless widget.persisted? widget_attributes = widget.attach_to_obj(obj) extracted_widgets[widget.id] = [widget, widget_attributes] extract_widgets_from_attributes(widget_attributes) end end end end end class Extraction attr_reader :widget_pool_attributes, :attributes def initialize(widget_pool_attributes, attributes) @widget_pool_attributes = widget_pool_attributes @attributes = attributes end def notify_persisted(obj) widget_pool_attributes.each_value do |(widget, attributes)| if attributes.present? widget.notify_persisted(obj) end end end end end end end