140 lines
3.5 KiB
Ruby
140 lines
3.5 KiB
Ruby
class ContentInstance
|
|
|
|
include Mongoid::Document
|
|
include Mongoid::Timestamps
|
|
|
|
## extensions ##
|
|
include CustomFields::ProxyClassEnabler
|
|
include Extensions::Shared::Seo
|
|
|
|
## fields (dynamic fields) ##
|
|
field :_slug
|
|
field :_position_in_list, :type => Integer, :default => 0
|
|
field :_visible, :type => Boolean, :default => true
|
|
|
|
## validations ##
|
|
validate :require_highlighted_field
|
|
validates :_slug, :presence => true, :uniqueness => { :scope => :content_type_id }
|
|
|
|
## associations ##
|
|
embedded_in :content_type, :inverse_of => :contents
|
|
|
|
## callbacks ##
|
|
before_validation :set_slug
|
|
before_save :set_visibility
|
|
before_create :add_to_list_bottom
|
|
after_create :send_notifications
|
|
|
|
## named scopes ##
|
|
scope :latest_updated, :order_by => :updated_at.desc, :limit => Locomotive.config.latest_items_nb
|
|
|
|
## methods ##
|
|
|
|
delegate :site, :to => :content_type
|
|
|
|
alias :visible? :_visible?
|
|
alias :_permalink :_slug
|
|
alias :_permalink= :_slug=
|
|
|
|
def site_id # needed by the uploader of custom fields
|
|
self.content_type.site_id
|
|
end
|
|
|
|
def highlighted_field_value
|
|
self.send(self.content_type.highlighted_field_name).to_s
|
|
end
|
|
|
|
alias :_label :highlighted_field_value
|
|
|
|
def visible?
|
|
self._visible || self._visible.nil?
|
|
end
|
|
|
|
def next
|
|
content_type.contents.where(:_position_in_list => _position_in_list + 1).first()
|
|
end
|
|
|
|
def previous
|
|
content_type.contents.where(:_position_in_list => _position_in_list - 1).first()
|
|
end
|
|
|
|
def errors_to_hash
|
|
Hash.new.replace(self.errors)
|
|
end
|
|
|
|
def reload_parent!
|
|
self.class.reload_parent!
|
|
end
|
|
|
|
def self.reload_parent!
|
|
self._parent = self._parent.reload
|
|
end
|
|
|
|
def to_liquid
|
|
Locomotive::Liquid::Drops::Content.new(self)
|
|
end
|
|
|
|
protected
|
|
|
|
# Sets the slug of the instance by using the value of the highlighted field
|
|
# (if available). If a sibling content instance has the same permalink then a
|
|
# unique one will be generated
|
|
def set_slug
|
|
self._slug = highlighted_field_value.dup if _slug.blank? && highlighted_field_value.present?
|
|
|
|
if _slug.present?
|
|
self._slug.permalink!
|
|
self._slug = next_unique_slug if slug_already_taken?
|
|
end
|
|
end
|
|
|
|
# Return the next available unique slug as a string
|
|
def next_unique_slug
|
|
slug = _slug.gsub(/-\d*$/, '')
|
|
last_slug = _parent.contents.where(:_id.ne => _id, :_slug => /^#{slug}-?\d*?$/i).order_by(:_slug).last._slug
|
|
next_number = last_slug.scan(/-(\d)$/).flatten.first.to_i + 1
|
|
|
|
[slug, next_number].join('-')
|
|
end
|
|
|
|
def slug_already_taken?
|
|
_parent.contents.where(:_id.ne => _id, :_slug => _slug).any?
|
|
end
|
|
|
|
def set_visibility
|
|
field = self.content_type.content_custom_fields.detect { |f| %w{visible active}.include?(f._alias) }
|
|
self._visible = self.send(field._name) rescue true
|
|
true
|
|
end
|
|
|
|
def add_to_list_bottom
|
|
self._position_in_list = self.content_type.contents.size
|
|
end
|
|
|
|
def require_highlighted_field
|
|
_alias = self.highlighted_field_alias
|
|
if self.send(_alias).blank?
|
|
self.errors.add(_alias, :blank)
|
|
end
|
|
end
|
|
|
|
def highlighted_field_alias
|
|
self.content_type.highlighted_field._alias.to_sym
|
|
end
|
|
|
|
def send_notifications
|
|
return unless self.content_type.api_enabled? && !self.content_type.api_accounts.blank?
|
|
|
|
accounts = self.content_type.site.accounts.to_a
|
|
|
|
self.content_type.api_accounts.each do |account_id|
|
|
next if account_id.blank?
|
|
|
|
account = accounts.detect { |a| a.id.to_s == account_id.to_s }
|
|
|
|
Admin::Notifications.new_content_instance(account, self).deliver
|
|
end
|
|
end
|
|
|
|
end
|