class Page

def self.save_order(new_position)

def self.save_order(new_position)
  dictionary = Hash[*new_position.flatten(1)]
  dictionary.each do |id, position|
    page = Page.find_by_id(id)
    page.position = position if page.position.present?
    page.save
  end
end

def allowed_children_lookup

def allowed_children_lookup
  [default_child, *Page.descendants.sort_by(&:name)].uniq
end

def cache?

def cache?
  true
end

def child_path(child)

def child_path(child)
  clean_path(path + '/' + child.slug)
end

def clean_path(path)

def clean_path(path)
  "/#{ path.to_s.strip }/".gsub(%r{//+}, '/')
end

def date_column_names

def date_column_names
  self.columns.collect{|c| c.name if c.sql_type =~ /(date|time)/}.compact
end

def default_child

def default_child
  self.class.default_child
end

def default_page_fields(config = TrustyCms::Config)

def default_page_fields(config = TrustyCms::Config)
  default_fields = config['defaults.page.fields'].to_s.strip.split(/\s*,\s*/)
  default_fields.map do |name|
    PageField.new(:name => name)
  end
end

def default_page_parts(config = TrustyCms::Config)

def default_page_parts(config = TrustyCms::Config)
  default_parts = config['defaults.page.parts'].to_s.strip.split(/\s*,\s*/)
  default_parts.map do |name|
    PagePart.new(:name => name, :filter_id => config['defaults.page.filter'])
  end
end

def descendant_class(class_name)

def descendant_class(class_name)
  raise ArgumentError.new("argument must be a valid descendant of Page") unless is_descendant_class_name?(class_name)
  if ["", nil, "Page"].include?(class_name)
    Page
  else
    class_name.constantize
  end
end

def description

def description
  self["description"]
end

def description=(value)

def description=(value)
  self["description"] = value
end

def display_name(string = nil)

def display_name(string = nil)
  if string
    @display_name = string
  else
    @display_name ||= begin
      n = name.to_s
      n.sub!(/^(.+?)Page$/, '\1')
      n.gsub!(/([A-Z])/, ' \1')
      n.strip
    end
  end
  @display_name = @display_name + " - not installed" if missing? && @display_name !~ /not installed/
  @display_name
end

def display_name=(string)

def display_name=(string)
  display_name(string)
end

def field(name)

def field(name)
  if new_record? or fields.any?(&:new_record?)
    fields.detect { |f| f.name.downcase == name.to_s.downcase }
  else
    fields.find_by_name name.to_s
  end
end

def find_by_path(path, live = true, clean = true)

def find_by_path(path, live = true, clean = true)
  return nil if virtual?
  path = clean_path(path) if clean
  my_path = self.path
  if (my_path == path) && (not live or published?)
    return self
  elsif (path =~ /^#{Regexp.quote(my_path)}([^\/]*)/)
    slug_child = children.find_by_slug($1)
    if slug_child
      found = slug_child.find_by_path(path, live, clean) # TODO: set to find_by_path after deprecation
      return found if found
    end
    children.each do |child|
      found = child.find_by_path(path, live, clean) # TODO: set to find_by_path after deprecation
      return found if found
    end
  end
  unless slug_child
    file_not_found_types = ([FileNotFoundPage] + FileNotFoundPage.descendants)
    file_not_found_names = file_not_found_types.collect { |x| x.name }
    condition = (['class_name = ?'] * file_not_found_names.length).join(' or ')
    condition = "status_id = #{Status[:published].id} and (#{condition})" if live
    return children.where([condition] + file_not_found_names).first
  end
  slug_child
end

def find_by_path(path, live = true)

def find_by_path(path, live = true)
  raise MissingRootPageError unless root
  root.find_by_path(path, live)
end

def find_by_url(*args)

def find_by_url(*args)
  ActiveSupport::Deprecation.warn("`find_by_url' has been deprecated; use `find_by_path' instead.", caller)
  find_by_path(*args)
end

def has_or_inherits_part?(name)

def has_or_inherits_part?(name)
  has_part?(name) || inherits_part?(name)
end

def has_part?(name)

def has_part?(name)
  !part(name).nil?
end

def headers

def headers
  # Return a blank hash that child classes can override or merge
  { }
end

def inherits_part?(name)

def inherits_part?(name)
  !has_part?(name) && self.ancestors.any? { |page| page.has_part?(name) }
end

def is_descendant_class_name?(class_name)

def is_descendant_class_name?(class_name)
  (Page.descendants.map(&:to_s) + [nil, "", "Page"]).include?(class_name)
end

def layout_with_inheritance

def layout_with_inheritance
  unless layout_without_inheritance
    parent.layout if parent?
  else
    layout_without_inheritance
  end
end

def lazy_initialize_parser_and_context

def lazy_initialize_parser_and_context
  unless @parser and @context
    @context = PageContext.new(self)
    @parser = Radius::Parser.new(@context, :tag_prefix => 'r')
  end
  @parser
end

def load_subclasses

def load_subclasses
  ([TRUSTY_CMS_ROOT] + TrustyCms::Extension.descendants.map(&:root)).each do |path|
    Dir["#{path}/app/models/*_page.rb"].each do |page|
      $1.camelize.constantize if page =~ %r{/([^/]+)\.rb}
    end
  end
  if ActiveRecord::Base.connection.data_sources.include?('pages') && Page.column_names.include?('class_name') # Assume that we have bootstrapped
    Page.connection.select_values("SELECT DISTINCT class_name FROM pages WHERE class_name <> '' AND class_name IS NOT NULL").each do |p|
      begin
        p.constantize
      rescue NameError, LoadError
        #Rubocop: The use of eval is a serious security risk.
        #eval(%Q{class #{p} < Page; acts_as_tree; def self.missing?; true end end}, TOPLEVEL_BINDING)
        Rails.logger.error NameError
      end
    end
  end
end

def missing?

def missing?
  false
end

def new_with_defaults(config = TrustyCms::Config)

def new_with_defaults(config = TrustyCms::Config)
  page = new
  page.parts.concat default_page_parts(config)
  page.fields.concat default_page_fields(config)
  default_status = config['defaults.page.status']
  page.status = Status[default_status] if default_status
  page
end

def parent?

def parent?
  !parent.nil?
end

def parse(text)

def parse(text)
  text = "" if text.nil?
  lazy_initialize_parser_and_context.parse(text)
end

def parse_object(object)

def parse_object(object)
  text = object.content || ''
  text = parse(text)
  text = object.filter.filter(text) if object.respond_to? :filter_id
  text
end

def part(name)

def part(name)
  if new_record? or parts.to_a.any?(&:new_record?)
    parts.to_a.find {|p| p.name == name.to_s }
  else
    parts.find_by_name name.to_s
  end
end

def path

def path
  if parent?
    parent.child_path(self)
  else
    clean_path(slug)
  end
end

def process(request, response)

def process(request, response)
  @request, @response = request, response
  set_response_headers(@response)
  @response.body = render
  @response.status = response_code
end

def published?

def published?
  status == Status[:published]
end

def render

def render
  if layout
    parse_object(layout)
  else
    render_part(:body)
  end
end

def render_part(part_name)

def render_part(part_name)
  part = part(part_name)
  if part
    parse_object(part)
  else
    ''
  end
end

def render_snippet(snippet)

def render_snippet(snippet)
  parse_object(snippet)
end

def response_code

def response_code
  200
end

def root

def root
  find_by_parent_id(nil)
end

def scheduled?

def scheduled?
  status == Status[:scheduled]
end

def set_allowed_children_cache

def set_allowed_children_cache
  self.allowed_children_cache = allowed_children_lookup.collect(&:name).join(',')
end

def set_content_type(response)

def set_content_type(response)
  if layout
    content_type = layout.content_type.to_s.strip
    if content_type.present?
      response.headers['Content-Type'] = content_type
    end
  end
end

def set_response_headers(response)

def set_response_headers(response)
  set_content_type(response)
  headers.each { |k,v| response.headers[k] = v }
end

def status

def status
 Status.find(self.status_id)
end

def status=(value)

def status=(value)
  self.status_id = value.id
end

def update_status

def update_status
  self.published_at = Time.zone.now if published? && self.published_at == nil
  if self.published_at != nil && (published? || scheduled?)
    self[:status_id] = Status[:scheduled].id if self.published_at  > Time.zone.now
    self[:status_id] = Status[:published].id if self.published_at <= Time.zone.now
  end
  true
end

def update_virtual

def update_virtual
  unless self.class == Page.descendant_class(class_name)
    self.virtual = Page.descendant_class(class_name).new.virtual?
  else
    self.virtual = virtual?
  end
  true
end

def valid_class_name

def valid_class_name
  unless Page.is_descendant_class_name?(class_name)
    errors.add :class_name, "must be set to a valid descendant of Page"
  end
end