Skip to content
Snippets Groups Projects
block.rb 5.46 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
#  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
#  heading_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_heading_id                (heading_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
#  fk_rails_90ac986fab  (heading_id => communication_block_headings.id)
Arnaud Levy's avatar
Arnaud Levy committed
#
class Communication::Block < ApplicationRecord
Arnaud Levy's avatar
Arnaud Levy committed
  include AsIndirectObject
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 WithPosition
Arnaud Levy's avatar
Arnaud Levy committed
  include WithTemplate
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
  BLOCK_COPY_COOKIE = 'osuny-content-editor-block-copy'
Arnaud Levy's avatar
Arnaud Levy committed

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

Sébastien Gaya's avatar
Sébastien Gaya 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
Arnaud Levy's avatar
Arnaud Levy committed

Arnaud Levy's avatar
Arnaud Levy committed
  # Les numéros sont un peu en vrac
  # Dans l'idée, pour le futur
  # 1000 basic
  # 2000 storytelling
  # 3000 references
  # 4000 utilities
Arnaud Levy's avatar
Arnaud Levy committed
  enum template_kind: {
Arnaud Levy's avatar
Arnaud Levy committed
    agenda: 3100,
    call_to_action: 900,
Arnaud Levy's avatar
Arnaud Levy committed
    chapter: 50,
Arnaud Levy's avatar
Arnaud Levy committed
    contact: 57,
Arnaud Levy's avatar
Arnaud Levy committed
    datatable: 54,
alexisben's avatar
alexisben committed
    definitions: 800,
Arnaud Levy's avatar
Arnaud Levy committed
    embed: 53,
    features: 2010,
    files: 55,
    gallery: 300,
    image: 51,
    key_figures: 56,
    license: 4040,
Arnaud Levy's avatar
Arnaud Levy committed
    links: 4050,
    organizations: 200,
Sébastien Gaya's avatar
Sébastien Gaya committed
    pages: 600,
Sébastien Gaya's avatar
Sébastien Gaya committed
    persons: 100,
Arnaud Levy's avatar
Arnaud Levy committed
    posts: 500,
    projects: 3101,
Arnaud Levy's avatar
Arnaud Levy committed
    programs: 58,
Arnaud Levy's avatar
Arnaud Levy committed
    sound: 1005,
    testimonials: 400,
    timeline: 700,
    video: 52,
Arnaud Levy's avatar
Arnaud Levy committed
  }

  CATEGORIES = {
Arnaud Levy's avatar
Arnaud Levy committed
    basic: [:chapter, :image, :video, :sound, :datatable],
Arnaud Levy's avatar
Arnaud Levy committed
    storytelling: [:key_figures, :features, :gallery, :call_to_action, :testimonials, :timeline],
    references: [:pages, :posts, :persons, :organizations, :agenda, :programs, :locations, :projects],
Arnaud Levy's avatar
Arnaud Levy committed
    utilities: [:files, :definitions, :contact, :links, :license, :embed]
  scope :published, -> { where(published: true) }
  scope :without_heading, -> { where(heading: nil) }
Arnaud Levy's avatar
Arnaud Levy committed

Arnaud Levy's avatar
Arnaud Levy committed
  before_validation :set_university_and_website_from_about, on: :create
  def self.permitted_about_types
Sébastien Gaya's avatar
Sébastien Gaya committed
    ApplicationRecord.model_names_with_concern(Contentful)
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)
    @language ||= about.respond_to?(:language) ? about.language : about.university.default_language
  def is_a_translation?
    about.respond_to?(:is_a_translation?) && about.is_a_translation?
  end

  def original_language
    about.try(:original_language)
  end

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.heading = nil
    block.save
    block
  end

  def translate!(about_translation, heading_id = nil)
    translation = self.dup
    translation.about = about_translation
    translation.template.translate!
    translation.data = translation.template.data
pabois's avatar
pabois committed
    translation.heading_id = heading_id
pabois's avatar
pabois committed
    translation.save
Arnaud Levy's avatar
Arnaud Levy committed
  def empty?
    template.empty?
  end

Arnaud Levy's avatar
Arnaud Levy committed
  def full_text
    template.full_text
  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.where(heading_id: heading_id).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

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

  # if a block changed we need to touch the old targets (for example persons previously connected), and the new connected ones
  def touch_targets
    if persons?
      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