camaleon_cms 2.1.2.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -4
  3. data/app/apps/plugins/attack/attack_helper.rb +3 -0
  4. data/app/apps/plugins/attack/config/custom_models.rb +4 -2
  5. data/app/apps/plugins/attack/config/locales/translation.yml +19 -0
  6. data/app/apps/plugins/attack/models/attack.rb +1 -1
  7. data/app/apps/plugins/front_cache/config/initializer.rb +4 -2
  8. data/app/apps/plugins/front_cache/config/locales/translation.yml +19 -0
  9. data/app/apps/themes/camaleon_first/main_helper.rb +1 -3
  10. data/app/apps/themes/default/views/admin/settings.html.erb +0 -1
  11. data/app/apps/themes/default/views/layouts/index.html.erb +5 -5
  12. data/app/apps/themes/new/assets/css/main.css +1 -1
  13. data/app/apps/themes/new/assets/js/main.js +1 -1
  14. data/app/apps/themes/new/views/admin/settings.html.erb +1 -1
  15. data/app/assets/images/camaleon_cms/language/{pt_br.png → pt-BR.png} +0 -0
  16. data/app/assets/javascripts/camaleon_cms/admin/_custom_fields.js +105 -51
  17. data/app/assets/javascripts/camaleon_cms/admin/_libraries.js +4 -2
  18. data/app/assets/javascripts/camaleon_cms/admin/_translator.js +2 -2
  19. data/app/assets/javascripts/camaleon_cms/admin/custom_fields_form.js +9 -7
  20. data/app/assets/javascripts/camaleon_cms/admin/jquery_validate/{pt_br.js → pt-BR.js} +0 -0
  21. data/app/assets/javascripts/camaleon_cms/admin/momentjs/{pt_br.js → pt-BR.js} +1 -1
  22. data/app/assets/javascripts/camaleon_cms/admin/nav_menu.js.coffee +15 -1
  23. data/app/assets/javascripts/camaleon_cms/admin/tinymce/langs/{pt_br.js → pt-BR.js} +1 -1
  24. data/app/assets/javascripts/camaleon_cms/admin/uploader/_media_manager.js.coffee +24 -12
  25. data/app/assets/stylesheets/camaleon_cms/admin/_custom_admin.css.scss +9 -0
  26. data/app/assets/stylesheets/camaleon_cms/admin/lte/_admin.css.scss +1 -1
  27. data/app/controllers/camaleon_cms/admin/appearances/nav_menus_controller.rb +13 -6
  28. data/app/controllers/camaleon_cms/admin/appearances/themes_controller.rb +1 -1
  29. data/app/controllers/camaleon_cms/admin/appearances/widgets/assign_controller.rb +1 -1
  30. data/app/controllers/camaleon_cms/admin/appearances/widgets/main_controller.rb +1 -1
  31. data/app/controllers/camaleon_cms/admin/appearances/widgets/sidebar_controller.rb +1 -1
  32. data/app/controllers/camaleon_cms/admin/comments_controller.rb +1 -1
  33. data/app/controllers/camaleon_cms/admin/media_controller.rb +15 -5
  34. data/app/controllers/camaleon_cms/admin/plugins_controller.rb +1 -1
  35. data/app/controllers/camaleon_cms/admin/settings/custom_fields_controller.rb +14 -8
  36. data/app/controllers/camaleon_cms/admin/settings_controller.rb +22 -7
  37. data/app/controllers/camaleon_cms/admin/user_roles_controller.rb +1 -1
  38. data/app/controllers/camaleon_cms/admin/users_controller.rb +1 -1
  39. data/app/controllers/camaleon_cms/apps/plugins_admin_controller.rb +4 -1
  40. data/app/controllers/camaleon_cms/apps/plugins_front_controller.rb +5 -10
  41. data/app/controllers/camaleon_cms/apps/themes_front_controller.rb +1 -4
  42. data/app/controllers/camaleon_cms/camaleon_controller.rb +4 -13
  43. data/app/controllers/camaleon_cms/frontend_controller.rb +15 -9
  44. data/app/controllers/concerns/camaleon_cms/frontend_concern.rb +17 -8
  45. data/app/decorators/camaleon_cms/application_decorator.rb +3 -3
  46. data/app/decorators/camaleon_cms/custom_fields_concern.rb +21 -6
  47. data/app/decorators/camaleon_cms/post_comment_decorator.rb +21 -0
  48. data/app/decorators/camaleon_cms/site_decorator.rb +5 -5
  49. data/app/decorators/camaleon_cms/theme_decorator.rb +10 -0
  50. data/app/decorators/camaleon_cms/user_decorator.rb +2 -2
  51. data/app/helpers/camaleon_cms/admin/custom_fields_helper.rb +24 -2
  52. data/app/helpers/camaleon_cms/admin/menus_helper.rb +13 -12
  53. data/app/helpers/camaleon_cms/frontend/application_helper.rb +1 -1
  54. data/app/helpers/camaleon_cms/frontend/nav_menu_helper.rb +7 -6
  55. data/app/helpers/camaleon_cms/plugins_helper.rb +20 -18
  56. data/app/helpers/camaleon_cms/site_helper.rb +1 -20
  57. data/app/helpers/camaleon_cms/theme_helper.rb +1 -1
  58. data/app/helpers/camaleon_cms/uploader_helper.rb +25 -20
  59. data/app/helpers/camaleon_cms/user_roles_helper.rb +6 -1
  60. data/app/mailers/camaleon_cms/html_mailer.rb +2 -1
  61. data/app/models/camaleon_cms/ability.rb +3 -26
  62. data/app/models/camaleon_cms/custom_field.rb +2 -1
  63. data/app/models/camaleon_cms/custom_field_group.rb +23 -22
  64. data/app/models/camaleon_cms/custom_fields_relationship.rb +1 -1
  65. data/app/models/camaleon_cms/nav_menu.rb +1 -1
  66. data/app/models/camaleon_cms/nav_menu_item.rb +12 -19
  67. data/app/models/camaleon_cms/post.rb +1 -1
  68. data/app/models/camaleon_cms/post_comment.rb +3 -1
  69. data/app/models/camaleon_cms/post_default.rb +1 -1
  70. data/app/models/camaleon_cms/post_type.rb +5 -4
  71. data/app/models/camaleon_cms/site.rb +12 -0
  72. data/app/models/camaleon_cms/term_taxonomy.rb +1 -1
  73. data/app/models/camaleon_cms/user_role.rb +5 -1
  74. data/app/models/concerns/camaleon_cms/custom_fields_read.rb +99 -49
  75. data/app/uploaders/camaleon_cms_aws_uploader.rb +1 -1
  76. data/app/uploaders/camaleon_cms_local_uploader.rb +19 -3
  77. data/app/uploaders/camaleon_cms_uploader.rb +13 -6
  78. data/app/views/camaleon_cms/admin/appearances/nav_menus/_custom_menus.html.erb +9 -2
  79. data/app/views/camaleon_cms/admin/appearances/nav_menus/_form.html.erb +1 -1
  80. data/app/views/camaleon_cms/admin/appearances/nav_menus/_menu_items.html.erb +2 -2
  81. data/app/views/camaleon_cms/admin/appearances/themes/index.html.erb +1 -3
  82. data/app/views/camaleon_cms/admin/media/_render_file_item.html.erb +1 -0
  83. data/app/views/camaleon_cms/admin/media/index.html.erb +3 -3
  84. data/app/views/camaleon_cms/admin/posts/_sidebar.html.erb +1 -1
  85. data/app/views/camaleon_cms/admin/posts/form.html.erb +1 -1
  86. data/app/views/camaleon_cms/admin/settings/_configuration_settings.html.erb +4 -0
  87. data/app/views/camaleon_cms/admin/settings/custom_fields/_get_items.html.erb +6 -6
  88. data/app/views/camaleon_cms/admin/settings/custom_fields/_meta_data.html.erb +0 -9
  89. data/app/views/camaleon_cms/admin/settings/custom_fields/_render.html.erb +39 -55
  90. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_audio.html.erb +1 -1
  91. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_checkbox.html.erb +2 -2
  92. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_checkboxes.html.erb +3 -3
  93. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_colorpicker.html.erb +3 -3
  94. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_date.html.erb +3 -3
  95. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_editor.html.erb +2 -2
  96. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_email.html.erb +1 -1
  97. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_field_attrs.html.erb +3 -3
  98. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_file.html.erb +1 -1
  99. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_image.html.erb +2 -2
  100. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_numeric.html.erb +1 -1
  101. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_phone.html.erb +1 -1
  102. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_posts.html.erb +3 -3
  103. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_private_file.html.erb +4 -0
  104. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_radio.html.erb +3 -3
  105. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_select.html.erb +3 -3
  106. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_select_eval.html.erb +1 -1
  107. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_text_area.html.erb +2 -2
  108. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_text_box.html.erb +2 -2
  109. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_url.html.erb +1 -1
  110. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_users.html.erb +1 -1
  111. data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_video.html.erb +1 -1
  112. data/app/views/camaleon_cms/admin/settings/custom_fields/form.html.erb +8 -0
  113. data/app/views/camaleon_cms/admin/settings/site.html.erb +1 -20
  114. data/app/views/camaleon_cms/admin/settings/theme.html.erb +20 -0
  115. data/app/views/camaleon_cms/admin/user_roles/form.html.erb +2 -2
  116. data/app/views/camaleon_cms/default_theme/admin/settings.html.erb +0 -1
  117. data/app/views/camaleon_cms/default_theme/partials/_comments.html.erb +0 -2
  118. data/app/views/camaleon_cms/default_theme/partials/_search_form.html.erb +1 -1
  119. data/app/views/camaleon_cms/default_theme/partials/_sidebar.html.erb +3 -3
  120. data/app/views/layouts/camaleon_cms/admin/_footer.html.erb +1 -1
  121. data/config/initializers/action_view.rb +12 -7
  122. data/config/initializers/custom_initializers.rb +6 -12
  123. data/config/locales/camaleon_cms/admin/en.yml +1 -0
  124. data/config/locales/camaleon_cms/admin/es.yml +4 -0
  125. data/config/locales/camaleon_cms/admin/it.yml +1 -24
  126. data/config/locales/camaleon_cms/admin/js.yml +41 -0
  127. data/config/locales/camaleon_cms/admin/{pt_br.yml → pt-BR.yml} +48 -18
  128. data/config/locales/camaleon_cms/common.yml +66 -0
  129. data/config/locales/camaleon_cms/languages.yml +13 -0
  130. data/config/locales/camaleon_cms/routes.yml +2 -2
  131. data/config/routes/admin.rb +3 -0
  132. data/config/system.json +3 -3
  133. data/db/migrate/20160606135421_improve_menus_structure.rb +7 -0
  134. data/db/migrate/20160609121449_add_group_to_custom_field_values.rb +5 -0
  135. data/lib/camaleon_cms/engine.rb +4 -3
  136. data/lib/camaleon_cms/version.rb +1 -1
  137. data/lib/ext/string.rb +20 -0
  138. data/lib/ext/translator.rb +2 -2
  139. data/lib/generators/camaleon_cms/gem_plugin_generator.rb +1 -1
  140. data/lib/generators/camaleon_cms/gem_plugin_template/config/camaleon_plugin.json +1 -1
  141. data/lib/generators/camaleon_cms/install_generator.rb +1 -0
  142. data/lib/generators/camaleon_cms/theme_template/app/apps/themes/my_theme/main_helper.rb +1 -4
  143. data/lib/generators/camaleon_cms/theme_template/app/apps/themes/my_theme/views/index.html.erb +1 -25
  144. data/lib/generators/camaleon_cms/theme_template/app/apps/themes/my_theme/views/layouts/index.html.erb +17 -18
  145. data/lib/plugin_routes.rb +4 -4
  146. metadata +25 -48
  147. data/app/apps/plugins/contact_form/admin_forms_controller.rb +0 -85
  148. data/app/apps/plugins/contact_form/assets/css/admin/form-builder/formbuilder.css +0 -70
  149. data/app/apps/plugins/contact_form/assets/css/contact-form.css +0 -8
  150. data/app/apps/plugins/contact_form/assets/css/front/railsform.scss +0 -94
  151. data/app/apps/plugins/contact_form/assets/css/readme.txt +0 -1
  152. data/app/apps/plugins/contact_form/assets/js/contact_form.js +0 -2
  153. data/app/apps/plugins/contact_form/assets/js/form-builder/formbuilder.js +0 -1271
  154. data/app/apps/plugins/contact_form/assets/js/form-builder/vendor.js +0 -3072
  155. data/app/apps/plugins/contact_form/assets/js/readme.txt +0 -1
  156. data/app/apps/plugins/contact_form/config/config.json +0 -35
  157. data/app/apps/plugins/contact_form/config/custom_models.rb +0 -3
  158. data/app/apps/plugins/contact_form/config/locales/readme.txt +0 -1
  159. data/app/apps/plugins/contact_form/config/locales/translation.yml +0 -315
  160. data/app/apps/plugins/contact_form/config/routes_admin.txt +0 -4
  161. data/app/apps/plugins/contact_form/config/routes_front.txt +0 -2
  162. data/app/apps/plugins/contact_form/contact_form_helper.rb +0 -154
  163. data/app/apps/plugins/contact_form/contact_form_html_helper.rb +0 -140
  164. data/app/apps/plugins/contact_form/front_controller.rb +0 -50
  165. data/app/apps/plugins/contact_form/models/contact_form.rb +0 -26
  166. data/app/apps/plugins/contact_form/views/admin_forms/_form.html.erb +0 -33
  167. data/app/apps/plugins/contact_form/views/admin_forms/edit.html.erb +0 -338
  168. data/app/apps/plugins/contact_form/views/admin_forms/index.html.erb +0 -65
  169. data/app/apps/plugins/contact_form/views/admin_forms/responses.html.erb +0 -60
  170. data/app/apps/plugins/contact_form/views/contact_form/_email_content.html.erb +0 -26
  171. data/app/apps/plugins/contact_form/views/forms_shorcode.html.erb +0 -28
  172. data/app/apps/plugins/contact_form/views/front/index.html.erb +0 -3
  173. data/app/apps/themes/camaleon_first/views/admin/settings.html.erb +0 -4
  174. data/app/apps/themes/new/assets/css/bootstrap/bootstrap.min.css +0 -6735
  175. data/app/apps/themes/new/assets/js/plugins/bootstrap/bootstrap.min.js +0 -6
  176. data/app/apps/themes/new/assets/js/plugins/jquery/jquery.min.js +0 -4
  177. data/lib/generators/camaleon_cms/gem_theme_generator.rb +0 -97
  178. data/lib/generators/camaleon_cms/gem_theme_template/app/assets/images/themes/my_plugin/image.png +0 -0
  179. data/lib/generators/camaleon_cms/gem_theme_template/app/assets/javascripts/themes/my_plugin/main.js +0 -14
  180. data/lib/generators/camaleon_cms/gem_theme_template/app/assets/stylesheets/themes/my_plugin/main.css +0 -13
  181. data/lib/generators/camaleon_cms/gem_theme_template/app/helpers/themes/my_plugin/main_helper.rb +0 -26
  182. data/lib/generators/camaleon_cms/gem_theme_template/app/views/themes/my_plugin/admin/settings.html.erb +0 -4
  183. data/lib/generators/camaleon_cms/gem_theme_template/app/views/themes/my_plugin/index.html.erb +0 -25
  184. data/lib/generators/camaleon_cms/gem_theme_template/app/views/themes/my_plugin/layouts/index.html.erb +0 -70
  185. data/lib/generators/camaleon_cms/gem_theme_template/app/views/themes/my_plugin/partials/readme.txt +0 -1
  186. data/lib/generators/camaleon_cms/gem_theme_template/config/camaleon_theme.json +0 -14
