app/models/alchemy/page/page_elements.rb in alchemy_cms-4.1.2 vs app/models/alchemy/page/page_elements.rb in alchemy_cms-4.2.0.rc1

- old
+ new

@@ -3,34 +3,43 @@ module Alchemy module Page::PageElements extend ActiveSupport::Concern included do - attr_accessor :do_not_autogenerate + attr_accessor :autogenerate_elements - has_many :elements, -> { where(parent_element_id: nil).not_trashed.order(:position) } + has_many :elements, + -> { order(:position).not_nested.unfixed.not_trashed }, + class_name: 'Alchemy::Element' + has_many :elements_including_fixed, + -> { order(:position).not_nested.not_trashed }, + class_name: 'Alchemy::Element' has_many :trashed_elements, -> { Element.trashed.order(:position) }, class_name: 'Alchemy::Element' + has_many :fixed_elements, + -> { order(:position).fixed.not_trashed }, + class_name: 'Alchemy::Element' has_many :descendent_elements, - -> { order(:position).not_trashed }, + -> { order(:position).unfixed.not_trashed }, class_name: 'Alchemy::Element' has_many :contents, through: :elements has_many :descendent_contents, through: :descendent_elements, class_name: 'Alchemy::Content', source: :contents has_and_belongs_to_many :to_be_swept_elements, -> { distinct }, class_name: 'Alchemy::Element', join_table: ElementToPage.table_name - after_create :autogenerate_elements, unless: -> { systempage? || do_not_autogenerate } + after_create :generate_elements, + unless: -> { systempage? || autogenerate_elements == false } after_update :trash_not_allowed_elements!, if: :has_page_layout_changed? - after_update :autogenerate_elements, + after_update :generate_elements, if: :has_page_layout_changed? end module ClassMethods # Copy page elements @@ -39,66 +48,21 @@ # @param target [Alchemy::Page] # @return [Array] # def copy_elements(source, target) new_elements = [] - source.elements.not_trashed.each do |source_element| - cell = nil - if source_element.cell - cell = target.cells.find_by(name: source_element.cell.name) - end - new_element = Element.copy source_element, { - page_id: target.id, - cell_id: cell.try(:id) - } + source.elements_including_fixed.each do |source_element| + new_element = Element.copy(source_element, { + page_id: target.id + }) new_element.move_to_bottom new_elements << new_element end new_elements end end - # Finds elements of page. - # - # @param [Hash] - # options hash - # @param [Boolean] (false) - # Pass true, if you want to also have not published elements. - # - # @option options [Array] only - # Returns only elements with given names - # @option options [Array] except - # Returns all elements except the ones with given names - # @option options [Fixnum] count - # Limit the count of returned elements - # @option options [Fixnum] offset - # Starts with an offset while returning elements - # @option options [Boolean] random (false) - # Return elements randomly shuffled - # @option options [Alchemy::Cell || String] from_cell - # Return elements from given cell - # - # @return [ActiveRecord::Relation] - # - def find_elements(options = {}, show_non_public = false) - elements = elements_from_cell_or_self(options[:from_cell]) - if options[:only].present? - elements = elements.named(options[:only]) - elsif options[:except].present? - elements = elements.excluded(options[:except]) - end - if options[:reverse_sort] || options[:reverse] - elements = elements.reverse_order - end - elements = elements.offset(options[:offset]).limit(options[:count]) - if options[:random] - elements = elements.order("RAND()") - end - show_non_public ? elements : elements.published - end - alias_method :find_selected_elements, :find_elements - # All available element definitions that can actually be placed on current page. # # It extracts all definitions that are unique or limited and already on page. # # == Example of unique element: @@ -125,11 +89,11 @@ element_definitions end return [] if @_element_definitions.blank? - @_existing_element_names = elements.not_trashed.pluck(:name) + @_existing_element_names = elements_including_fixed.pluck(:name) delete_unique_element_definitions! delete_outnumbered_element_definitions! @_element_definitions end @@ -170,30 +134,24 @@ definitions += element_definitions_by_name(d['nestable_elements']) end definitions.uniq { |d| d['name'] } end - # All names of elements that are defined in the corresponding - # page and cell definition. + # All names of elements that are defined in the page definition. # - # Assign elements to a page in +config/alchemy/page_layouts.yml+ and/or - # +config/alchemy/cells.yml+ file. + # Assign elements to a page in +config/alchemy/page_layouts.yml+. # # == Example of page_layouts.yml: # # - name: contact - # cells: [right_column] # elements: [headline, contactform] # - # == Example of cells.yml: - # - # - name: right_column - # elements: [teaser] - # def element_definition_names - element_names_from_definition | element_names_from_cell_definitions + definition['elements'] || [] end + alias_method :element_names_from_definition, :element_definition_names + deprecate element_names_from_definition: :element_definition_names, deprecator: Alchemy::Deprecation # Element definitions with given name(s) # # @param [Array || String] # one or many Alchemy::Element names. Pass +'all'+ to get all Element definitions @@ -229,55 +187,29 @@ .where(Element.table_name => {folded: false}) .select(&:has_tinymce?) .collect(&:id) end - def element_names_from_definition - definition['elements'] || [] - end - private - def element_names_from_cell_definitions - @_element_names_from_cell_definitions ||= cell_definitions.map do |d| - d['elements'] - end.flatten - end - # Looks in the page_layout descripion, if there are elements to autogenerate. # # And if so, it generates them. # - # If the page has cells, it looks if there are elements to generate. - # - def autogenerate_elements - elements_already_on_page = elements.available.pluck(:name) - elements = definition["autogenerate"] - if elements.present? - elements.each do |element| - next if elements_already_on_page.include?(element) - Element.create_from_scratch(attributes_for_element_name(element)) - end + def generate_elements + elements_already_on_page = elements_including_fixed.pluck(:name) + definition.fetch('autogenerate', []).each do |element_name| + next if elements_already_on_page.include?(element_name) + Element.create(page: self, name: element_name) end end - # Returns a hash of attributes for given element name - def attributes_for_element_name(element) - element_cell_definition = cell_definitions.detect { |c| c['elements'].include?(element) } - if has_cells? && element_cell_definition - cell = cells.find_by!(name: element_cell_definition['name']) - {page_id: id, cell_id: cell.id, name: element} - else - {page_id: id, name: element} - end - end - # Trashes all elements that are not allowed for this page_layout. def trash_not_allowed_elements! not_allowed_elements = elements.where([ "#{Element.table_name}.name NOT IN (?)", - element_names_from_definition + element_definition_names ]) not_allowed_elements.to_a.map(&:trash!) end def has_page_layout_changed? @@ -300,33 +232,9 @@ # def delete_outnumbered_element_definitions! @_element_definitions.delete_if do |element| outnumbered = @_existing_element_names.select { |name| name == element['name'] } element['amount'] && outnumbered.count >= element['amount'].to_i - end - end - - # Returns elements either from given cell or self - # - def elements_from_cell_or_self(cell) - case cell.class.name - when 'Alchemy::Cell' - cell.elements - when 'String' - cell_elements_by_name(cell) - else - elements.not_in_cell - end - end - - # Returns all elements from given cell name - # - def cell_elements_by_name(name) - if cell = cells.find_by_name(name) - cell.elements - else - Alchemy::Logger.warn("Cell with name `#{name}` could not be found!", caller(0..0)) - Element.none end end end end