camaleon_cms 2.1.2.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of camaleon_cms might be problematic. Click here for more details.

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),