Newer
Older
# == Schema Information
#
# Table name: communication_website_pages
#
# id :uuid not null, primary key
# header_cta :boolean default(FALSE)
# header_cta_label :string
# header_cta_url :string
# created_at :datetime not null
# updated_at :datetime not null
# parent_id :uuid indexed
# university_id :uuid not null, indexed
#
# Indexes
#
# index_communication_website_pages_on_communication_website_id (communication_website_id)
# index_communication_website_pages_on_language_id (language_id)
# index_communication_website_pages_on_original_id (original_id)
# index_communication_website_pages_on_parent_id (parent_id)
# index_communication_website_pages_on_university_id (university_id)
#
# Foreign Keys
#
# fk_rails_1a42003f06 (parent_id => communication_website_pages.id)
# fk_rails_280107c62b (communication_website_id => communication_websites.id)
# fk_rails_304f57360f (original_id => communication_website_pages.id)
# fk_rails_d208d15a73 (university_id => universities.id)
# kind was replaced by type in January 2023
self.ignored_columns = %w(path kind)
include Contentful # TODO L10N : To remove
include Filterable
include Shareable # TODO L10N : To remove
include Localizable
include WithBlobs # TODO L10N : To remove
include WithDuplication # TODO L10N : To adjust
include WithFeaturedImage # TODO L10N : To remove
# TODO L10N : To adjust (WithType)
include WithSpecialPage # WithSpecialPage can set default publication status, so must be included before WithPublication
include WithPosition # Scope :ordered must override WithPublication
include WithTree
has_summernote :text # TODO: Remove text attribute
# TODO L10N : remove after migrations
has_many :permalinks,
class_name: "Communication::Website::Permalink",
as: :about,
dependent: :destroy
belongs_to :parent,
class_name: 'Communication::Website::Page',
optional: true
has_many :children,
class_name: 'Communication::Website::Page',
after_save :touch_elements_if_special_page_in_hierarchy
scope :latest_in, -> (language) { published_now_in(language).order("communication_website_page_localizations.updated_at DESC").limit(5) }
scope :ordered_by_title, -> (language) {
localization_title_select = <<-SQL
COALESCE(
MAX(CASE WHEN localizations.language_id = '#{language.id}' THEN TRIM(LOWER(UNACCENT(localizations.title))) END),
MAX(TRIM(LOWER(UNACCENT(localizations.title)))) FILTER (WHERE localizations.rank = 1)
) AS localization_title
SQL
joins(sanitize_sql_array([<<-SQL
LEFT JOIN (
SELECT
localizations.*,
ROW_NUMBER() OVER(PARTITION BY localizations.about_id ORDER BY localizations.created_at ASC) as rank
FROM
communication_website_page_localizations as localizations
) localizations ON communication_website_pages.id = localizations.about_id
SQL
]))
.select("communication_website_pages.*", localization_title_select)
.group("communication_website_pages.id")
.order("localization_title ASC")
scope :for_search_term, -> (term, language) {
joins(:localizations)
.where(communication_website_page_localizations: { language_id: language.id })
.where("
unaccent(communication_website_page_localizations.meta_description) ILIKE unaccent(:term) OR
unaccent(communication_website_page_localizations.summary) ILIKE unaccent(:term) OR
unaccent(communication_website_page_localizations.title) ILIKE unaccent(:term)
", term: "%#{sanitize_sql_like(term)}%")
}
scope :for_published, -> (published, language) {
joins(:localizations)
.where(communication_website_page_localizations: { language_id: language.id , published: published == 'true'})
}
scope :for_full_width, -> (full_width, language = nil) { where(full_width: full_width == 'true') }
localizations.in_languages(website.active_language_ids)
website.menus.in_languages(website.active_language_ids) +
# La page actuelle a les bodyclass classe1 et classe2 ("classe1 classe2")
# Les différents ancêtres ont les classes home, bodyclass et secondclass
# -> "page-classe1 page-classe2 ancestor-home ancestor-bodyclass ancestor-secondclass"
classes = []
classes += add_prefix_to_classes(bodyclass.split(' '), 'page') unless bodyclass.blank?
classes += add_prefix_to_classes(ancestor_classes, 'ancestor') unless ancestor_classes.blank?
classes.join(' ')
self.class.unscoped
.where(parent: parent, university: university, website: website)
.where.not(id: id)
# Some special pages can override this method to allow explicit direct connections
# Example: The Communication::Website::Page::Person special page allows to connect University::Person records directly.
def self.direct_connection_permitted_about_class
# TODO L10N : to remove
def translate_other_attachments(translation)
translate_attachment(translation, :shared_image) if shared_image.attached?
end
# ["class1", "class2"], "page" -> ["page-class1", "page-class2"]
def add_prefix_to_classes(classes, prefix)
classes.map { |single_class| "#{prefix}-#{single_class}" }
end
# ["class1", "class2", "class3 class4"] -> ["class1", "class2", "class3", "class4"]
def ancestor_classes
@ancestor_classes ||= ancestors.pluck(:bodyclass)
.compact_blank
.join(' ')
.split(' ')
.compact_blank
website.pages.where(parent_id: parent_id).ordered.last
def abouts_with_page_block
website.blocks.pages.collect(&:about)
end
def touch_elements_if_special_page_in_hierarchy
# We do not call touch as we don't want to trigger the sync on the connected objects
descendants_and_self.each do |page|
if page.type == 'Communication::Website::Page::Person'
website.connected_people.update_all(updated_at: Time.zone.now)
elsif page.type == 'Communication::Website::Page::Organization'
website.connected_organizations.update_all(updated_at: Time.zone.now)