=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 module CategoriesTagsForPosts extend ActiveSupport::Concern included do # data_tags: (String) tags name separated by commas, sample: "Tag1,Tag two,tag new" # data_categories: (Array) array of category ids assigned for this post, sample: [1,2,3] attr_accessible :data_tags, :data_categories attr_accessor :data_tags, :data_categories after_save :save_extra_data after_save :check_default_category end # check if this post can manage categories def manage_categories? post_type.manage_categories? end # check if this post can manage tags def manage_tags? post_type.manage_tags? end # update category assignations for this post # remove assignations that no longer exist # add new assignations # cats: (Array) array of category ids assigned for this post, sample: [1,2,3] def update_categories(cats=[]) rescue_extra_data cats = cats.to_i old_categories = categories.pluck("term_taxonomy.id") delete_categories = old_categories - cats news_categories = cats - old_categories term_relationships.where("term_taxonomy_id in (?)", delete_categories ).destroy_all if delete_categories.present? news_categories.each do |key| term_relationships.create(:term_taxonomy_id => key) end update_counters("categories") end # update tags assignations for this post # remove assignations that no longer exist # add new assignations # tags: (String) tags name separated by commas, sample: "Tag1,Tag two,tag new" def update_tags(tags) rescue_extra_data tags = tags.split(",").strip post_tags = self.post_type.post_tags post_tags = post_tags.where("name not in (?)", tags) if tags.present? self.term_relationships.where("term_taxonomy_id in (?)", post_tags.pluck("term_taxonomy.id")).destroy_all tags.each do |f| post_tag = self.post_type.post_tags.where({name: f}).first_or_create(slug: f.parameterize) self.term_relationships.where({term_taxonomy_id: post_tag.id}).first_or_create end update_counters("tags") end # Assign this post for category with id: category_id # categories_id: (Array) array of category ids assigned for this post, sample: [1,2,3] def assign_category(categories_id) categories_id = [categories_id] if categories_id.is_a?(Integer) rescue_extra_data categories_id.each do |key| term_relationships.where(:term_taxonomy_id => key).first_or_create! end update_counters("categories") end # Assign this post for category with id: category_id # categories_id: (Array) array of category ids assigned for this post, sample: [1,2,3] def unassign_category(categories_id) categories_id = [categories_id] if categories_id.is_a?(Integer) rescue_extra_data term_relationships.where(:term_taxonomy_id => categories_id).destroy_all update_counters("categories") end # Assign new tags to this post # tags_title: (String) tags name separated by commas, sample: "Tag1,Tag two,tag new" def assign_tags(tag_titles) update_counters_before tags = tag_titles.split(",").strip tags.each do |t| post_tag = self.post_type.post_tags.where(name: t).first_or_create! self.term_relationships.where({term_taxonomy_id: post_tag.id}).first_or_create! end update_counters("tags") end # Unassign tags from this post # tags_title: (String) tags name separated by commas, sample: "Tag1,Tag two,tag new" def unassign_tags(tag_titles) update_counters_before tags = tag_titles.split(",").strip self.term_relationships.where({term_taxonomy_id: self.post_type.post_tags.where(name: tags).pluck(:id)}).destroy_all update_counters("tags") end # update quantity of posts assigned for tags and categories assigned to this post def update_extra_data rescue_extra_data update_counters end private @cats_before, @tags_before = [], [] # save as a cache previous categories and tags assigned for this post def rescue_extra_data @cats_before = self.categories.pluck(:id) if manage_categories? @tags_before = self.post_tags.pluck(:id) if manage_tags? end # update quantity of posts assigned for tags and categories assigned to this post # if kind is empty, then this will update both: cats and tags # kind: (string) tags | categories def update_counters(kind = "") self.post_type.full_categories.where(id: (@cats_before + self.categories.pluck(:id)).uniq).each { |c| c.update_column("count", c.posts.published.size) } if ["", "categories"].include?(kind) && manage_categories? self.post_type.post_tags.where(id: (@tags_before + self.post_tags.pluck(:id)).uniq).each { |tag| tag.update_column("count", tag.posts.published.size) } if ["", "tags"].include?(kind) && manage_tags? end # save extra data such as: categories and tags assigned to this post def save_extra_data update_categories(self.data_categories) if manage_categories? && !self.data_categories.nil? update_tags(self.data_tags) if manage_tags? && !self.data_tags.nil? end # auto assign default categories if none categories were assigned def check_default_category if manage_categories? assign_category([self.post_type.default_category.id]) unless self.categories.present? end end end