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.where(slug: slug).first 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, errors_saved = [], 0, [] 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.where(id: item[:id]).first).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 self.object_class when "PostType_Post" caption = "Fields for Contents in #{self.site.post_types.find(self.objectid).decorate.the_title}" when 'PostType_Category' caption = "Fields for Categories in #{self.site.post_types.find(self.objectid).decorate.the_title}" when 'PostType_PostTag' caption = "Fields for Post tags in #{self.site.post_types.find(self.objectid).decorate.the_title}" when 'Widget::Main' caption = "Fields for Widget (#{CamaleonCms::Widget::Main.find(self.objectid).name.translate})" when 'Theme' caption = "Field settings for Theme (#{self.site.themes.find(self.objectid).name rescue self.objectid})" when 'NavMenu' caption = "Field settings for Menus (#{CamaleonCms::NavMenu.find(self.objectid).name})" when 'Site' caption = "Field settings the site" when 'PostType' caption = "Fields for all Post_Types" when 'Post' p = CamaleonCms::Post.find(self.objectid).decorate caption = "Fields for content (#{p.the_title})" else # 'Plugin' or other class caption = "Fields for #{self.object_class}" end rescue => e Rails.logger.info "----------#{e.message}----#{self.attributes}" end caption end private def before_validating self.slug = "_group-#{self.name.to_s.parameterize}" unless self.slug.present? end # auto save the default field values def auto_save_default_values(field, options) options = options.with_indifferent_access class_name = self.object_class.split("_").first if ["Post", "Category", "Plugin", "Theme"].include?(class_name) && self.objectid.present? && (options[:default_value].present? || options[:default_values].present?) if class_name == "Theme" owner = "CamaleonCms::#{class_name}".constantize.where(id: self.objectid).first # owner model else owner = "CamaleonCms::#{class_name}".constantize.find(self.objectid) rescue "CamaleonCms::#{class_name}".constantize.where(slug: self.objectid).first # 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