@@ -21,7 +21,7 @@ class CamaleonCms::NavMenu < CamaleonCms::TermTaxonomy
21
21
  # sample: {label: "my label", type: "category", link: 12}
22
22
  # return item created
23
23
  def append_menu_item (value)
24
- item = children.create!({name: value[:label], data_options: {type: value[:type], object_id: value[:link]}})
24
+ item = children.create!({name: value[:label], url: value[:link], kind: value[:type]})
25
25
  item
26
26
  end
27
27
 
@@ -7,6 +7,11 @@
7
7
  See the GNU Affero General Public License (GPLv3) for more details.
8
8
  =end
9
9
  class CamaleonCms::NavMenuItem < CamaleonCms::TermTaxonomy
10
+ alias_attribute :site_id, :term_group
11
+ alias_attribute :label, :name
12
+ alias_attribute :url, :description
13
+ alias_attribute :kind, :slug
14
+ attr_accessible :label, :url, :kind
10
15
  default_scope { where(taxonomy: :nav_menu_item).order(id: :asc) }
11
16
  has_many :metas, ->{ where(object_class: 'NavMenuItem')}, :class_name => "CamaleonCms::Meta", foreign_key: :objectid, dependent: :destroy
12
17
  belongs_to :parent, class_name: "CamaleonCms::NavMenu", inverse_of: :children
