Skip to content
Snippets Groups Projects
block.rb 4.66 KiB
Newer Older
Arnaud Levy's avatar
Arnaud Levy committed
# == Schema Information
#
# Table name: communication_blocks
#
Arnaud Levy's avatar
Arnaud Levy committed
#  id                       :uuid             not null, primary key
#  about_type               :string           indexed => [about_id]
#  data                     :jsonb
Arnaud Levy's avatar
Arnaud Levy committed
#  html_class               :string
Arnaud Levy's avatar
Arnaud Levy committed
#  migration_identifier     :string
Arnaud Levy's avatar
Arnaud Levy committed
#  position                 :integer          default(0), not null
#  published                :boolean          default(TRUE)
#  template_kind            :integer          default(NULL), not null
#  title                    :string
#  created_at               :datetime         not null
#  updated_at               :datetime         not null
#  about_id                 :uuid             indexed => [about_type]
#  communication_website_id :uuid             indexed
#  university_id            :uuid             not null, indexed
Arnaud Levy's avatar
Arnaud Levy committed
#
# Indexes
#
Arnaud Levy's avatar
Arnaud Levy committed
#  index_communication_blocks_on_communication_website_id  (communication_website_id)
#  index_communication_blocks_on_university_id             (university_id)
#  index_communication_website_blocks_on_about             (about_type,about_id)
Arnaud Levy's avatar
Arnaud Levy committed
#
# Foreign Keys
#
#  fk_rails_18291ef65f  (university_id => universities.id)
Arnaud Levy's avatar
Arnaud Levy committed
#  fk_rails_80e5625874  (communication_website_id => communication_websites.id)
Arnaud Levy's avatar
Arnaud Levy committed
#
class Communication::Block < ApplicationRecord
Arnaud Levy's avatar
Arnaud Levy committed
  BLOCK_COPY_COOKIE = 'osuny-content-editor-block-copy'
  CATEGORIES = {
    basic: [:title, :chapter, :image, :video, :sound, :datatable],
    storytelling: [:key_figures, :features, :gallery, :call_to_action, :testimonials, :timeline],
Arnaud Levy's avatar
Arnaud Levy committed
    references: [:pages, :posts, :persons, :organizations, :agenda, :programs, :locations, :projects, :papers, :volumes, :categories],
Arnaud Levy's avatar
Arnaud Levy committed
    utilities: [:files, :definitions, :contact, :links, :license, :embed]
  }

Arnaud Levy's avatar
Arnaud Levy committed
  include AsIndirectObject
Sébastien Gaya's avatar
Sébastien Gaya committed
  include Migratable
  include Orderable
Arnaud Levy's avatar
Arnaud Levy committed
  include WithAccessibility
Arnaud Levy's avatar
Arnaud Levy committed
  include WithHeadingRanks
Arnaud Levy's avatar
Arnaud Levy committed
  include WithHtmlClass
Arnaud Levy's avatar
Arnaud Levy committed
  include WithMediaLibrary
Arnaud Levy's avatar
Arnaud Levy committed
  include WithTemplate
  include WithOpenApi # Must be included after WithTemplate to load template_kinds
Arnaud Levy's avatar
Arnaud Levy committed
  include WithUniversity
  include Sanitizable
Arnaud Levy's avatar
Arnaud Levy committed

Arnaud Levy's avatar
Arnaud Levy committed
  belongs_to  :about, polymorphic: true
  belongs_to  :communication_website,
              class_name: "Communication::Website",
              optional: true
  alias       :website :communication_website

  before_validation :set_university_and_website_from_about, on: :create
  before_validation :execute_template_before_validation
Arnaud Levy's avatar
Arnaud Levy committed

  # We do not use the :touch option of the belongs_to association
  # because we do not want to touch the about when destroying the block.
  after_save :touch_about#, :touch_targets # FIXME
Arnaud Levy's avatar
Arnaud Levy committed

  scope :published, -> { where(published: true) }
