camaleon_cms 2.9.1 → 2.9.3
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.
- checksums.yaml +4 -4
- data/README.md +29 -9
- data/Rakefile +3 -16
- data/app/apps/plugins/attack/admin_controller.rb +9 -6
- data/app/apps/plugins/attack/attack_helper.rb +35 -25
- data/app/apps/plugins/authoring_post/authoring_post_helper.rb +23 -16
- data/app/apps/plugins/front_cache/admin_controller.rb +16 -10
- data/app/apps/plugins/front_cache/config/initializer.rb +1 -1
- data/app/apps/plugins/front_cache/front_cache_helper.rb +57 -24
- data/app/apps/plugins/visibility_post/config/config.json +1 -0
- data/app/apps/plugins/visibility_post/config/routes_front.txt +1 -0
- data/app/apps/plugins/visibility_post/front_controller.rb +23 -0
- data/app/apps/plugins/visibility_post/visibility_post_helper.rb +141 -70
- data/app/apps/themes/camaleon_first/main_helper.rb +18 -12
- data/app/apps/themes/default/assets/css/style.css.scss +24 -0
- data/app/apps/themes/default/assets/genericons/genericons.css +3 -8
- data/app/apps/themes/default/default_helper.rb +2 -1
- data/app/apps/themes/default/views/category.html.erb +1 -1
- data/app/apps/themes/default/views/layouts/index.html.erb +3 -1
- data/app/apps/themes/default/views/post_tag.html.erb +1 -1
- data/app/apps/themes/default/views/post_type.html.erb +1 -1
- data/app/apps/themes/default/views/search.html.erb +1 -1
- data/app/apps/themes/new/assets/css/styles.css.scss +24 -0
- data/app/apps/themes/new/custom_helper.rb +5 -9
- data/app/apps/themes/new/views/category.html.erb +1 -1
- data/app/apps/themes/new/views/layouts/_header.html.erb +3 -1
- data/app/apps/themes/new/views/post_tag.html.erb +1 -1
- data/app/apps/themes/new/views/post_type.html.erb +1 -1
- data/app/apps/themes/new/views/search.html.erb +1 -1
- data/app/assets/javascripts/camaleon_cms/admin/_data.js +16 -0
- data/app/assets/javascripts/camaleon_cms/admin/_post.js +5 -2
- data/app/assets/javascripts/camaleon_cms/admin/nav_menu.js +14 -3
- data/app/assets/javascripts/camaleon_cms/admin/uploader/_media_manager.js +5 -0
- data/app/controllers/camaleon_cms/admin/appearances/nav_menus_controller.rb +29 -10
- data/app/controllers/camaleon_cms/admin/appearances/themes_controller.rb +8 -5
- data/app/controllers/camaleon_cms/admin/appearances/widgets/assign_controller.rb +9 -2
- data/app/controllers/camaleon_cms/admin/appearances/widgets/main_controller.rb +4 -3
- data/app/controllers/camaleon_cms/admin/appearances/widgets/sidebar_controller.rb +2 -2
- data/app/controllers/camaleon_cms/admin/categories_controller.rb +27 -8
- data/app/controllers/camaleon_cms/admin/comments_controller.rb +0 -1
- data/app/controllers/camaleon_cms/admin/installers_controller.rb +32 -1
- data/app/controllers/camaleon_cms/admin/media_controller.rb +84 -19
- data/app/controllers/camaleon_cms/admin/plugins_controller.rb +1 -3
- data/app/controllers/camaleon_cms/admin/post_tags_controller.rb +15 -6
- data/app/controllers/camaleon_cms/admin/posts/drafts_controller.rb +40 -11
- data/app/controllers/camaleon_cms/admin/posts_controller.rb +58 -22
- data/app/controllers/camaleon_cms/admin/sessions_controller.rb +238 -45
- data/app/controllers/camaleon_cms/admin/settings/custom_fields_controller.rb +103 -18
- data/app/controllers/camaleon_cms/admin/settings/post_types_controller.rb +17 -5
- data/app/controllers/camaleon_cms/admin/settings/sites_controller.rb +33 -7
- data/app/controllers/camaleon_cms/admin/settings_controller.rb +11 -6
- data/app/controllers/camaleon_cms/admin/user_roles_controller.rb +9 -7
- data/app/controllers/camaleon_cms/admin/users_controller.rb +89 -18
- data/app/controllers/camaleon_cms/admin_controller.rb +144 -26
- data/app/controllers/camaleon_cms/apps/plugins_admin_controller.rb +5 -0
- data/app/controllers/camaleon_cms/camaleon_controller.rb +37 -92
- data/app/controllers/camaleon_cms/frontend_controller.rb +140 -70
- data/app/controllers/concerns/camaleon_cms/admin/custom_fields_concern.rb +44 -0
- data/app/controllers/concerns/camaleon_cms/frontend_concern.rb +46 -17
- data/app/controllers/concerns/camaleon_cms/frontend_visited_state_concern.rb +72 -0
- data/app/controllers/concerns/camaleon_cms/hook_lifecycle_concern.rb +104 -0
- data/app/controllers/concerns/camaleon_cms/request_context_concern.rb +113 -0
- data/app/controllers/concerns/camaleon_cms/runtime_admin_menu_concern.rb +237 -0
- data/app/controllers/concerns/camaleon_cms/runtime_captcha_image_concern.rb +13 -0
- data/app/controllers/concerns/camaleon_cms/runtime_html_content_concern.rb +143 -0
- data/app/controllers/concerns/camaleon_cms/runtime_shortcode_theme_concern.rb +246 -0
- data/app/controllers/concerns/camaleon_cms/runtime_state_concern.rb +13 -0
- data/app/controllers/concerns/camaleon_cms/runtime_uploader_concern.rb +54 -0
- data/app/controllers/concerns/camaleon_cms/session_captcha_runtime_concern.rb +19 -0
- data/app/controllers/concerns/camaleon_cms/session_runtime_concern.rb +40 -0
- data/app/decorators/camaleon_cms/application_decorator.rb +11 -8
- data/app/decorators/camaleon_cms/category_decorator.rb +3 -2
- data/app/decorators/camaleon_cms/post_comment_decorator.rb +13 -5
- data/app/decorators/camaleon_cms/post_decorator.rb +67 -51
- data/app/decorators/camaleon_cms/post_type_decorator.rb +1 -1
- data/app/decorators/camaleon_cms/site_decorator.rb +29 -23
- data/app/decorators/camaleon_cms/term_taxonomy_decorator.rb +21 -10
- data/app/decorators/camaleon_cms/theme_decorator.rb +3 -3
- data/app/decorators/camaleon_cms/user_decorator.rb +26 -5
- data/app/helpers/camaleon_cms/admin/application_helper.rb +21 -24
- data/app/helpers/camaleon_cms/admin/breadcrumb_helper.rb +1 -1
- data/app/helpers/camaleon_cms/admin/custom_fields_helper.rb +24 -23
- data/app/helpers/camaleon_cms/admin/menus_helper.rb +249 -139
- data/app/helpers/camaleon_cms/admin/post_type_helper.rb +51 -31
- data/app/helpers/camaleon_cms/camaleon_helper.rb +31 -39
- data/app/helpers/camaleon_cms/captcha_helper.rb +73 -53
- data/app/helpers/camaleon_cms/comment_helper.rb +87 -41
- data/app/helpers/camaleon_cms/content_helper.rb +13 -6
- data/app/helpers/camaleon_cms/email_helper.rb +7 -3
- data/app/helpers/camaleon_cms/frontend/content_select_helper.rb +34 -20
- data/app/helpers/camaleon_cms/frontend/nav_menu_helper.rb +144 -67
- data/app/helpers/camaleon_cms/frontend/seo_helper.rb +39 -28
- data/app/helpers/camaleon_cms/frontend/site_helper.rb +32 -12
- data/app/helpers/camaleon_cms/hooks_helper.rb +14 -4
- data/app/helpers/camaleon_cms/html_helper.rb +73 -38
- data/app/helpers/camaleon_cms/plugins_helper.rb +23 -24
- data/app/helpers/camaleon_cms/session_helper.rb +195 -39
- data/app/helpers/camaleon_cms/short_code_helper.rb +181 -85
- data/app/helpers/camaleon_cms/site_helper.rb +43 -9
- data/app/helpers/camaleon_cms/theme_helper.rb +35 -19
- data/app/helpers/camaleon_cms/uploader_helper.rb +19 -422
- data/app/helpers/camaleon_cms/user_roles_helper.rb +5 -4
- data/app/mailers/camaleon_cms/html_mailer.rb +4 -4
- data/app/models/camaleon_cms/ability.rb +65 -105
- data/app/models/camaleon_cms/category.rb +7 -5
- data/app/models/camaleon_cms/custom_field.rb +29 -6
- data/app/models/camaleon_cms/custom_field_group.rb +75 -21
- data/app/models/camaleon_cms/custom_fields_relationship.rb +133 -2
- data/app/models/camaleon_cms/media.rb +8 -2
- data/app/models/camaleon_cms/meta.rb +2 -2
- data/app/models/camaleon_cms/nav_menu.rb +6 -2
- data/app/models/camaleon_cms/nav_menu_item.rb +18 -8
- data/app/models/camaleon_cms/plugin.rb +4 -3
- data/app/models/camaleon_cms/post.rb +113 -27
- data/app/models/camaleon_cms/post_comment.rb +10 -6
- data/app/models/camaleon_cms/post_default.rb +42 -12
- data/app/models/camaleon_cms/post_relationship.rb +6 -4
- data/app/models/camaleon_cms/post_tag.rb +4 -3
- data/app/models/camaleon_cms/post_type.rb +22 -12
- data/app/models/camaleon_cms/site.rb +40 -28
- data/app/models/camaleon_cms/term_relationship.rb +10 -7
- data/app/models/camaleon_cms/term_taxonomy.rb +51 -5
- data/app/models/camaleon_cms/theme.rb +3 -3
- data/app/models/camaleon_cms/user.rb +17 -5
- data/app/models/camaleon_cms/user_role.rb +77 -4
- data/app/models/camaleon_cms/widget/assigned.rb +11 -6
- data/app/models/camaleon_cms/widget/main.rb +13 -7
- data/app/models/camaleon_cms/widget/sidebar.rb +3 -6
- data/app/models/camaleon_record.rb +123 -5
- data/app/models/concerns/camaleon_cms/categories_tags_for_posts.rb +20 -38
- data/app/models/concerns/camaleon_cms/common_relationships.rb +18 -5
- data/app/models/concerns/camaleon_cms/custom_fields_read.rb +115 -58
- data/app/models/concerns/camaleon_cms/metas.rb +32 -7
- data/app/models/concerns/camaleon_cms/normalize_attrs.rb +2 -8
- data/app/models/concerns/camaleon_cms/site_default_settings.rb +120 -16
- data/app/models/concerns/camaleon_cms/user_methods.rb +44 -19
- data/app/models/current_request.rb +23 -0
- data/app/uploaders/camaleon_cms_aws_uploader.rb +39 -11
- data/app/uploaders/camaleon_cms_local_uploader.rb +76 -19
- data/app/uploaders/camaleon_cms_uploader.rb +23 -10
- data/app/validators/camaleon_cms/post_uniq_validator.rb +21 -8
- data/app/validators/camaleon_cms/uniq_validator.rb +1 -1
- data/app/validators/camaleon_cms/user_url_validator.rb +215 -36
- data/app/views/camaleon_cms/admin/appearances/nav_menus/_left_menu_items.html.erb +2 -2
- data/app/views/camaleon_cms/admin/appearances/widgets/main/form.html.erb +1 -1
- data/app/views/camaleon_cms/admin/categories/index.html.erb +3 -3
- data/app/views/camaleon_cms/admin/comments/index.html.erb +2 -2
- data/app/views/camaleon_cms/admin/comments/list.html.erb +1 -1
- data/app/views/camaleon_cms/admin/installers/form.html.erb +5 -0
- data/app/views/camaleon_cms/admin/installers/welcome.html.erb +30 -6
- data/app/views/camaleon_cms/admin/plugins/_plugins_list.html.erb +2 -2
- data/app/views/camaleon_cms/admin/post_tags/index.html.erb +3 -3
- data/app/views/camaleon_cms/admin/posts/_sidebar.html.erb +2 -2
- data/app/views/camaleon_cms/admin/posts/form.html.erb +3 -2
- data/app/views/camaleon_cms/admin/posts/index.html.erb +6 -6
- data/app/views/camaleon_cms/admin/search.html.erb +1 -1
- data/app/views/camaleon_cms/admin/sessions/back_to_parent.html.erb +39 -0
- data/app/views/camaleon_cms/admin/sessions/logout_confirm.html.erb +27 -0
- data/app/views/camaleon_cms/admin/settings/_email_settings.html.erb +4 -1
- data/app/views/camaleon_cms/admin/settings/custom_fields/_get_items.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/custom_fields/_render.html.erb +42 -6
- data/app/views/camaleon_cms/admin/settings/custom_fields/_render_category_simple.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_select_eval.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/custom_fields/form.html.erb +5 -4
- data/app/views/camaleon_cms/admin/settings/custom_fields/index.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/post_types/index.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/shortcodes.html.erb +4 -4
- data/app/views/camaleon_cms/admin/settings/site.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/sites/form.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/sites/index.html.erb +1 -1
- data/app/views/camaleon_cms/admin/user_roles/form.html.erb +102 -7
- data/app/views/camaleon_cms/admin/user_roles/index.html.erb +1 -1
- data/app/views/camaleon_cms/admin/users/form.html.erb +8 -4
- data/app/views/camaleon_cms/admin/users/index.html.erb +2 -2
- data/app/views/camaleon_cms/default_theme/partials/_render_custom_field.html.erb +8 -2
- data/app/views/camaleon_cms/default_theme/sitemap.html.erb +1 -1
- data/app/views/camaleon_cms/default_theme/sitemap.xml.builder +1 -1
- data/app/views/layouts/camaleon_cms/admin/_flash_messages.html.erb +2 -2
- data/app/views/layouts/camaleon_cms/admin/_header.html.erb +1 -1
- data/config/initializers/action_view.rb +42 -5
- data/config/initializers/active_record_extension.rb +13 -27
- data/config/initializers/assets.rb +52 -23
- data/config/initializers/custom_initializers.rb +3 -3
- data/config/locales/camaleon_cms/admin/ar.yml +7 -2
- data/config/locales/camaleon_cms/admin/de.yml +7 -2
- data/config/locales/camaleon_cms/admin/en.yml +39 -2
- data/config/locales/camaleon_cms/admin/es.yml +7 -2
- data/config/locales/camaleon_cms/admin/fr.yml +7 -2
- data/config/locales/camaleon_cms/admin/it.yml +7 -2
- data/config/locales/camaleon_cms/admin/nl.yml +8 -2
- data/config/locales/camaleon_cms/admin/pt-BR.yml +7 -2
- data/config/locales/camaleon_cms/admin/pt.yml +7 -2
- data/config/locales/camaleon_cms/admin/ru.yml +7 -2
- data/config/locales/camaleon_cms/admin/uk.yml +7 -2
- data/config/locales/camaleon_cms/admin/zh-CH.yml +7 -2
- data/config/routes/admin.rb +33 -15
- data/config/routes/frontend.rb +21 -15
- data/db/migrate/20150611161134_post_table_into_utf8.rb +14 -14
- data/db/migrate/20150926095310_rename_column_posts.rb +3 -3
- data/db/migrate/20151212095328_add_confirm_token_to_users.rb +3 -3
- data/db/migrate/20160504155652_add_feature_to_posts.rb +1 -1
- data/db/migrate/20160504155653_move_first_name_of_users.rb +2 -2
- data/db/migrate/20160609121449_add_group_to_custom_field_values.rb +1 -1
- data/db/migrate/20161215202255_drop_user_relationship_table.rb +1 -1
- data/db/migrate/20180124132318_create_media.rb +1 -1
- data/db/migrate/20180704211100_adjust_field_length.rb +1 -1
- data/lib/camaleon_cms/assets_precompile.rb +86 -0
- data/lib/camaleon_cms/captcha_image_generation.rb +65 -0
- data/lib/camaleon_cms/content_security.rb +158 -0
- data/lib/camaleon_cms/engine.rb +47 -9
- data/lib/camaleon_cms/media_security_headers.rb +27 -0
- data/lib/camaleon_cms/setup_token.rb +69 -0
- data/lib/camaleon_cms/svg_content_checker.rb +123 -0
- data/lib/camaleon_cms/task_reporter.rb +14 -0
- data/lib/camaleon_cms/unsafe_markup.rb +207 -0
- data/lib/camaleon_cms/uploader_content_security.rb +248 -0
- data/lib/camaleon_cms/uploader_image_processing.rb +166 -0
- data/lib/camaleon_cms/uploader_path_security.rb +146 -0
- data/lib/camaleon_cms/uploader_pipeline.rb +350 -0
- data/lib/camaleon_cms/uploader_support.rb +86 -0
- data/lib/camaleon_cms/version.rb +1 -1
- data/lib/camaleon_cms.rb +11 -0
- data/lib/ext/hash.rb +28 -2
- data/lib/ext/string.rb +13 -8
- data/lib/ext/translator.rb +10 -2
- data/lib/generators/camaleon_cms/gem_plugin_template/app/controllers/plugins/my_plugin/admin_controller.rb +5 -1
- data/lib/generators/camaleon_cms/install_generator.rb +7 -4
- data/lib/generators/camaleon_cms/install_template/plugin_routes.rb +5 -12
- data/lib/generators/camaleon_cms/theme_generator.rb +5 -10
- data/lib/generators/camaleon_cms/theme_template/views/layouts/index.html.erb +3 -1
- data/lib/plugin_routes.rb +412 -368
- data/lib/tasks/camaleon_cms/camaleon_tasks.rake +2 -1
- data/lib/tasks/cross_site_field_groups.rake +74 -0
- data/lib/tasks/custom_fields_roles.rake +58 -0
- data/lib/tasks/orphaned_comments.rake +42 -0
- data/lib/tasks/private_upload_acls.rake +31 -0
- data/lib/tasks/site_custom_field_groups.rake +36 -0
- data/lib/tasks/unsafe_stored_content.rake +42 -0
- data/lib/tasks/unsafe_stored_uploads.rake +70 -0
- data/lib/tasks/user_field_groups.rake +27 -0
- metadata +185 -7
|
@@ -24,7 +24,7 @@ module CamaleonCms
|
|
|
24
24
|
# update category assignations for this post
|
|
25
25
|
# remove assignations that no longer exist
|
|
26
26
|
# add new assignations
|
|
27
|
-
# cats: (Array) array of category ids assigned for this post, sample: [1,2,3]
|
|
27
|
+
# cats: (Array) array of category ids assigned for this post, sample: [1, 2, 3]
|
|
28
28
|
def update_categories(cats = [])
|
|
29
29
|
rescue_extra_data
|
|
30
30
|
cats = cats.to_i
|
|
@@ -35,7 +35,7 @@ module CamaleonCms
|
|
|
35
35
|
news_categories.each do |key|
|
|
36
36
|
term_relationships.create(term_taxonomy_id: key)
|
|
37
37
|
end
|
|
38
|
-
|
|
38
|
+
update_counts('categories')
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
# update tags assignations for this post
|
|
@@ -53,7 +53,7 @@ module CamaleonCms
|
|
|
53
53
|
post_tag = post_type.post_tags.where({ name: f }).first_or_create(slug: f.parameterize)
|
|
54
54
|
term_relationships.where({ term_taxonomy_id: post_tag.id }).first_or_create
|
|
55
55
|
end
|
|
56
|
-
|
|
56
|
+
update_counts('tags')
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
# Assign this post for category with id: category_id
|
|
@@ -64,43 +64,25 @@ module CamaleonCms
|
|
|
64
64
|
categories_id.each do |key|
|
|
65
65
|
term_relationships.where(term_taxonomy_id: key).first_or_create!
|
|
66
66
|
end
|
|
67
|
-
|
|
67
|
+
update_counts('categories')
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
-
#
|
|
71
|
-
# categories_id: (Array) array of category ids
|
|
70
|
+
# Unassign this post from categories with ids: categories_id
|
|
71
|
+
# categories_id: (Array) array of category ids to unassign from this post, sample: [1,2,3]
|
|
72
72
|
def unassign_category(categories_id)
|
|
73
73
|
categories_id = [categories_id] if categories_id.is_a?(Integer)
|
|
74
|
+
# a loaded (stale) categories association would hide the removed ids from the
|
|
75
|
+
# counter refresh below — check_default_category loads it on every save
|
|
76
|
+
categories.reset
|
|
74
77
|
rescue_extra_data
|
|
75
78
|
term_relationships.where(term_taxonomy_id: categories_id).destroy_all
|
|
76
|
-
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# Assign new tags to this post
|
|
80
|
-
# tags_title: (String) tags name separated by commas, sample: "Tag1,Tag two,tag new"
|
|
81
|
-
def assign_tags(tag_titles)
|
|
82
|
-
update_counters_before
|
|
83
|
-
tags = tag_titles.split(',').strip
|
|
84
|
-
tags.each do |t|
|
|
85
|
-
post_tag = post_type.post_tags.where(name: t).first_or_create!
|
|
86
|
-
term_relationships.where({ term_taxonomy_id: post_tag.id }).first_or_create!
|
|
87
|
-
end
|
|
88
|
-
update_counters('tags')
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
# Unassign tags from this post
|
|
92
|
-
# tags_title: (String) tags name separated by commas, sample: "Tag1,Tag two,tag new"
|
|
93
|
-
def unassign_tags(tag_titles)
|
|
94
|
-
update_counters_before
|
|
95
|
-
tags = tag_titles.split(',').strip
|
|
96
|
-
term_relationships.where({ term_taxonomy_id: post_type.post_tags.where(name: tags).pluck(:id) }).destroy_all
|
|
97
|
-
update_counters('tags')
|
|
79
|
+
update_counts('categories')
|
|
98
80
|
end
|
|
99
81
|
|
|
100
|
-
#
|
|
82
|
+
# Update the quantity of posts assigned for tags and categories assigned to this post
|
|
101
83
|
def update_extra_data
|
|
102
84
|
rescue_extra_data
|
|
103
|
-
|
|
85
|
+
update_counts
|
|
104
86
|
end
|
|
105
87
|
|
|
106
88
|
private
|
|
@@ -113,23 +95,23 @@ module CamaleonCms
|
|
|
113
95
|
@tags_before = post_tags.pluck(:id) if manage_tags?
|
|
114
96
|
end
|
|
115
97
|
|
|
116
|
-
#
|
|
98
|
+
# Update the quantity of posts assigned for tags and categories assigned to this post
|
|
117
99
|
# if kind is empty, then this will update both: cats and tags
|
|
118
100
|
# kind: (string) tags | categories
|
|
119
|
-
def
|
|
101
|
+
def update_counts(kind = '')
|
|
120
102
|
if ['', 'categories'].include?(kind) && manage_categories?
|
|
121
|
-
post_type.full_categories.where(id: (@cats_before + categories.pluck(:id)).uniq).
|
|
122
|
-
c.update_column(
|
|
103
|
+
post_type.full_categories.where(id: (@cats_before + categories.pluck(:id)).uniq).find_each do |c|
|
|
104
|
+
c.update_column(:count, c.posts.published.size) # rubocop:disable Rails/SkipsModelValidations
|
|
123
105
|
end
|
|
124
106
|
end
|
|
125
107
|
return unless ['', 'tags'].include?(kind) && manage_tags?
|
|
126
108
|
|
|
127
|
-
post_type.post_tags.where(id: (@tags_before + post_tags.pluck(:id)).uniq).
|
|
128
|
-
tag.update_column(
|
|
109
|
+
post_type.post_tags.where(id: (@tags_before + post_tags.pluck(:id)).uniq).find_each do |tag|
|
|
110
|
+
tag.update_column(:count, tag.posts.published.size) # rubocop:disable Rails/SkipsModelValidations
|
|
129
111
|
end
|
|
130
112
|
end
|
|
131
113
|
|
|
132
|
-
#
|
|
114
|
+
# Save extra data such as categories and tags assigned to this post
|
|
133
115
|
def save_extra_data
|
|
134
116
|
update_categories(data_categories) if manage_categories? && !data_categories.nil?
|
|
135
117
|
update_tags(data_tags) if manage_tags? && !data_tags.nil?
|
|
@@ -139,7 +121,7 @@ module CamaleonCms
|
|
|
139
121
|
def check_default_category
|
|
140
122
|
return unless manage_categories?
|
|
141
123
|
|
|
142
|
-
assign_category([post_type.default_category.id])
|
|
124
|
+
assign_category([post_type.default_category.id]) if categories.blank?
|
|
143
125
|
end
|
|
144
126
|
end
|
|
145
127
|
end
|
|
@@ -3,22 +3,35 @@
|
|
|
3
3
|
module CamaleonCms
|
|
4
4
|
module CommonRelationships
|
|
5
5
|
extend ActiveSupport::Concern
|
|
6
|
+
# rubocop:disable Rails/InverseOf
|
|
6
7
|
|
|
7
8
|
included do
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
# Scopes use the demodulized class name (the 2.9.2 contract every install's rows were
|
|
10
|
+
# written under): 'Post', 'Main' for Widget::Main, and 'User' for a host Admin::User.
|
|
11
|
+
# to_s tolerates anonymous subclasses (STI specs build them), whose name is nil.
|
|
12
|
+
object_class_name = name.to_s.demodulize
|
|
13
|
+
has_many :metas, -> { where(object_class: object_class_name) },
|
|
10
14
|
class_name: 'CamaleonCms::Meta', foreign_key: :objectid, dependent: :destroy
|
|
11
15
|
|
|
12
|
-
has_many :custom_field_values, -> { where(object_class:
|
|
16
|
+
has_many :custom_field_values, -> { where(object_class: object_class_name) },
|
|
13
17
|
class_name: 'CamaleonCms::CustomFieldsRelationship', foreign_key: :objectid, dependent: :delete_all
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
# No dependent: on the definition associations (2.9.2 behavior). Teardown is owned by
|
|
20
|
+
# CustomFieldsRead#_destroy_custom_field_groups, which runs first and destroys groups WITH
|
|
21
|
+
# callbacks; a dependent here is inert at best, and on hook-less includers (PostComment) a
|
|
22
|
+
# delete_all removed group rows while orphaning their fields and option metas. A :destroy
|
|
23
|
+
# cascade is no alternative: custom_fields matches group rows too (same table, same scope)
|
|
24
|
+
# but its CustomField typing would skip group teardown.
|
|
25
|
+
# rubocop:disable Rails/HasManyOrHasOneDependent
|
|
26
|
+
has_many :custom_fields, -> { where(object_class: object_class_name) },
|
|
16
27
|
class_name: 'CamaleonCms::CustomField', foreign_key: :objectid
|
|
17
28
|
|
|
18
29
|
# valid only for simple groups and not for complex like: posts, post, ... where the group is for individual or
|
|
19
30
|
# children groups
|
|
20
|
-
has_many :custom_field_groups, -> { where(object_class:
|
|
31
|
+
has_many :custom_field_groups, -> { where(object_class: object_class_name) },
|
|
21
32
|
class_name: 'CamaleonCms::CustomFieldGroup', foreign_key: :objectid
|
|
33
|
+
# rubocop:enable Rails/HasManyOrHasOneDependent
|
|
22
34
|
end
|
|
35
|
+
# rubocop:enable Rails/InverseOf
|
|
23
36
|
end
|
|
24
37
|
end
|
|
@@ -35,21 +35,29 @@ module CamaleonCms
|
|
|
35
35
|
when 'Post'
|
|
36
36
|
if term_relationships.empty? && args[:cat_ids].nil?
|
|
37
37
|
CamaleonCms::CustomFieldGroup.where(
|
|
38
|
-
'(objectid = ? AND object_class = ?) OR (objectid = ? AND object_class = ?)',
|
|
38
|
+
'(objectid = ? AND object_class = ?) OR (objectid = ? AND object_class = ?)',
|
|
39
|
+
id || -1, class_name, post_type.id, "PostType_#{class_name}"
|
|
39
40
|
)
|
|
40
41
|
else
|
|
41
42
|
cat_ids = categories.map(&:id)
|
|
42
43
|
cat_ids += args[:cat_ids] unless args[:cat_ids].nil?
|
|
43
44
|
cat_ids += CamaleonCms::Category.find(cat_ids).map { |category| _category_parents_ids(category) }.flatten.uniq
|
|
44
|
-
CamaleonCms::CustomFieldGroup.where(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
CamaleonCms::CustomFieldGroup.where(
|
|
46
|
+
"(objectid = ? AND object_class = ?) OR
|
|
47
|
+
(objectid = ? AND object_class = ?) OR
|
|
48
|
+
(objectid IN (?) AND object_class = ?)",
|
|
49
|
+
id || -1, class_name, post_type.id, "PostType_#{class_name}", cat_ids, "Category_#{class_name}"
|
|
50
|
+
)
|
|
50
51
|
end
|
|
51
52
|
when 'NavMenuItem'
|
|
52
53
|
main_menu.custom_field_groups
|
|
54
|
+
when 'Site'
|
|
55
|
+
# Site overrides `custom_field_groups` to mean "every group this site owns" (foreign key
|
|
56
|
+
# parent_id), unlike the object_class + objectid association every other model receives from
|
|
57
|
+
# CommonRelationships. Scoping by placement here keeps groups meant for post types, themes or
|
|
58
|
+
# menus off the site settings form, where their required fields blocked the submit and their
|
|
59
|
+
# values were discarded on save anyway.
|
|
60
|
+
custom_field_groups.where(object_class: 'Site', objectid: id)
|
|
53
61
|
when 'PostType'
|
|
54
62
|
case args[:kind]
|
|
55
63
|
when 'all'
|
|
@@ -69,7 +77,9 @@ module CamaleonCms
|
|
|
69
77
|
# return collections CustomFieldGroup
|
|
70
78
|
# site: site object
|
|
71
79
|
def get_user_field_groups(site)
|
|
72
|
-
|
|
80
|
+
# Demodulized to match the association scope and the placement the settings form stores
|
|
81
|
+
# ('User' for a host Admin::User); parseCamaClass still strips a Draper Decorator suffix.
|
|
82
|
+
site.custom_field_groups.where(object_class: self.class.to_s.parseCamaClass.demodulize)
|
|
73
83
|
end
|
|
74
84
|
|
|
75
85
|
# get custom field value
|
|
@@ -82,7 +92,7 @@ module CamaleonCms
|
|
|
82
92
|
rescue StandardError
|
|
83
93
|
_default
|
|
84
94
|
end
|
|
85
|
-
v.
|
|
95
|
+
v.presence || _default
|
|
86
96
|
end
|
|
87
97
|
alias get_field get_field_value
|
|
88
98
|
alias get_field! get_field_value
|
|
@@ -117,12 +127,12 @@ module CamaleonCms
|
|
|
117
127
|
# puts res[0]['my_slug1'].first ==> "val 1"
|
|
118
128
|
def get_fields_grouped(field_keys)
|
|
119
129
|
res = []
|
|
120
|
-
custom_field_values.where(custom_field_slug: field_keys)
|
|
121
|
-
|
|
122
|
-
field_keys.
|
|
123
|
-
_tmp =
|
|
124
|
-
|
|
125
|
-
|
|
130
|
+
custom_field_values.where(custom_field_slug: field_keys)
|
|
131
|
+
.order(group_number: :asc).group_by(&:group_number).each_value do |group_fields|
|
|
132
|
+
group = field_keys.each_with_object({}) do |field_key, hsh|
|
|
133
|
+
_tmp = group_fields
|
|
134
|
+
.each_with_object([]) { |field, ary| ary << field.value if field_key == field.custom_field_slug }
|
|
135
|
+
hsh[field_key] = _tmp if _tmp.present?
|
|
126
136
|
end
|
|
127
137
|
res << group
|
|
128
138
|
end
|
|
@@ -131,11 +141,12 @@ module CamaleonCms
|
|
|
131
141
|
|
|
132
142
|
# return all values
|
|
133
143
|
# {key1: "single value", key2: [multiple, values], key3: value4} if include_options = false
|
|
134
|
-
# {key1: {values: "single value", options: {a:1, b: 4}}, key2: {values: [multiple, values], options: {a=1, b=2} }}
|
|
144
|
+
# {key1: {values: "single value", options: {a:1, b: 4}}, key2: {values: [multiple, values], options: {a=1, b=2} }}
|
|
145
|
+
# if include_options = true
|
|
135
146
|
def get_field_values_hash(include_options = false)
|
|
136
147
|
fields = {}
|
|
137
148
|
custom_field_values.to_a.uniq.each do |field_value|
|
|
138
|
-
custom_field = field_value.
|
|
149
|
+
custom_field = field_value.custom_field
|
|
139
150
|
values = custom_field.values.where(objectid: id).pluck(:value)
|
|
140
151
|
unless include_options
|
|
141
152
|
fields[field_value.custom_field_slug] =
|
|
@@ -155,13 +166,14 @@ module CamaleonCms
|
|
|
155
166
|
# deprecated f attribute
|
|
156
167
|
def get_fields_object(_f = true)
|
|
157
168
|
fields = {}
|
|
158
|
-
custom_field_values.eager_load(:
|
|
159
|
-
custom_field = field_value.
|
|
169
|
+
custom_field_values.eager_load(:custom_field).to_a.uniq.each do |field_value|
|
|
170
|
+
custom_field = field_value.custom_field
|
|
160
171
|
# if custom_field.options[:show_frontend].to_s.to_bool
|
|
161
172
|
values = custom_field.values.where(objectid: id).pluck(:value)
|
|
162
|
-
fields[field_value.custom_field_slug] =
|
|
163
|
-
|
|
164
|
-
|
|
173
|
+
fields[field_value.custom_field_slug] = custom_field.attributes.merge(
|
|
174
|
+
options: custom_field.cama_options,
|
|
175
|
+
values: custom_field.cama_options[:multiple].to_s.to_bool ? values : values.first
|
|
176
|
+
)
|
|
165
177
|
# end
|
|
166
178
|
end
|
|
167
179
|
fields.to_sym
|
|
@@ -179,10 +191,11 @@ module CamaleonCms
|
|
|
179
191
|
# post_type.add_custom_field_group(values, kind = "Category")
|
|
180
192
|
# Note 2: If you need add fields for only the Post_type, you have to use options or metas
|
|
181
193
|
# return: CustomFieldGroup object
|
|
182
|
-
# kind: argument only for PostType model: (Post | Category | PostTag), default => Post.
|
|
194
|
+
# kind: argument only for PostType model: (Post | Category | PostTag), default => Post.
|
|
195
|
+
# If kind = "" this will add group for all post_types
|
|
183
196
|
def add_custom_field_group(values, kind = 'Post')
|
|
184
197
|
values = values.with_indifferent_access
|
|
185
|
-
group = get_field_groups(kind).
|
|
198
|
+
group = get_field_groups(kind).find_by_slug(values[:slug]) # rubocop:disable Rails/DynamicFindBy
|
|
186
199
|
unless group
|
|
187
200
|
site = _cama_get_field_site
|
|
188
201
|
values[:parent_id] = site.id if site.present?
|
|
@@ -202,7 +215,7 @@ module CamaleonCms
|
|
|
202
215
|
# more details in add_manual_field(item, options) from custom field groups
|
|
203
216
|
# kind: argument only for PostType model: (Post | Category | PostTag), default => Post
|
|
204
217
|
def add_custom_field_to_default_group(item, options, kind = 'Post')
|
|
205
|
-
g = get_field_groups(kind).
|
|
218
|
+
g = get_field_groups(kind).find_by_slug('_default') # rubocop:disable Rails/DynamicFindBy
|
|
206
219
|
g ||= add_custom_field_group({ name: 'Default Field Group', slug: '_default' }, kind)
|
|
207
220
|
g.add_manual_field(item, options)
|
|
208
221
|
end
|
|
@@ -210,13 +223,8 @@ module CamaleonCms
|
|
|
210
223
|
|
|
211
224
|
# return field object for current model
|
|
212
225
|
def get_field_object(slug)
|
|
213
|
-
CamaleonCms::CustomField.where(
|
|
214
|
-
slug: slug,
|
|
215
|
-
parent_id: get_field_groups.pluck(:id)
|
|
216
|
-
).first || CamaleonCms::CustomField.where(
|
|
217
|
-
slug: slug,
|
|
218
|
-
parent_id: get_field_groups({ include_parent: true })
|
|
219
|
-
).first
|
|
226
|
+
CamaleonCms::CustomField.where(slug: slug, parent_id: get_field_groups.pluck(:id)).first ||
|
|
227
|
+
CamaleonCms::CustomField.where(slug: slug, parent_id: get_field_groups({ include_parent: true })).first
|
|
220
228
|
end
|
|
221
229
|
|
|
222
230
|
# save all fields sent from browser (reservated for browser request)
|
|
@@ -226,28 +234,57 @@ module CamaleonCms
|
|
|
226
234
|
# "1"=>{ "untitled-text-box"=>{"id"=>"262", "values"=>{"0"=>"33333"}}}
|
|
227
235
|
# }
|
|
228
236
|
def set_field_values(datas = {})
|
|
229
|
-
return
|
|
237
|
+
return if datas.blank?
|
|
230
238
|
|
|
231
239
|
ActiveRecord::Base.transaction do
|
|
240
|
+
# A value identical to one already stored is not newly authored, so it must not be re-gated on
|
|
241
|
+
# an unrelated edit (audit M8): the admin form round-trips every value and this method
|
|
242
|
+
# delete/recreates them all, so without this skip a single pre-gate dangerous value would fail
|
|
243
|
+
# the whole save and brick every later edit -- the trap Post#reject_untrusted_dangerous_content
|
|
244
|
+
# avoids via content_changed?. Snapshot the stored pairs before clearing; skip the gate for any
|
|
245
|
+
# recreated value that matches one.
|
|
246
|
+
previously_stored = custom_field_values.pluck(:custom_field_slug, :value).to_set
|
|
232
247
|
custom_field_values.delete_all
|
|
233
248
|
datas.each_value do |fields_data|
|
|
234
249
|
fields_data.each do |field_key, values|
|
|
235
|
-
next
|
|
250
|
+
next if values[:values].blank?
|
|
251
|
+
|
|
252
|
+
# Resolve the field id from the trusted slug, not the client-supplied values[:id]: a
|
|
253
|
+
# forged custom_field_id points the row at a different field definition, and the
|
|
254
|
+
# scan-and-reject gate keys off custom_field.options[:field_key] -- so a forged non-gated
|
|
255
|
+
# id would slip markup past the gate for a gated (editor/uri/field_attrs) slug. Fall back
|
|
256
|
+
# to values[:id] only when the slug names no field here (trusted/internal callers that
|
|
257
|
+
# pass slugs outside this object's registered groups; permitted browser payloads never do).
|
|
258
|
+
field_id = get_field_object(field_key)&.id || fallback_field_id_for(field_key) || values[:id]
|
|
259
|
+
group_number = [values[:group_number].to_i, 0].max
|
|
236
260
|
|
|
237
261
|
order_value = -1
|
|
238
|
-
(
|
|
239
|
-
|
|
240
|
-
|
|
262
|
+
(
|
|
263
|
+
if values[:values].is_a?(Hash) || values[:values].is_a?(ActionController::Parameters)
|
|
264
|
+
values[:values].values
|
|
265
|
+
else
|
|
266
|
+
values[:values]
|
|
267
|
+
end
|
|
268
|
+
).each do |value|
|
|
269
|
+
row = custom_field_values.new(
|
|
270
|
+
custom_field_id: field_id, custom_field_slug: field_key,
|
|
271
|
+
value: fix_meta_value(value), term_order: order_value += 1, group_number: group_number
|
|
272
|
+
)
|
|
273
|
+
row.unfiltered_value! if previously_stored.include?([field_key.to_s, row.value])
|
|
274
|
+
row.save!
|
|
241
275
|
end
|
|
242
276
|
end
|
|
243
277
|
end
|
|
244
278
|
end
|
|
245
279
|
end
|
|
246
280
|
|
|
247
|
-
#
|
|
281
|
+
# Update the value for the field with slug _key
|
|
248
282
|
# Sample: my_posy.update_field_value('sub_title', 'Test Sub Title')
|
|
249
|
-
def update_field_value(
|
|
250
|
-
|
|
283
|
+
def update_field_value(key, value = nil, group_number = 0)
|
|
284
|
+
# Route through validations so the scan-and-reject gate applies (audit M5): update_column
|
|
285
|
+
# skipped it, letting a dangerous value an untrusted caller supplies reach the frontend verbatim.
|
|
286
|
+
custom_field_values.find_by(custom_field_slug: key, group_number: group_number)
|
|
287
|
+
&.update(value: value)
|
|
251
288
|
rescue StandardError
|
|
252
289
|
nil
|
|
253
290
|
end
|
|
@@ -262,48 +299,68 @@ module CamaleonCms
|
|
|
262
299
|
|
|
263
300
|
# Set custom field values for current model (support for multiple group values)
|
|
264
301
|
# key: (string required) slug of the custom field
|
|
265
|
-
# value: (array | string) array: array of values for multiple values support,
|
|
302
|
+
# value: (array | string) array: array of values for multiple values support,
|
|
303
|
+
# string: uniq value for the custom field
|
|
266
304
|
# args:
|
|
267
305
|
# field_id: (integer optional) identifier of the custom field
|
|
268
306
|
# order: order or position of the field value
|
|
269
307
|
# group_number: number of the group (only for custom field group with is_repeat enabled)
|
|
270
|
-
# clear: (boolean, default true) if true, will remove previous values and set these values,
|
|
308
|
+
# clear: (boolean, default true) if true, will remove previous values and set these values,
|
|
309
|
+
# if not will append values
|
|
271
310
|
# return false if the was not saved because there is not present the field with slug: key
|
|
272
311
|
# sample: my_post.set_field_value('subtitle', 'Sub Title')
|
|
273
|
-
# sample:
|
|
312
|
+
# sample: set values for a field (for fields that support multiple values)
|
|
313
|
+
# my_post.set_field_value('subtitle', ['Sub Title1', 'Sub Title2'])
|
|
274
314
|
# sample: my_post.set_field_value('subtitle', 'Sub Title', {group_number: 1})
|
|
275
|
-
# sample:
|
|
315
|
+
# sample: add field values for fields in group 1
|
|
316
|
+
# my_post.set_field_value('subtitle', 'Sub Title', {group_number: 1, group_number: 1})
|
|
276
317
|
def set_field_value(key, value, args = {})
|
|
277
318
|
args = { order: 0, group_number: 0, field_id: nil, clear: true }.merge!(args)
|
|
278
|
-
|
|
319
|
+
if args[:field_id].blank?
|
|
279
320
|
args[:field_id] = begin
|
|
280
321
|
get_field_object(key).id
|
|
281
322
|
rescue StandardError
|
|
282
323
|
nil
|
|
283
324
|
end
|
|
284
325
|
end
|
|
285
|
-
|
|
326
|
+
args[:field_id] ||= fallback_field_id_for(key)
|
|
286
327
|
|
|
287
|
-
if args[:
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
328
|
+
raise ArgumentError, "There is no custom field configured for #{key}" if args[:field_id].blank?
|
|
329
|
+
|
|
330
|
+
v = {
|
|
331
|
+
custom_field_id: args[:field_id], custom_field_slug: key, value: fix_meta_value(value),
|
|
332
|
+
term_order: args[:order], group_number: args[:group_number]
|
|
333
|
+
}
|
|
334
|
+
# Atomic (audit M7): clear the previous value and write the new one in one transaction, so a
|
|
335
|
+
# value the scan-and-reject gate refuses (create! -> RecordInvalid) rolls the delete back and
|
|
336
|
+
# the previously stored value survives instead of being destroyed.
|
|
337
|
+
ActiveRecord::Base.transaction do
|
|
338
|
+
if args[:clear]
|
|
339
|
+
custom_field_values.where({ custom_field_slug: key, group_number: args[:group_number] }).delete_all
|
|
340
|
+
end
|
|
341
|
+
if value.is_a?(Array)
|
|
342
|
+
value.each { |val| custom_field_values.create!(v.merge({ value: fix_meta_value(val) })) }
|
|
343
|
+
else
|
|
344
|
+
custom_field_values.create!(v)
|
|
296
345
|
end
|
|
297
|
-
else
|
|
298
|
-
custom_field_values.create!(v)
|
|
299
346
|
end
|
|
300
347
|
end
|
|
301
348
|
|
|
302
349
|
private
|
|
303
350
|
|
|
351
|
+
def fallback_field_id_for(key)
|
|
352
|
+
return unless self.class.to_s.parseCamaClass == 'Post'
|
|
353
|
+
return unless respond_to?(:post_type_id) && post_type_id.present?
|
|
354
|
+
|
|
355
|
+
group_ids = CamaleonCms::CustomFieldGroup.where(object_class: 'PostType_Post', objectid: post_type_id).pluck(:id)
|
|
356
|
+
return if group_ids.blank?
|
|
357
|
+
|
|
358
|
+
CamaleonCms::CustomField.where(slug: key, parent_id: group_ids).pick(:id)
|
|
359
|
+
end
|
|
360
|
+
|
|
304
361
|
def fix_meta_value(value)
|
|
305
362
|
return value.to_json if value.is_a?(ActionController::Parameters)
|
|
306
|
-
return JSON.
|
|
363
|
+
return JSON.generate(value) if value.is_a?(Array) || value.is_a?(Hash)
|
|
307
364
|
|
|
308
365
|
value
|
|
309
366
|
end
|
|
@@ -14,7 +14,25 @@ module CamaleonCms
|
|
|
14
14
|
# Add meta with value or Update meta with key: key
|
|
15
15
|
# return true or false
|
|
16
16
|
def set_meta(key, value)
|
|
17
|
-
|
|
17
|
+
fixed_value = fix_meta_value(value)
|
|
18
|
+
|
|
19
|
+
# Check if the parent object has been saved to the database yet
|
|
20
|
+
if persisted?
|
|
21
|
+
# Safe to use database-driven lookups and updates
|
|
22
|
+
meta_record = metas.find_or_create_by(key: key.to_s)
|
|
23
|
+
meta_record.update(value: fixed_value)
|
|
24
|
+
else
|
|
25
|
+
# In-Memory Fallback: Find an existing unsaved item in the array collection,
|
|
26
|
+
# or build a brand new unsaved record on the association.
|
|
27
|
+
meta_record = metas.find { |m| m.key == key.to_s }
|
|
28
|
+
|
|
29
|
+
if meta_record
|
|
30
|
+
meta_record.value = fixed_value
|
|
31
|
+
else
|
|
32
|
+
metas.build(key: key.to_s, value: fixed_value)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
18
36
|
cama_set_cache("meta_#{key}", value)
|
|
19
37
|
end
|
|
20
38
|
|
|
@@ -23,7 +41,7 @@ module CamaleonCms
|
|
|
23
41
|
def get_meta(key, default = nil)
|
|
24
42
|
key_str = key.is_a?(Symbol) ? key.to_s : key
|
|
25
43
|
cama_fetch_cache("meta_#{key_str}") do
|
|
26
|
-
option = metas.loaded? ? metas.
|
|
44
|
+
option = metas.loaded? ? metas.find { |m| m.key == key_str } : metas.where(key: key_str).first
|
|
27
45
|
res = ''
|
|
28
46
|
if option.present?
|
|
29
47
|
value = begin
|
|
@@ -73,12 +91,16 @@ module CamaleonCms
|
|
|
73
91
|
# return value for attribute
|
|
74
92
|
def get_option(key = nil, default = nil, meta_key = '_default')
|
|
75
93
|
values = cama_options(meta_key)
|
|
94
|
+
return default if key.nil?
|
|
95
|
+
|
|
76
96
|
key = key.to_sym
|
|
77
97
|
values.key?(key) && values[key] != '' ? values[key] : default
|
|
78
98
|
end
|
|
79
99
|
|
|
80
100
|
# delete attribute from configuration
|
|
81
101
|
def delete_option(key, meta_key = '_default')
|
|
102
|
+
return if key.nil?
|
|
103
|
+
|
|
82
104
|
values = cama_options(meta_key)
|
|
83
105
|
key = key.to_sym
|
|
84
106
|
values.delete(key) if values.key?(key)
|
|
@@ -88,7 +110,7 @@ module CamaleonCms
|
|
|
88
110
|
# set multiple configurations
|
|
89
111
|
# h: {ket1: "sdsds", ff: "fdfdfdfd"}
|
|
90
112
|
def set_options(h = {}, meta_key = '_default')
|
|
91
|
-
return
|
|
113
|
+
return if h.blank?
|
|
92
114
|
|
|
93
115
|
data = cama_options(meta_key)
|
|
94
116
|
PluginRoutes.fixActionParameter(h).to_sym.each do |key, value|
|
|
@@ -116,11 +138,14 @@ module CamaleonCms
|
|
|
116
138
|
save_metas_options # unless self.changed?
|
|
117
139
|
end
|
|
118
140
|
|
|
119
|
-
#
|
|
120
|
-
# sample:
|
|
141
|
+
# Save all settings for this post type - received in data_options and data_metas attribute (options and metas)
|
|
142
|
+
# sample:
|
|
143
|
+
# Site.first.post_types.create(
|
|
144
|
+
# {name: "owen", slug: "my_post_type", data_options: { has_category: true, default_layout: "my_layout" }}
|
|
145
|
+
# )
|
|
121
146
|
def save_metas_options
|
|
122
147
|
set_multiple_options(data_options)
|
|
123
|
-
return
|
|
148
|
+
return if data_metas.blank?
|
|
124
149
|
|
|
125
150
|
data_metas.each do |key, val|
|
|
126
151
|
set_meta(key, val)
|
|
@@ -134,7 +159,7 @@ module CamaleonCms
|
|
|
134
159
|
changed_value = if value.is_a?(ActionController::Parameters)
|
|
135
160
|
value.to_json
|
|
136
161
|
elsif value.is_a?(Array) || value.is_a?(Hash)
|
|
137
|
-
JSON.
|
|
162
|
+
JSON.generate(value)
|
|
138
163
|
else
|
|
139
164
|
value
|
|
140
165
|
end
|
|
@@ -9,17 +9,11 @@ module CamaleonCms
|
|
|
9
9
|
args.each do |attr|
|
|
10
10
|
next unless new_record? || attribute_changed?(attr)
|
|
11
11
|
|
|
12
|
-
self[attr] =
|
|
13
|
-
__send__(attr)&.gsub(CamaleonRecord::TRANSLATION_TAG_HIDE_REGEX, CamaleonRecord::TRANSLATION_TAG_HIDE_MAP)
|
|
14
|
-
)&.gsub(CamaleonRecord::TRANSLATION_TAG_RESTORE_REGEX, CamaleonRecord::TRANSLATION_TAG_RESTORE_MAP)
|
|
12
|
+
self[attr] = CamaleonRecord.cama_sanitize_translatable(__send__(attr))
|
|
15
13
|
end
|
|
16
14
|
end
|
|
17
15
|
else
|
|
18
|
-
normalizes(*args, with:
|
|
19
|
-
ActionController::Base.helpers.sanitize(
|
|
20
|
-
field.gsub(CamaleonRecord::TRANSLATION_TAG_HIDE_REGEX, CamaleonRecord::TRANSLATION_TAG_HIDE_MAP)
|
|
21
|
-
).gsub(CamaleonRecord::TRANSLATION_TAG_RESTORE_REGEX, CamaleonRecord::TRANSLATION_TAG_RESTORE_MAP)
|
|
22
|
-
})
|
|
16
|
+
normalizes(*args, with: ->(field) { CamaleonRecord.cama_sanitize_translatable(field) })
|
|
23
17
|
end
|
|
24
18
|
end
|
|
25
19
|
end
|