@@ -16,8 +21,6 @@ class CamaleonCms::NavMenuItem < CamaleonCms::TermTaxonomy
16
21
  before_create :set_parent_site
17
22
  after_create :update_count
18
23
  #before_destroy :update_count
19
- alias_attribute :site_id, :term_group
20
- alias_attribute :label, :name
21
24
 
22
25
  # return the main menu
23
26
  def main_menu
@@ -27,17 +30,6 @@ class CamaleonCms::NavMenuItem < CamaleonCms::TermTaxonomy
27
30
  parent_menu.main_menu if parent_menu.present?
28
31
  end
29
32
 
30
- # return the type of this menu (post|category|post_tag|post_type|external)
31
- def get_type
32
- self.get_option('type')
33
- end
34
-
35
- # return the url of the external menu item
36
- # return the object_id of menus like posttype, post, category, ...
37
- def url
38
- get_option('object_id')
39
- end
40
-
41
33
  # check if this menu have children
42
34
  def have_children?
43
35
  self.children.count != 0
@@ -47,19 +39,17 @@ class CamaleonCms::NavMenuItem < CamaleonCms::TermTaxonomy
47
39
  # same values of NavMenu#append_menu_item
48
40
  # return item created
49
41
  def append_menu_item(value)
50
- children.create({name: value[:label], data_options: {type: value[:type], object_id: value[:link]}})
42
+ children.create({name: value[:label], url: value[:link], kind: value[:type]})
51
43
  end
