=begin Camaleon CMS is a content management system Copyright (C) 2015 by Owen Peredo Diaz Email: owenperedo@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License (GPLv3) for more details. =end class CamaleonCms::PostType < CamaleonCms::TermTaxonomy alias_attribute :site_id, :parent_id default_scope { where(taxonomy: :post_type) } has_many :metas, ->{ where(object_class: 'PostType')}, :class_name => "CamaleonCms::Meta", foreign_key: :objectid, dependent: :delete_all has_many :categories, :class_name => "CamaleonCms::Category", foreign_key: :parent_id, dependent: :destroy, inverse_of: :post_type_parent has_many :post_tags, :class_name => "CamaleonCms::PostTag", foreign_key: :parent_id, dependent: :destroy, inverse_of: :post_type has_many :posts, class_name: "CamaleonCms::Post", foreign_key: :taxonomy_id, dependent: :destroy, inverse_of: :post_type has_many :posts_through_categories, foreign_key: :objectid, through: :term_relationships, :source => :objects has_many :posts_draft, class_name: "CamaleonCms::Post", foreign_key: :taxonomy_id, dependent: :destroy, source: :drafts, inverse_of: :post_type has_many :field_group_taxonomy, -> {where("object_class LIKE ?","PostType_%")}, :class_name => "CamaleonCms::CustomField", foreign_key: :objectid, dependent: :destroy belongs_to :owner, class_name: "CamaleonCms::User", foreign_key: :user_id belongs_to :site, :class_name => "CamaleonCms::Site", foreign_key: :parent_id scope :visible_menu, -> {where(term_group: nil)} scope :hidden_menu, -> {where(term_group: -1)} before_destroy :destroy_field_groups after_create :set_default_site_user_roles after_create :refresh_routes after_destroy :refresh_routes after_update :check_refresh_routes before_update :default_category # check if current post type manage categories def manage_categories? options[:has_category] end # hide or show this post type on admin -> contents -> menu # true => enable, false => disable def toggle_show_for_admin_menu(flag) self.update(term_group: flag == true ? nil : -1) end # check if this post type is shown on admin -> contents -> menu def show_for_admin_menu? self.term_group == nil end # check if this post type manage post tags def manage_tags? options[:has_tags] end # assign settings for this post type # default values: { # has_category: false, # has_tags: false, # has_summary: true, # has_content: true, # has_comments: false, # has_picture: true, # has_template: true, # has_keywords: true, # not_deleted: false, # has_layout: false, # default_layout: '', # contents_route_format: 'post' # } def set_settings(settings = {}) settings.each do |key, val| self.set_option(key, val) end end # set or update a setting for this post type def set_setting(key, value) self.set_option(key, value) end # select full_categories for the post type, include all children categories def full_categories s = self.site CamaleonCms::Category.where("term_group = ? or status in (?)", s.id, s.post_types.pluck(:id).to_s) end # return default category for this post type # only return a category for post types that manage categories def default_category if manage_categories? cat = self.categories.find_by_slug("uncategorized") unless cat.present? cat = self.categories.create({name: 'Uncategorized', slug: 'uncategorized', parent: self.id}) cat.set_option("not_deleted", true) end cat end end # add a post for current model # title: title for post, => required # content: html text content, => required # thumb: image url, => default (empty). check http://camaleon.tuzitio.com/api-methods.html#section_fileuploads # categories: [1,3,4,5], => default (empty) # tags: String comma separated, => default (empty) # slug: string key for post, => default (empty) # summary: String resume (optional) => default (empty) # post_order: Integer to define the order position in the list (optional) # fields: Hash of values for custom fields, sample => fields: {subtitle: 'abc', icon: 'test' } (optional) # settings: Hash of post settings, sample => settings: # {has_content: false, has_summary: true, default_layout: 'my_layout', default_template: 'my_template' } (optional, see more in post.set_setting(...)) # data_metas: {template: "", layout: ""} # return created post if it was created, else return errors def add_post(args) _fields = args.delete(:fields) _settings = args.delete(:settings) _summary = args.delete(:summary) _order_position = args.delete(:order_position) _categories = args.delete(:categories) _tags = args.delete(:tags) _thumb = args.delete(:thumb) p = self.posts.new(args) p.slug = self.site.get_valid_post_slug(p.title.parameterize) unless p.slug.present? if p.save! _settings.each{ |k, v| p.set_setting(k, v) } if _settings.present? p.assign_category(_categories) if _categories.present? && self.manage_categories? p.assign_tags(_tags) if _tags.present? && self.manage_tags? p.set_position(_order_position) if _order_position.present? p.set_summary(_summary) if _summary.present? p.set_thumb(_thumb) if _thumb.present? _fields.each{ |k, v| p.save_field_value(k, v) } if _fields.present? return p.decorate else p.errors end end # return all available route formats of this post type for content posts def contents_route_formats { "post_of_post_type" => "/group/:post_type_id-:title/:slug
(Sample: http://localhost.com/group/17-services/myservice.html)", "post_of_category" => "/category/:category_id-:title/:slug
(Sample: http://localhost.com/category/17-services/myservice.html)", "post_of_category_post_type" => "/:post_type_title/category/:category_id-:title/:slug
(Sample: http://localhost.com/services/category/17-services/myservice.html)", "post_of_posttype" => "/:post_type_title/:slug
(Sample: http://localhost.com/services/myservice.html)", "post" => "/:slug
(Sample: http://localhost.com/myservice.html)", "hierarchy_post" => "/:parent1_slug/:parent2_slug/.../:slug
(Sample: http://localhost.com/item-1/item-1-1/item-111.html)" } end # return the configuration of routes for post contents def contents_route_format get_option("contents_route_format", "post") end # verify if this post_type support for page hierarchy (parents) def manage_hierarchy? get_option('has_parent_structure', false) end private # skip save_metas_options callback after save changes (inherit from taxonomy) to call from here manually def save_metas_options_skip true end # assign default roles for this post type # define default settings for this post type def set_default_site_user_roles self.set_multiple_options({has_category: false, has_tags: false, has_summary: true, has_content: true, has_comments: false, has_picture: true, has_template: true, has_keywords: true, not_deleted: false, has_layout: false, default_layout: ""}.merge((data_options||{}).to_sym)) self.site.set_default_user_roles(self) default_category end # destroy all custom field groups assigned to this post type def destroy_field_groups unless self.destroyed_by_association.present? if self.slug == "post" || self.slug == "page" errors.add(:base, "This post type can not be deleted.") return false end end self.get_field_groups.destroy_all end # reload routes to enable this post type url, like: http://localhost/my-slug def refresh_routes PluginRoutes.reload unless self.destroyed_by_association.present? end # check if slug was changed def check_refresh_routes refresh_routes if self.slug_changed? end end