Arnaud Levy's avatar
Arnaud Levy committed

Arnaud Levy's avatar
Arnaud Levy committed
  # When we set data from json, we pass it to the template.
  # The json we save is first sanitized and prepared by the template.
Arnaud Levy's avatar
Arnaud Levy committed
  def data=(value)
Arnaud Levy's avatar
Arnaud Levy committed
    template.data = value
Arnaud Levy's avatar
Arnaud Levy committed
    super template.data
Arnaud Levy's avatar
Arnaud Levy committed
  end

Arnaud Levy's avatar
Arnaud Levy committed
  # Template data is clean and sanitized, and initialized with json
Arnaud Levy's avatar
Arnaud Levy committed
  def data
Arnaud Levy's avatar
Arnaud Levy committed
    template.data
Arnaud Levy's avatar
Arnaud Levy committed
  end

Arnaud Levy's avatar
Arnaud Levy committed
  def dependencies
    template.dependencies
Arnaud Levy's avatar
Arnaud Levy committed
  end

Arnaud Levy's avatar
Arnaud Levy committed
  def references
    [about]
Arnaud Levy's avatar
Arnaud Levy committed
  end

  def language
    return @language if defined?(@language)
Arnaud Levy's avatar
Arnaud Levy committed
    return unless about.respond_to?(:language)
    @language ||= about.language
Arnaud Levy's avatar
Arnaud Levy committed
  def duplicate
    block = self.dup
    block.save
    block
  end

Arnaud Levy's avatar
Arnaud Levy committed
  def paste(about)
    block = self.dup
    block.about = about
    block.save
    block
  end

Arnaud Levy's avatar
Arnaud Levy committed
  def localize_for!(new_localization)
    localized_block = self.dup
    localized_block.about = new_localization
    localized_block.save
Arnaud Levy's avatar
Arnaud Levy committed
  def empty?
    template.empty?
  end

Arnaud Levy's avatar
Arnaud Levy committed
  def full_text
Arnaud Levy's avatar
Arnaud Levy committed
    "#{title} #{template.full_text}"
  end

  def slug
    title.blank? ? '' : "#{title.parameterize}"
Arnaud Levy's avatar
Arnaud Levy committed
  end

Arnaud Levy's avatar
Arnaud Levy committed
  def to_s
Arnaud Levy's avatar
Arnaud Levy committed
    title.blank?  ? "#{Communication::Block.model_name.human} #{position}"
                  : "#{title}"
Arnaud Levy's avatar
Arnaud Levy committed
  end
Sébastien Gaya's avatar
Sébastien Gaya committed
  def last_ordered_element
    about.blocks.ordered.last
Sébastien Gaya's avatar
Sébastien Gaya committed
  end

Arnaud Levy's avatar
Arnaud Levy committed
  def set_university_and_website_from_about
    # about always have an university_id but can have no communication_website_id
Arnaud Levy's avatar
Arnaud Levy committed
    self.university_id = about.university_id
Arnaud Levy's avatar
Arnaud Levy committed
    self.communication_website_id = about.try(:communication_website_id)
Arnaud Levy's avatar
Arnaud Levy committed
  end

  def execute_template_before_validation
    template.before_validation
  end

Arnaud Levy's avatar
Arnaud Levy committed
  def check_accessibility
    accessibility_merge template
  end

Sébastien Gaya's avatar
Sébastien Gaya committed
  def touch_about
    about.touch
  end
Arnaud Levy's avatar
Arnaud Levy committed
  # Invalidation des caches des personnes pour les backlinks
  # if a block changed we need to touch the old targets (for example persons previously connected), and the new connected ones
Arnaud Levy's avatar
Arnaud Levy committed
  # FIXME
    if persons? || organizations?
      dependencies.each(&:touch)
      # TODO: @arnaud help!
      # I need to touch the old dependencies
      # Ideally we should only touch the diff between old and new dependencies
    end
  end
Arnaud Levy's avatar
Arnaud Levy committed
end