52
44
 
53
45
  # update current menu
54
46
  # value: same as append_menu_item (label, link)
55
47
  def update_menu_item(value)
56
- self.update({name: value[:label], data_options: {object_id: value[:link]}})
48
+ self.update({name: value[:label], url: value[:link]})
57
49
  end
58
50
 
59
- # skip uniq slug validation
60
- def skip_slug_validation?
61
- true
62
- end
51
+ # overwrite skip uniq slug validation
52
+ def skip_slug_validation?; true end
63
53
 
64
54
  private
65
55
  def update_count
@@ -73,4 +63,7 @@ class CamaleonCms::NavMenuItem < CamaleonCms::TermTaxonomy
73
63
  self.site_id = self.parent_item.site_id if self.parent_item.present?
74
64
  self.site_id = self.parent.site_id if self.parent.present?
75
65
  end
66
+
67
+ # overwrite inherit method
68
+ def destroy_dependencies; end
76
69
  end
@@ -213,7 +213,7 @@ class CamaleonCms::Post < CamaleonCms::PostDefault
213
213
  # return the layout assigned to this post
214
214
  # post_type: post type owner of this post
215
215
  def get_layout(posttype = nil)
216
- return get_option("default_template") if !manage_layout?(posttype)
216
+ return get_option("default_layout") if !manage_layout?(posttype)
217
217
  get_meta('layout', get_option("default_layout") || (posttype || self.post_type).get_option('default_layout', nil))
218
218
  end
219
219
 
@@ -10,7 +10,8 @@ class CamaleonCms::PostComment < ActiveRecord::Base
10
10
  include CamaleonCms::Metas
11
11
  self.table_name = "#{PluginRoutes.static_system_info["db_prefix"]}comments"
12
12
  attr_accessible :user_id, :post_id, :content, :author, :author_email, :author_url, :author_IP,
13
- :approved, :agent, :agent, :typee, :comment_parent
13
+ :approved, :agent, :agent, :typee, :comment_parent, :is_anonymous
14
+ attr_accessor :is_anonymous
14
15
 
15
16
  #default_scope order('comments.created_at ASC')
16
17
  #approved: approved | pending | spam
@@ -28,6 +29,7 @@ class CamaleonCms::PostComment < ActiveRecord::Base
28
29
  scope :approveds, -> { where(:approved => 'approved') }
29
30
 
30
31
  validates :content, :presence => true
32
+ validates_presence_of :author, :author_email, if: Proc.new { |c| c.is_anonymous.present? }
31
33
  after_create :update_counter
32
34
  after_destroy :update_counter
33
35
 
@@ -56,7 +56,7 @@ class CamaleonCms::PostDefault < ActiveRecord::Base
56
56
 
57
57
  # return all menu items in which this post was assigned
58
58
  def in_nav_menu_items
59
- CamaleonCms::NavMenuItem.joins(:metas).where("value LIKE ?","%\"object_id\":\"#{self.id}\"%").where("value LIKE ?","%\"type\":\"post\"%").readonly(false)
59
+ CamaleonCms::NavMenuItem.where(url: self.id, kind: 'post')
60
60
  end
