lib/scrivito/basic_widget.rb in scrivito_sdk-0.30.0 vs lib/scrivito/basic_widget.rb in scrivito_sdk-0.40.0.rc1

- old
+ new

@@ -64,31 +64,48 @@ def destroy new_widget_list = container[container_field_name] - [self] container.update(container_field_name => new_widget_list) end - # Clones the {Scrivito::BasicWidget Widget}. The clone gets all - # attributes of the original widget except nested widget attributes. - # The clone is not attached to an {Scrivito::BasicObj Obj} initially. - # It only becomes usable by assigning it to a widget attribute of an Obj. # - # @example - # # From another_obj, take the first widget in my_widgets, - # # and put a clone in obj's my_widgets. - # obj.update(my_widgets: [another_obj.my_widgets.first.clone]) + # Create a copy of a {Scrivito::BasicWidget Widget}. # # @api public - def clone - attributes = {} - data_from_cms.all_custom_attributes.each do |attr_name| - if type_of_attribute(attr_name) != 'widget' - attributes[attr_name] = read_attribute(attr_name) + # + # The copy will have all attributes of the original widget including its widgets. + # Its attributes can be accessed only after it has been stored in a widget field of an + # {Scrivito::BasicObj Obj}, since initially the copy is not stored in any widget field. + # + # @example Duplicate the first widget in field +my_widget+ + # obj.update(my_widgets: obj.my_widgets.push(obj.my_widgets.first.copy)) + # + def copy + attrs = {} + each_custom_attribute do |attr_name, attr_value, attr_type| + attrs[attr_name] = attr_type == 'widget' ? attr_value.map(&:copy) : attr_value + end + self.class.new(attrs) + end + + def copy_for_restore(referenced_ids) + attrs = {} + each_custom_attribute do |attr_name, attr_value, attr_type| + attrs[attr_name] = if attr_type == 'widget' + attr_value.reject { |widget| referenced_ids.include?(widget.id) } + .map { |widget| widget.copy_for_restore(referenced_ids) } + else + attr_value end end - self.class.new(attributes) + attrs['_id'] = id + self.class.new(attrs) end + def clone + raise "The method `clone' was removed. Please use `copy' instead" + end + def id if @id @id else raise_not_persisted_error @@ -191,10 +208,14 @@ # @api public def container_field_name @container_field_name || cache_container_and_field_name_for_widget.second end + def container_field_index + container[container_field_name].index(self) + end + def has_attribute?(key) key.to_s == '_obj_class' || super end def inspect @@ -262,9 +283,15 @@ obj.widget_data_for_revision(id, revision) end def cache_container_and_field_name_for_widget @cache_container_and_field_name_for_widget ||= obj.container_and_field_name_for_widget(id) + end + + def each_custom_attribute + data_from_cms.all_custom_attributes.each do |attr_name| + yield attr_name, read_attribute(attr_name), type_of_attribute(attr_name) + end end end end