camaleon_cms 2.9.2 → 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 +17 -4
- 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 +15 -10
- data/app/apps/plugins/front_cache/config/initializer.rb +1 -1
- data/app/apps/plugins/front_cache/front_cache_helper.rb +33 -9
- 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/layouts/index.html.erb +3 -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/layouts/_header.html.erb +3 -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 +8 -6
- data/app/controllers/camaleon_cms/admin/appearances/themes_controller.rb +8 -5
- data/app/controllers/camaleon_cms/admin/appearances/widgets/assign_controller.rb +7 -2
- data/app/controllers/camaleon_cms/admin/appearances/widgets/main_controller.rb +2 -1
- data/app/controllers/camaleon_cms/admin/categories_controller.rb +19 -4
- 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 +66 -14
- data/app/controllers/camaleon_cms/admin/plugins_controller.rb +1 -3
- data/app/controllers/camaleon_cms/admin/post_tags_controller.rb +10 -4
- data/app/controllers/camaleon_cms/admin/posts/drafts_controller.rb +40 -11
- data/app/controllers/camaleon_cms/admin/posts_controller.rb +55 -22
- data/app/controllers/camaleon_cms/admin/sessions_controller.rb +237 -44
- data/app/controllers/camaleon_cms/admin/settings/custom_fields_controller.rb +76 -13
- data/app/controllers/camaleon_cms/admin/settings/post_types_controller.rb +5 -2
- data/app/controllers/camaleon_cms/admin/settings/sites_controller.rb +26 -3
- data/app/controllers/camaleon_cms/admin/settings_controller.rb +5 -3
- data/app/controllers/camaleon_cms/admin/user_roles_controller.rb +7 -5
- data/app/controllers/camaleon_cms/admin/users_controller.rb +78 -11
- data/app/controllers/camaleon_cms/admin_controller.rb +136 -26
- 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 +20 -5
- 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 +66 -50
- 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 +5 -8
- 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 +34 -17
- 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 +19 -7
- 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 +143 -66
- 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 +58 -37
- data/app/helpers/camaleon_cms/plugins_helper.rb +23 -24
- data/app/helpers/camaleon_cms/session_helper.rb +188 -44
- data/app/helpers/camaleon_cms/short_code_helper.rb +181 -85
- data/app/helpers/camaleon_cms/site_helper.rb +34 -13
- data/app/helpers/camaleon_cms/theme_helper.rb +35 -19
- data/app/helpers/camaleon_cms/uploader_helper.rb +19 -473
- 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 +15 -7
- data/app/models/camaleon_cms/category.rb +6 -6
- data/app/models/camaleon_cms/custom_field.rb +15 -6
- data/app/models/camaleon_cms/custom_field_group.rb +39 -22
- 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 +5 -3
- data/app/models/camaleon_cms/nav_menu_item.rb +16 -8
- data/app/models/camaleon_cms/plugin.rb +3 -4
- 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 -5
- data/app/models/camaleon_cms/post_type.rb +21 -13
- data/app/models/camaleon_cms/site.rb +39 -29
- data/app/models/camaleon_cms/term_relationship.rb +10 -7
- data/app/models/camaleon_cms/term_taxonomy.rb +52 -4
- data/app/models/camaleon_cms/theme.rb +2 -4
- data/app/models/camaleon_cms/user.rb +17 -5
- data/app/models/camaleon_cms/user_role.rb +66 -6
- data/app/models/camaleon_cms/widget/assigned.rb +11 -6
- data/app/models/camaleon_cms/widget/main.rb +12 -8
- data/app/models/camaleon_cms/widget/sidebar.rb +3 -8
- data/app/models/camaleon_record.rb +89 -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 +111 -54
- data/app/models/concerns/camaleon_cms/metas.rb +31 -6
- 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 +8 -1
- data/app/uploaders/camaleon_cms_aws_uploader.rb +31 -10
- 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 +5 -4
- 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/categories/index.html.erb +2 -2
- 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 +2 -2
- data/app/views/camaleon_cms/admin/posts/_sidebar.html.erb +1 -1
- data/app/views/camaleon_cms/admin/posts/form.html.erb +3 -2
- data/app/views/camaleon_cms/admin/posts/index.html.erb +5 -5
- 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 +19 -4
- 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/form.html.erb +4 -3
- 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/user_roles/form.html.erb +24 -3
- data/app/views/camaleon_cms/admin/users/form.html.erb +8 -4
- data/app/views/camaleon_cms/admin/users/index.html.erb +1 -1
- 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/_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 +1 -1
- data/config/locales/camaleon_cms/admin/ar.yml +1 -0
- data/config/locales/camaleon_cms/admin/de.yml +1 -0
- data/config/locales/camaleon_cms/admin/en.yml +33 -0
- data/config/locales/camaleon_cms/admin/es.yml +1 -0
- data/config/locales/camaleon_cms/admin/fr.yml +1 -0
- data/config/locales/camaleon_cms/admin/it.yml +1 -0
- data/config/locales/camaleon_cms/admin/nl.yml +1 -0
- data/config/locales/camaleon_cms/admin/pt-BR.yml +1 -0
- data/config/locales/camaleon_cms/admin/pt.yml +1 -0
- data/config/locales/camaleon_cms/admin/ru.yml +1 -0
- data/config/locales/camaleon_cms/admin/uk.yml +1 -0
- data/config/locales/camaleon_cms/admin/zh-CH.yml +1 -0
- data/config/routes/admin.rb +33 -15
- data/config/routes/frontend.rb +21 -15
- 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 +10 -5
- 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 +15 -13
- 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 +123 -4
|
@@ -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,7 +141,8 @@ 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|
|
|
@@ -159,9 +170,10 @@ module CamaleonCms
|
|
|
159
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,45 +299,65 @@ 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
363
|
return JSON.generate(value) if value.is_a?(Array) || value.is_a?(Hash)
|
|
@@ -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)
|
|
@@ -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
|
|
@@ -4,10 +4,20 @@ module CamaleonCms
|
|
|
4
4
|
# default structure for each new site
|
|
5
5
|
def default_settings
|
|
6
6
|
default_post_type = [
|
|
7
|
-
{
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
{
|
|
8
|
+
name: 'Post', description: 'Posts',
|
|
9
|
+
options: {
|
|
10
|
+
has_category: true, has_tags: true, not_deleted: true, has_summary: true, has_content: true,
|
|
11
|
+
has_comments: true, has_picture: true, has_template: true
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: 'Page', description: 'Pages',
|
|
16
|
+
options: {
|
|
17
|
+
has_category: false, has_tags: false, not_deleted: true, has_summary: false, has_content: true,
|
|
18
|
+
has_comments: false, has_picture: true, has_template: true, has_layout: true
|
|
19
|
+
}
|
|
20
|
+
}
|
|
11
21
|
]
|
|
12
22
|
default_post_type.each do |pt|
|
|
13
23
|
post_types.create({ name: pt[:name], slug: pt[:name].to_s.parameterize, description: pt[:description],
|
|
@@ -17,20 +27,101 @@ module CamaleonCms
|
|
|
17
27
|
# nav menus
|
|
18
28
|
@nav_menu = nav_menus.new({ name: 'Main Menu', slug: 'main_menu' })
|
|
19
29
|
if @nav_menu.save
|
|
20
|
-
post_types.
|
|
30
|
+
post_types.find_each do |pt|
|
|
21
31
|
if pt.slug == 'post'
|
|
22
32
|
title = 'Sample Post'
|
|
23
33
|
slug = 'sample-post'
|
|
24
|
-
|
|
34
|
+
content_parts = []
|
|
35
|
+
content_parts << helpers.content_tag(
|
|
36
|
+
:p, 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer pharetra ut augue in posuere. ' \
|
|
37
|
+
'Nulla non malesuada dui. Sed egestas tortor ut purus tempor sodales. ' \
|
|
38
|
+
'Duis non sollicitudin nulla, quis mollis neque. Integer sit amet augue ac neque varius auctor. ' \
|
|
39
|
+
'Vestibulum malesuada leo leo, at semper libero efficitur nec. ' \
|
|
40
|
+
'Etiam semper nisi ac nisi ullamcorper, sed tincidunt purus elementum. ' \
|
|
41
|
+
'Mauris ac congue nibh. Quisque pretium eget leo nec suscipit.'
|
|
42
|
+
)
|
|
43
|
+
content_parts << helpers.content_tag(
|
|
44
|
+
:p, 'Vestibulum ultrices orci ut congue interdum. ' \
|
|
45
|
+
'Morbi dolor nunc, imperdiet vel risus semper, tempor dapibus urna. ' \
|
|
46
|
+
'Phasellus luctus pharetra enim quis volutpat. Integer tristique urna nec malesuada ullamcorper. ' \
|
|
47
|
+
'Curabitur dictum, lectus id ultrices rhoncus, ante neque auctor erat, ' \
|
|
48
|
+
'ut sodales nisi odio sit amet lorem. In hac habitasse platea dictumst. ' \
|
|
49
|
+
'Quisque orci orci, hendrerit at luctus tristique, lobortis in diam. ' \
|
|
50
|
+
'Curabitur ligula enim, rhoncus ut vestibulum a, consequat sit amet nisi. ' \
|
|
51
|
+
'Aliquam bibendum fringilla ultrices. Aliquam erat volutpat. ' \
|
|
52
|
+
'Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; ' \
|
|
53
|
+
'In justo mi, congue in rhoncus lobortis, facilisis in est. Nam et rhoncus purus.'
|
|
54
|
+
)
|
|
55
|
+
content_parts << helpers.content_tag(
|
|
56
|
+
:p, 'Sed sagittis auctor lectus at rutrum. ' \
|
|
57
|
+
'Morbi ultricies felis mi, ut scelerisque augue facilisis eu. In molestie quam ex. ' \
|
|
58
|
+
'Quisque ut sapien sed odio tempus imperdiet. In id accumsan massa. ' \
|
|
59
|
+
'Morbi quis nunc ullamcorper, interdum enim eu, finibus purus. ' \
|
|
60
|
+
'Vestibulum ac fermentum augue, at tempus ante. ' \
|
|
61
|
+
'Aliquam ultrices, purus ut porttitor gravida, dui augue dignissim massa, ' \
|
|
62
|
+
'ac tempor ante dolor at arcu. ' \
|
|
63
|
+
'Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. ' \
|
|
64
|
+
'Suspendisse placerat risus est, eget varius mi ultricies in. ' \
|
|
65
|
+
'Duis non odio ut felis dapibus eleifend. In fringilla enim lobortis placerat efficitur.'
|
|
66
|
+
)
|
|
67
|
+
content_parts << helpers.content_tag(
|
|
68
|
+
:p, 'Nulla sodales faucibus urna, quis viverra dolor facilisis sollicitudin. Aenean ac egestas nibh. ' \
|
|
69
|
+
'Nam non tortor eget nibh scelerisque fermentum. ' \
|
|
70
|
+
'Etiam ornare, nunc ut luctus mollis, ante dolor consectetur augue, ' \
|
|
71
|
+
'non scelerisque odio est a nulla. Nullam cursus egestas nulla, nec commodo nibh suscipit ut. ' \
|
|
72
|
+
'Mauris ut felis sem. Aenean at mi at nisi dictum blandit sit amet at erat. ' \
|
|
73
|
+
'Etiam eget lobortis tellus. Curabitur in commodo arcu, at vehicula tortor.'
|
|
74
|
+
)
|
|
75
|
+
content = helpers.safe_join(content_parts)
|
|
25
76
|
else
|
|
26
77
|
title = 'Welcome'
|
|
27
78
|
slug = 'welcome'
|
|
28
|
-
|
|
79
|
+
welcome_parts = []
|
|
80
|
+
logo_img = helpers
|
|
81
|
+
.image_tag('https://camaleon.website/media/132/logo2.png', width: 155, height: 155, alt: 'logo')
|
|
82
|
+
welcome_parts << helpers.content_tag(:p, logo_img, style: 'text-align: center;')
|
|
83
|
+
cms_strong = helpers.content_tag(:strong, 'Camaleon CMS')
|
|
84
|
+
rails_link = helpers.link_to('Ruby on Rails', 'https://rubyonrails.org')
|
|
85
|
+
part2_text = helpers.safe_join(
|
|
86
|
+
[
|
|
87
|
+
cms_strong,
|
|
88
|
+
' is a free and open-source tool and a fexible content management system (CMS) based on ',
|
|
89
|
+
rails_link
|
|
90
|
+
]
|
|
91
|
+
)
|
|
92
|
+
welcome_parts << helpers.content_tag(:p, part2_text)
|
|
93
|
+
welcome_parts << helpers.content_tag(:p, 'With Camaleon you can do the following:')
|
|
94
|
+
li_texts = [
|
|
95
|
+
'Create instantly a lot of sites in the same installation',
|
|
96
|
+
'Manage your content information in several languages',
|
|
97
|
+
'Extend current functionality by plugins (MVC structure and no more echo or prints anywhere)',
|
|
98
|
+
'Create or install different themes for each site',
|
|
99
|
+
'Create your own structure without coding anything (adapt Camaleon as you want and not you for Camaleon)',
|
|
100
|
+
'Create your store and start to sell your products using our plugins',
|
|
101
|
+
'Avoid web attacks',
|
|
102
|
+
'Compare the speed and enjoy the speed of your new Camaleon site',
|
|
103
|
+
'Customize or create your themes for mobile support',
|
|
104
|
+
'Support more visitors at the same time',
|
|
105
|
+
'Manage your information with a panel like wordpress ',
|
|
106
|
+
'All urls are oriented for SEO',
|
|
107
|
+
'Multiples roles of users'
|
|
108
|
+
]
|
|
109
|
+
li_tags = li_texts.map { |text| helpers.content_tag(:li, text) }
|
|
110
|
+
welcome_parts << helpers.content_tag(:ul, helpers.safe_join(li_tags))
|
|
111
|
+
content = helpers.safe_join(welcome_parts)
|
|
29
112
|
end
|
|
30
113
|
user = users.admin_scope.first
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
114
|
+
if user.blank?
|
|
115
|
+
# Never mint a known default password. Generate a random one, force a change on first
|
|
116
|
+
# login, and stash the plaintext transiently so the provisioning controller can surface
|
|
117
|
+
# it once. See harden-installer-default-admin.
|
|
118
|
+
generated_password = SecureRandom.alphanumeric(16)
|
|
119
|
+
user = users.admin_scope.create({ email: 'admin@local.com', username: 'admin',
|
|
120
|
+
password: generated_password,
|
|
121
|
+
password_confirmation: generated_password,
|
|
122
|
+
first_name: 'Administrator' })
|
|
123
|
+
user.set_meta('must_change_password', true)
|
|
124
|
+
self.generated_admin_password = generated_password
|
|
34
125
|
end
|
|
35
126
|
post = pt.add_post({ title: title, slug: slug, content: content, user_id: user.id, status: 'published' })
|
|
36
127
|
@nav_menu.append_menu_item({ label: title, type: 'post', link: post.id })
|
|
@@ -60,18 +151,26 @@ module CamaleonCms
|
|
|
60
151
|
if post_type.present?
|
|
61
152
|
d = user_role.get_meta("_post_type_#{id}", {})
|
|
62
153
|
CamaleonCms::UserRole::ROLES[:post_type].each do |value|
|
|
154
|
+
# post_content_unfiltered_html lets a role store unsanitized HTML in post content; it must not be
|
|
155
|
+
# granted to the default Editor role (only admins, via `can :manage, :all`, are trusted for it).
|
|
156
|
+
next if value[:key].to_s == 'post_content_unfiltered_html'
|
|
157
|
+
|
|
63
158
|
value_old = d[value[:key].to_sym] || []
|
|
64
159
|
d[value[:key].to_sym] = value_old + [post_type.id]
|
|
65
160
|
end
|
|
66
161
|
else
|
|
67
162
|
pts = post_types.all.pluck(:id)
|
|
68
|
-
CamaleonCms::UserRole::ROLES[:post_type].each
|
|
163
|
+
CamaleonCms::UserRole::ROLES[:post_type].each do |value|
|
|
164
|
+
next if value[:key].to_s == 'post_content_unfiltered_html'
|
|
165
|
+
|
|
166
|
+
d[value[:key]] = pts
|
|
167
|
+
end
|
|
69
168
|
end
|
|
70
169
|
user_role.set_meta("_post_type_#{id}", d || {})
|
|
71
170
|
end
|
|
72
171
|
|
|
73
|
-
user_role = user_roles.where({ slug: 'contributor' })
|
|
74
|
-
|
|
172
|
+
user_role = user_roles.where({ slug: 'contributor' })
|
|
173
|
+
.first_or_create({ name: 'Contributor', description: 'Contributor Role' })
|
|
75
174
|
if user_role.valid?
|
|
76
175
|
d = {}
|
|
77
176
|
if post_type.present?
|
|
@@ -89,13 +188,18 @@ module CamaleonCms
|
|
|
89
188
|
|
|
90
189
|
return if post_type.present?
|
|
91
190
|
|
|
92
|
-
user_role = user_roles.where({ slug: 'client',
|
|
93
|
-
|
|
94
|
-
description: 'Default roles client' })
|
|
191
|
+
user_role = user_roles.where({ slug: 'client', term_group: -1 })
|
|
192
|
+
.first_or_create({ name: 'Client', description: 'Default roles client' })
|
|
95
193
|
return unless user_role.valid?
|
|
96
194
|
|
|
97
195
|
user_role.set_meta("_post_type_#{id}", {})
|
|
98
196
|
user_role.set_meta("_manager_#{id}", {})
|
|
99
197
|
end
|
|
198
|
+
|
|
199
|
+
private
|
|
200
|
+
|
|
201
|
+
def helpers
|
|
202
|
+
ActionController::Base.helpers
|
|
203
|
+
end
|
|
100
204
|
end
|
|
101
205
|
end
|