61
61
 
62
62
  # Set the meta, field values and the post keywords here
@@ -13,6 +13,7 @@ class CamaleonCms::PostType < CamaleonCms::TermTaxonomy
13
13
  has_many :categories, :class_name => "CamaleonCms::Category", foreign_key: :parent_id, dependent: :destroy, inverse_of: :post_type_parent
14
14
  has_many :post_tags, :class_name => "CamaleonCms::PostTag", foreign_key: :parent_id, dependent: :destroy, inverse_of: :post_type
15
15
  has_many :posts, class_name: "CamaleonCms::Post", foreign_key: :taxonomy_id, dependent: :destroy, inverse_of: :post_type
16
+ has_many :comments, through: :posts
16
17
  has_many :posts_through_categories, foreign_key: :objectid, through: :term_relationships, :source => :objects
17
18
  has_many :posts_draft, class_name: "CamaleonCms::Post", foreign_key: :taxonomy_id, dependent: :destroy, source: :drafts, inverse_of: :post_type
18
19
  has_many :field_group_taxonomy, -> {where("object_class LIKE ?","PostType_%")}, :class_name => "CamaleonCms::CustomField", foreign_key: :objectid, dependent: :destroy
@@ -108,21 +109,21 @@ class CamaleonCms::PostType < CamaleonCms::TermTaxonomy
108
109
  # settings: Hash of post settings, sample => settings:
109
110
  # {has_content: false, has_summary: true, default_layout: 'my_layout', default_template: 'my_template' } (optional, see more in post.set_setting(...))
110
111
  # data_metas: {template: "", layout: ""}
112
+ # sample: my_posttype.add_post(title: "My Title", post_order: 5, content: 'lorem_ipsum', settings: {default_template: "home/counters", has_content: false, has_keywords: false, skip_fields: ["sub_tite", 'banner']}, fields: {pattern: true, bg: 'http://www.reallusion.com/de/images/3dx5/whatsnew/3dx5_features_banner_bg_02.jpg'})
113
+ # More samples here: https://gist.github.com/owen2345/eba9691585ed78ad6f7b52e9591357bf
111
114
  # return created post if it was created, else return errors
112
115
  def add_post(args)
113
116
  _fields = args.delete(:fields)
114
117
  _settings = args.delete(:settings)
115
118
  _summary = args.delete(:summary)
116
119
  _order_position = args.delete(:order_position)
117
- _categories = args.delete(:categories)
118
- _tags = args.delete(:tags)
120
+ args[:data_categories] = _categories = args.delete(:categories)
121
+ args[:data_tags] = args.delete(:tags)
119
122
  _thumb = args.delete(:thumb)
120
123
  p = self.posts.new(args)
121
124
  p.slug = self.site.get_valid_post_slug(p.title.parameterize) unless p.slug.present?
122
125
  if p.save!
123
126
  _settings.each{ |k, v| p.set_setting(k, v) } if _settings.present?
124
- p.assign_category(_categories) if _categories.present? && self.manage_categories?
125
- p.assign_tags(_tags) if _tags.present? && self.manage_tags?
126
127
  p.set_position(_order_position) if _order_position.present?
127
128
  p.set_summary(_summary) if _summary.present?
128
129
  p.set_thumb(_thumb) if _thumb.present?
@@ -252,6 +252,17 @@ class CamaleonCms::Site < CamaleonCms::TermTaxonomy
252
252
  self.status == 'maintenance'
253
253
  end
254
254
 
255
+ # return the anonymous user
256
+ # if the anonymous user not exist, will create one
257
+ def get_anonymous_user
258
+ user = self.users.where(username: 'anonymous').first
259
+ unless user.present?
260
+ pass = "anonymous#{rand(9999)}"
261
+ user = self.users.create({email: 'anonymous_user@local.com', username: 'anonymous', password: pass, password_confirmation: pass, first_name: 'Anonymous'})
262
+ end
263
+ user
264
+ end
265
+
255
266
  private
256
267
  # destroy all things before site destroy
257
268
  def destroy_site
@@ -291,6 +302,7 @@ class CamaleonCms::Site < CamaleonCms::TermTaxonomy
291
302
  @nav_menu.append_menu_item({label: title, type: 'post', link: post.id})
292
303
  end
293
304
  end
305
+ get_anonymous_user
294
306
  end
295
307
 
296
308
  # assign all users to this new site
@@ -43,7 +43,7 @@ class CamaleonCms::TermTaxonomy < ActiveRecord::Base
43
43
 
44
44
  # return all menu items in which this taxonomy was assigned
45
45
  def in_nav_menu_items
46
- CamaleonCms::NavMenuItem.joins(:metas).where("value LIKE ?","%\"object_id\":\"#{self.id}\"%").where("value LIKE ?","%\"type\":\"#{self.taxonomy}\"%").readonly(false)
46
+ CamaleonCms::NavMenuItem.where(url: self.id, kind: self.taxonomy)
47
47
  end
48
48
 
49
49
  # permit to skip slug validations for children models, like menu items
@@ -129,8 +129,12 @@ class CamaleonCms::UserRole < CamaleonCms::TermTaxonomy
129
129
  key: 'settings',
130
130
  label: "#{I18n.t('camaleon_cms.admin.sidebar.settings')}",
131
131
  description: "#{I18n.t('camaleon_cms.admin.users.tool_tip.settings')}"
