class CamaleonCms::CustomFieldGroup < CamaleonCms::CustomField
self.primary_key = :id
# attrs required: name, slug, description
alias_attribute :site_id, :parent_id
default_scope { where.not(object_class: '_fields')
.reorder("#{CamaleonCms::CustomField.table_name}.field_order ASC") }
has_many :metas, -> { where(object_class: 'CustomFieldGroup') }, class_name: 'CamaleonCms::Meta',
foreign_key: :objectid, dependent: :destroy
has_many :fields, -> { where(object_class: '_fields') }, class_name: 'CamaleonCms::CustomField',
foreign_key: :parent_id, dependent: :destroy
belongs_to :site, class_name: 'CamaleonCms::Site', foreign_key: :parent_id
validates_uniqueness_of :slug, scope: [:object_class, :objectid, :parent_id]
before_validation :before_validating
# add fields to group
# item:
# - sample: {"name"=>"Label", "slug"=>"my_slug", "description"=>"my description (optional)"}
# - options (textbox sample): {"field_key":"text_box","multiple":"1","required":"1",
# "translate":"1"}
# * field_key (string) | translate (boolean) | default_value (unique value) |
# default_values (array - multiple values for this field) | label_eval (boolean) |
# multiple_options (array)
# * multiple_options (used for select, radio and checkboxes ): [{"title"=>"Option Title",
# "value"=>"2", "default"=>"1"}, {"title"=>"abcde", "value"=>"3"}]
# * label_eval: (Boolean, default false), true => will evaluate the label and description of
# current field using (eval('my_label')) to have translatable|dynamic labels
# ****** check all options for each case in Admin::CustomFieldsHelper ****
# SAMPLE: my_model.add_field({"name"=>"Sub Title", "slug"=>"subtitle"}, {"field_key"=>"text_box",
# "translate"=>true, default_value: "Get in Touch"})
def add_manual_field(item, options)
c = get_field(item[:slug] || item['slug'])
return c if c.present?
field_item = self.fields.new(item)
if field_item.save
field_item.set_options(options)
auto_save_default_values(field_item, options)
end
field_item
end
alias_method :add_field, :add_manual_field
# return a field with slug = slug from current group
def get_field(slug)
self.fields.find_by(slug: slug)
end
# only used by form on admin panel (protected)
# return array of failed_fields and full_fields [[failed fields], [all fields]]
def add_fields(items, item_options)
self.fields.where.not(id: items.map { |_k, obj| obj['id'] }.uniq).destroy_all
cache_fields = []
order_index = 0
errors_saved = []
if items.present?
items.each do |i, item|
item[:field_order] = order_index
options = item_options[i] || {}
if item[:id].present? && (field_item = self.fields.find_by(id: item[:id])).present?
saved = field_item.update(item)
cache_fields << field_item
else
field_item = self.fields.new(item)
cache_fields << field_item
saved = field_item.save
auto_save_default_values(field_item, options) if saved
errors_saved << field_item unless saved
end
if saved
field_item.set_meta('_default', options)
order_index += 1
end
end
end
[errors_saved, cache_fields]
end
# generate the caption for this group
def get_caption
caption = ''
begin
case object_class
when 'PostType_Post'
caption = "Fields for Contents in #{self.site.post_types.find(objectid).decorate.the_title}"
when 'PostType_Category'
caption = "Fields for Categories in #{self.site.post_types.find(objectid).decorate.the_title}"
when 'PostType_PostTag'
caption = "Fields for Post tags in #{self.site.post_types.find(objectid).decorate.the_title}"
when 'Widget::Main'
caption = "Fields for Widget (#{CamaleonCms::Widget::Main.find(objectid).name.translate})"
when 'Theme'
caption = "Field settings for Theme (#{self.site.themes.find(objectid).name rescue objectid})"
when 'NavMenu'
caption = "Field settings for Menus (#{CamaleonCms::NavMenu.find(objectid).name})"
when 'Site'
caption = 'Field settings the site'
when 'PostType'
caption = 'Fields for all Post_Types'
when 'Post'
p = CamaleonCms::Post.find(objectid).decorate
caption = "Fields for content (#{p.the_title})"
else # 'Plugin' or other class
caption = "Fields for #{object_class}"
end
rescue => e
Rails.logger.debug "Camaleon CMS - Menu Item Error: #{e.message} ==> Attrs: #{self.attributes}"
end
caption
end
private
def before_validating
self.slug = "_group-#{name.to_s.parameterize}" unless slug.present?
end
# auto save the default field values
def auto_save_default_values(field, options)
options = options.with_indifferent_access
class_name = object_class.split("_").first
if %w(Post Category Plugin Theme).include?(class_name) && objectid && (options[:default_value].present? || options[:default_values].present?)
if class_name == 'Theme'
owner = "CamaleonCms::#{class_name}".constantize.find(objectid) # owner model
else
owner = "CamaleonCms::#{class_name}".constantize.find(objectid) rescue "CamaleonCms::#{class_name}".constantize.find_by(slug: objectid) # owner model
end
(options[:default_values] || [options[:default_value]] || []).each do |value|
owner.field_values.create!(custom_field_id: field.id, custom_field_slug: field.slug,
value: fix_meta_value(value)) if owner.present?
end
end
end
end