132
+ },
133
+ {
134
+ key: 'theme_settings',
135
+ label: "#{I18n.t('camaleon_cms.admin.settings.theme_setting', default: 'Theme Settings')}",
136
+ description: "#{I18n.t('camaleon_cms.admin.users.tool_tip.themes')}"
132
137
  }
133
138
  ]
134
139
  }
135
-
136
140
  end
@@ -21,22 +21,27 @@ module CamaleonCms::CustomFieldsRead extend ActiveSupport::Concern
21
21
  # get custom field groups for current object
22
22
  # only: Post_type, Post, Category, PostTag, Widget, Site and a Custom model pre configured
23
23
  # return collections CustomFieldGroup
24
- # args: (Hash)
25
- # kind: argument only for PostType Objects: (Post (Default) | Category | PostTag).
24
+ # args: (Hash, used only for PostType Objects)
25
+ # kind: (Post (Default) | Category | PostTag | PostType).
26
+ # If kind = "Post" this will return all groups for all posts from current post type
27
+ # If kind = "Category" this will return all groups for all categories from current post type
28
+ # If kind = "PostTag" this will return all groups for all posttags from current post type
29
+ # If kind = "all" this will return all groups from current post type
26
30
  # If kind = "post_type" this will return groups for all post_types
27
- # If kind = "Post" this will return all groups for all posts from current post type + groups of current post type
28
- # include_parent: (boolean, default false) Permit to recover groups from self + parent post_type (argument valid only for Post | PostTag | Category)
29
- # args: (String) => is a value for kind attribute
31
+ # Sample: mypost.get_field_groups() ==> return fields for posts from parent posttype
32
+ # Sample: mycat.get_field_groups() ==> return fields for categories from parent posttype
33
+ # Sample: myposttag.get_field_groups() ==> return fields for posttags from parent posttype
34
+ # Sample: mypost_type.get_field_groups({kind: 'Post'}) => return custom fields for posts
35
+ # Sample: mypost_type.get_field_groups({kind: 'Category'}) => return custom fields for posts
36
+ # Sample: mypost_type.get_field_groups({kind: 'PostTag'}) => return custom fields for posts
30
37
  def get_field_groups(args = {})
31
38
  args = args.is_a?(String) ? {kind: args, include_parent: false } : {kind: "Post", include_parent: false }.merge(args)
32
39
  class_name = self.class.to_s.parseCamaClass
33
40
  case class_name
34
- when 'Category','Post','PostTag'
35
- if args[:include_parent]
36
- CamaleonCms::CustomFieldGroup.where("(objectid = ? AND object_class = ?) OR (objectid = ? AND object_class = ?)", self.id || -1, class_name, self.post_type.id, "PostType_#{class_name}")
37
- else
38
- CamaleonCms::CustomFieldGroup.where(objectid: self.id || -1, object_class: class_name)
39
- end
41
+ when 'Category','PostTag'
42
+ self.post_type.get_field_groups(class_name)
43
+ when 'Post'
44
+ CamaleonCms::CustomFieldGroup.where("(objectid = ? AND object_class = ?) OR (objectid = ? AND object_class = ?)", self.id || -1, class_name, self.post_type.id, "PostType_#{class_name}")
40
45
  when 'NavMenuItem'
41
46
  self.main_menu.field_groups
42
47
  when 'PostType'
@@ -65,33 +70,48 @@ module CamaleonCms::CustomFieldsRead extend ActiveSupport::Concern
65
70
  # _key: custom field key
66
71
  # if value is not present, then return default
67
72
  # return default only if the field was not registered
68
- def get_field_value(_key, _default = nil)
69
- v = _default
70
- v = get_field_values(_key).first rescue _default
73
+ def get_field_value(_key, _default = nil, group_number = 0)
74
+ v = get_field_values(_key, group_number).first rescue _default
71
75
  v.present? ? v : _default
72
76
  end
73
77
  alias_method :get_field, :get_field_value
74
-
75
- # the same as the_field() but if the value is not present, this will return default value
76
- def get_field!(_key, _default = nil)
77
- v = _default
78
- v = get_field_values(_key).first rescue _default
79
- v.present? ? v : _default
80
- end
78
+ alias_method :get_field!, :get_field_value
81
79
 
82
80
  # get custom field values
83
81
  # _key: custom field key
84
- def get_field_values(_key)
85
- self.field_values.where(custom_field_slug: _key).pluck(:value)
82
+ def get_field_values(_key, group_number = 0)
83
+ self.field_values.where(custom_field_slug: _key, group_number: group_number).pluck(:value)
86
84
  end
87
85
  alias_method :get_fields, :get_field_values
88
86
 
89
- # ------------- new function update field value -------------
90
- def update_field_value(_key, value = nil)
91
- self.field_values.where(custom_field_slug: _key).first.update_column('value', value) rescue nil
87
+ # return the values of custom fields grouped by group_number
88
+ # field_keys: (array of keys)
89
+ # samples: my_object.get_fields_grouped(['my_slug1', 'my_slug2'])
90
+ # return: [
91
+ # { 'my_slug1' => ["val 1"], 'my_slug2' => ['val 2']},
92
+ # { 'my_slug1' => ["val2 for slug1"], 'my_slug2' => ['val 2 for slug2']}
93
+ # ] ==> 2 groups
94
+ #
95
+ # return: [
96
+ # { 'my_slug1' => ["val 1", 'val 2 for fields multiple support'], 'my_slug2' => ['val 2']},
97
+ # { 'my_slug1' => ["val2 for slug1", 'val 2'], 'my_slug2' => ['val 2 for slug2']}
98
+ # { 'my_slug1' => ["val3 for slug1", 'val 3'], 'my_slug2' => ['val 3 for slug2']}
99
+ # ] ==> 3 groups
100
+ #
101
+ # puts res[0]['my_slug1'].first ==> "val 1"
102
+ def get_fields_grouped(field_keys)
103
+ res = []
104
+ field_values.where(custom_field_slug: field_keys).order(group_number: :asc).group_by(&:group_number).each do |group_number, group_fields|
105
+ group = {}
106
+ field_keys.each do |field_key|
107
+ group[field_key] = []
108
+ group_fields.each{ |field| group[field_key] << field.value if field_key == field.custom_field_slug }
109
+ end
110
+ res << group
111
+ end
112
+ res
92
113
  end
93
114
 
94
-
95
115
  # return all values
96
116
  # {key1: "single value", key2: [multiple, values], key3: value4} if include_options = false
97
117
  # {key1: {values: "single value", options: {a:1, b: 4}}, key2: {values: [multiple, values], options: {a=1, b=2} }} if include_options = true
@@ -127,6 +147,7 @@ module CamaleonCms::CustomFieldsRead extend ActiveSupport::Concern
127
147
  # name: name for the group
128
148
  # slug: key for group (if slug = _default => this will never show title and description)
129
149
  # description: description for the group (optional)
150
+ # is_repeat: (boolean, optional -> default false) indicate if group support multiple format (repeated values)
130
151
  # Model supported: PostType, Category, Post, Posttag, Widget, Plugin, Theme, User and Custom models pre configured
131
152
  # Note 1: If you need add fields for all post's or all categories, then you need to add the fields into the
132
153
  # post_type.add_custom_field_group(values, kind = "Post")
@@ -140,7 +161,11 @@ module CamaleonCms::CustomFieldsRead extend ActiveSupport::Concern
140
161
  unless group.present?
141
162
  site = _cama_get_field_site
142
163
  values[:parent_id] = site.id if site.present?
143
- group = get_field_groups(kind).create(values)
164
+ if self.is_a?(CamaleonCms::Post) # harcoded for post to support custom field groups
165
+ group = CamaleonCms::CustomFieldGroup.where(object_class: "Post", objectid: self.id).create!(values)
166
+ else
167
+ group = get_field_groups(kind).create!(values)
168
+ end
144
169
  end
145
170
  group
146
171
  end
@@ -157,47 +182,72 @@ module CamaleonCms::CustomFieldsRead extend ActiveSupport::Concern
157
182
  end
158
183
  alias_method :add_field, :add_custom_field_to_default_group
159
184
 
160
- # only custom field plugin (protected)
161
- # example:
162
- # id: custom_field_id
185
+ # return field object for current model
186
+ def get_field_object(slug)
187
+ CamaleonCms::CustomField.where(parent_id: get_field_groups.pluck(:id), slug: slug).first || CamaleonCms::CustomField.where(slug: slug, parent_id: get_field_groups({include_parent: true})).first
188
+ end
189
+
190
+ # save all fields sent from browser (reservated for browser request)
191
+ # sample:
163
192
  # {
164
- # :key : {id: 123, values: ['uno','dos']}
165
- # :key2 : {id: 455, values: ['uno','dos']}
166
- # :key3 : {id: 4555, values: ['uno','dos']}
193
+ # "0"=>{ "untitled-text-box"=>{"id"=>"262", "values"=>{"0"=>"33333"}}},
194
+ # "1"=>{ "untitled-text-box"=>{"id"=>"262", "values"=>{"0"=>"33333"}}}
167
195
  # }
168
196
  def set_field_values(datas = {})
169
- self.field_values.delete_all
170
197
  if datas.present?
171
- datas.each do |key, values|
172
- if values[:values].present?
173
- order_value = -1
174
- (values[:values].is_a?(Hash) ? values[:values].values : values[:values]).each do |value|
175
- item = self.field_values.create!({custom_field_id: values[:id], custom_field_slug: key, value: fix_meta_value(value), term_order: order_value += 1})
198
+ self.field_values.delete_all
199
+ datas.each do |index, fields_data|
200
+ fields_data.each do |field_key, values|
201
+ if values[:values].present?
202
+ order_value = -1
203
+ (values[:values].is_a?(Hash) ? values[:values].values : values[:values]).each do |value|
204
+ item = self.field_values.create!({custom_field_id: values[:id], custom_field_slug: field_key, value: fix_meta_value(value), term_order: order_value += 1, group_number: values[:group_number] || 0})
205
+ end
176
206
  end
177
207
  end
178
208
  end
179
209
  end
180
210
  end
181
211
 
182
- # return field object for current model
183
- def get_field_object(slug)
184
- CamaleonCms::CustomField.where(parent_id: get_field_groups.pluck(:id), slug: slug).first || CamaleonCms::CustomField.where(slug: slug, parent_id: get_field_groups({include_parent: true})).first
212
+ # update new value for field with slug _key
213
+ # Sample: my_posy.update_field_value('sub_title', 'Test Sub Title')
214
+ def update_field_value(_key, value = nil, group_number = 0)
215
+ self.field_values.where(custom_field_slug: _key, group_number: group_number).first.update_column('value', value) rescue nil
185
216
  end
186
217
 
187
- # clear and register values for this custom field
218
+ # Set custom field values for current model
188
219
  # key: slug of the custom field
189
220
  # value: array of values for multiple values support
190
221
  # value: string value
191
222
  def save_field_value(key, value, order = 0, clear = true)
192
- field = get_field_object(key)
193
- return unless field.present?
194
- self.field_values.where({custom_field_slug: key}).destroy_all if clear
223
+ set_field_value(key, value, {clear: clear, order: order})
224
+ end
225
+
226
+ # Set custom field values for current model (support for multiple group values)
227
+ # key: (string required) slug of the custom field
228
+ # value: (array | string) array: array of values for multiple values support, string: uniq value for the custom field
229
+ # args:
230
+ # field_id: (integer optional) identifier of the custom field
231
+ # order: order or position of the field value
232
+ # group_number: number of the group (only for custom field group with is_repeat enabled)
233
+ # clear: (boolean, default true) if true, will remove previous values and set these values, if not will append values
234
+ # return false if the was not saved because there is not present the field with slug: key
235
+ # sample: my_post.set_field_value('subtitle', 'Sub Title')
236
+ # sample: my_post.set_field_value('subtitle', ['Sub Title1', 'Sub Title2']) # set values for a field (for fields that support multiple values)
237
+ # sample: my_post.set_field_value('subtitle', 'Sub Title', {group_number: 1})
238
+ # sample: my_post.set_field_value('subtitle', 'Sub Title', {group_number: 1, group_number: 1}) # add field values for fields in group 1
239
+ def set_field_value(key, value, args = {})
240
+ args = {order: 0, group_number: 0, field_id: nil, clear: true}.merge(args)
241
+ args[:field_id] = get_field_object(key).id rescue nil unless args[:field_id].present?
242
+ return false unless args[:field_id].present?
243
+ self.field_values.where({custom_field_slug: key, group_number: args[:group_number]}).delete_all if args[:clear]
244
+ v = {custom_field_id: args[:field_id], custom_field_slug: key, value: fix_meta_value(value), term_order: args[:order], group_number: args[:group_number]}
195
245
  if value.is_a?(Array)
196
246
  value.each do |val|
197
- self.field_values.create!({custom_field_id: field.id, custom_field_slug: key, value: fix_meta_value(val), term_order: order})
247
+ self.field_values.create!(v.merge({value: fix_meta_value(val)}))
198
248
  end
199
249
  else
200
- self.field_values.create!({custom_field_id: field.id, custom_field_slug: key, value: fix_meta_value(value), term_order: order})
250
+ self.field_values.create!(v)
201
251
  end
202
252
  end
203
253
 
@@ -6,7 +6,7 @@ class CamaleonCmsAwsUploader < CamaleonCmsUploader
6
6
  bucket.objects.each do |file|
7
7
  cache_item(file_parse(file), objects)
8
8
  end
9
- @current_site.set_meta('cama_media_cache', objects)
9
+ @current_site.set_meta(cache_key, objects)
10
10
  objects
11
11
  end
12
12
 
@@ -1,4 +1,5 @@
1
1
  class CamaleonCmsLocalUploader < CamaleonCmsUploader
2
+ PRIVATE_DIRECTORY = 'private'
2
3
  def browser_files(prefix = '/', objects = {})
3
4
  objects[prefix] = {files: {}, folders: {}}
4
5
  path = File.join(@root_folder, prefix)
@@ -10,12 +11,27 @@ class CamaleonCmsLocalUploader < CamaleonCmsUploader
10
11
  cache_item(obj, objects)
11
12
  browser_files(File.join(prefix, obj['name']), objects) if obj['format'] == 'folder'
12
13
  end
13
- @current_site.set_meta('cama_media_cache', objects) if prefix == '/'
14
+ @current_site.set_meta(cache_key, objects) if prefix == '/'
14
15
  objects
15
16
  end
16
17
 
18
+ # return the full file path for private file with key
19
+ # sample: 'my_file.pdf' ==> /var/www/my_app/private/my_file.pdf
20
+ def self.private_file_path(key, current_site)
21
+ Rails.root.join(self::PRIVATE_DIRECTORY, current_site.id.to_s, key.gsub(/(\/){2,}/, "/")).to_s
22
+ end
23
+
24
+ # check if this uploader is private mode
25
+ def is_private_uploader?
26
+ @args[:private]
27
+ end
28
+
17
29
  def after_initialize
18
- @root_folder = @args[:root_folder] || @current_site.upload_directory
30
+ if is_private_uploader?
31
+ @root_folder = Rails.root.join(self.class::PRIVATE_DIRECTORY, @current_site.id.to_s).to_s
32
+ else
33
+ @root_folder = @args[:root_folder] || @current_site.upload_directory
34
+ end
19
35
  FileUtils.mkdir_p(@root_folder) unless Dir.exist?(@root_folder)
20
36
  end
21
37
 
@@ -25,7 +41,7 @@ class CamaleonCmsLocalUploader < CamaleonCmsUploader
25
41
  res = {
26
42
  "name" => File.basename(file_path),
27
43
  "key" => parse_key(file_path),
28
- "url" => is_dir ? '' : File.join(@current_site.the_url(locale: false), url_path),
44
+ "url" => is_dir ? '' : (is_private_uploader? ? url_path.sub("#{@root_folder}/", '') : File.join(@current_site.the_url(locale: false), url_path)),
29
45
  "is_folder" => is_dir,
30
46
  "size" => is_dir ? 0 : File.size(file_path).round(2),
31
47
  "format" => is_dir ? 'folder' : self.class.get_file_format(file_path),