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
|
@@ -15,13 +15,24 @@
|
|
|
15
15
|
</div>
|
|
16
16
|
<% end %>
|
|
17
17
|
<div class="fields_container">
|
|
18
|
-
<% fields.decorate.each do |field|
|
|
19
|
-
|
|
18
|
+
<% fields.decorate.each do |field|
|
|
19
|
+
field_key = field.get_option('field_key').presence || field.options[:field_key].presence || field.options['field_key'].presence
|
|
20
|
+
normalized_field_key = field_key.presence || 'text_box'
|
|
21
|
+
is_disabled = field.get_option('disabled').present? || field.get_option('readonly').present?
|
|
22
|
+
required_field = field.get_option('required').to_s.to_bool
|
|
23
|
+
group_field_data[field.slug] = {
|
|
24
|
+
default_value: field.get_option('default_value'),
|
|
25
|
+
is_disabled: is_disabled,
|
|
26
|
+
id: field.id,
|
|
27
|
+
multiple: field.get_option('multiple').to_s.to_bool && !is_disabled,
|
|
28
|
+
kind: normalized_field_key
|
|
29
|
+
} %>
|
|
30
|
+
<div class="item-custom-field c-field-<%= normalized_field_key %>" data-field-key="<%= field.slug %>">
|
|
20
31
|
<input name="<%= field_name %>[<%= field.slug %>][id]" type="hidden" value="<%= field.id %>"/>
|
|
21
32
|
<input name="<%= field_name %>[<%= field.slug %>][group_number]" class="cama_custom_group_number" type="hidden" value="0"/>
|
|
22
33
|
<label>
|
|
23
34
|
<%= field.name %>
|
|
24
|
-
<%= raw "<em class='text-danger'>*</em>" if
|
|
35
|
+
<%= raw "<em class='text-danger'>*</em>" if required_field %>
|
|
25
36
|
<% if current_site.get_option('custom_fields_show_shortcodes') && ["post", "posttype", "category", "postTag", "site", "user", "navmenu", "theme"].include?(obj_class) %>
|
|
26
37
|
<small class="shortcode_field"><br><%= cama_shortcode_print("[data field='#{field.slug}' #{"object='#{obj_class}' #{"id='#{record.id}'" if obj_class != "Theme" }" unless record.new_record?}]") %></small>
|
|
27
38
|
<% end %>
|
|
@@ -31,7 +42,11 @@
|
|
|
31
42
|
<% end %>
|
|
32
43
|
<div class="editor-custom-fields content-field-<%= field.id %>" data-add_field_title="<%= t('camaleon_cms.admin.button.add_new_field', default: 'Add new field')%>">
|
|
33
44
|
<%= begin
|
|
34
|
-
|
|
45
|
+
custom_field_render = (cama_custom_field_elements[normalized_field_key.to_sym][:render] rescue nil)
|
|
46
|
+
render(
|
|
47
|
+
field.get_option('render') || custom_field_render || "camaleon_cms/admin/settings/custom_fields/fields/#{normalized_field_key}",
|
|
48
|
+
field: field, values: nil, is_disabled: is_disabled, default_use: default_use, field_name: field_name
|
|
49
|
+
)
|
|
35
50
|
rescue => e
|
|
36
51
|
Rails.logger.error "Camaleon CMS - Render Custom Fields Error: Custom field template was not found => #{e.message}: #{$!.backtrace}".cama_log_style(:red)
|
|
37
52
|
e.message
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
def _render_category_option_html(item, pos = 0)
|
|
3
3
|
category = item.decorate
|
|
4
4
|
value = "Category_Post,#{category.id}" %>
|
|
5
|
-
<option value="<%= value %>" data-help="<%=
|
|
5
|
+
<option value="<%= value %>" data-help="<%= safe_join([t('camaleon_cms.admin.settings.tooltip.add_custom_field_posts'), category.the_title]) %>"><%= safe_join([('—' * pos), ' ', category.the_title]) %></option>
|
|
6
6
|
<% end
|
|
7
7
|
|
|
8
8
|
def _render_categories(categories, _level = 0)
|
|
@@ -64,13 +64,14 @@
|
|
|
64
64
|
</optgroup>
|
|
65
65
|
|
|
66
66
|
<optgroup label="<%= t('camaleon_cms.admin.settings.others') %>">
|
|
67
|
-
|
|
67
|
+
<%# Demodulized: user groups are stored and read under the association's scope name %>
|
|
68
|
+
<% value = "#{PluginRoutes.get_user_class_name.demodulize},#{current_site.id}" %>
|
|
68
69
|
<option value="<%= value %>" data-help="<%= t('camaleon_cms.admin.settings.tooltip.add_custom_field_users') %>"><%= t('camaleon_cms.admin.sidebar.users') %></option>
|
|
69
70
|
<% value = "Site,#{current_site.id}" %>
|
|
70
71
|
<option value="<%= value %>" data-help="<%= t('camaleon_cms.admin.settings.tooltip.add_custom_field_sites') %>"><%= t('camaleon_cms.admin.sidebar.site_settings') %></option>
|
|
71
|
-
<%
|
|
72
|
+
<% cf_extra_models_for_fields.each do |model| %>
|
|
72
73
|
<% value = "#{model.name},#{current_site.id}" %>
|
|
73
|
-
<option value="<%= value %>" data-help=""><%= model.name %></option
|
|
74
|
+
<option value="<%= value %>" data-help=""><%= model.name %></option>
|
|
74
75
|
<% end %>
|
|
75
76
|
</optgroup>
|
|
76
77
|
|
|
@@ -13,17 +13,17 @@
|
|
|
13
13
|
</tr>
|
|
14
14
|
</thead>
|
|
15
15
|
<tbody>
|
|
16
|
-
<%
|
|
16
|
+
<% shortcodes_list.each do |code| %>
|
|
17
17
|
<tr>
|
|
18
18
|
<td>
|
|
19
19
|
<code>[<%= code %>]</code>
|
|
20
20
|
</td>
|
|
21
|
-
<td class="col_descr"><%=
|
|
21
|
+
<td class="col_descr"><%= shortcodes_descriptions[code] %></td>
|
|
22
22
|
</tr>
|
|
23
23
|
<% end %>
|
|
24
24
|
</tbody>
|
|
25
25
|
</table>
|
|
26
|
-
<%= content_tag("div", t('camaleon_cms.admin.message.data_found_list'), class: "alert alert-warning") if
|
|
26
|
+
<%= content_tag("div", t('camaleon_cms.admin.message.data_found_list'), class: "alert alert-warning") if shortcodes_list.empty? %>
|
|
27
27
|
</div>
|
|
28
28
|
</div>
|
|
29
29
|
</div>
|
|
@@ -34,4 +34,4 @@
|
|
|
34
34
|
$(this).html($(this).html().replace(/\n/g, "<br>"));
|
|
35
35
|
});
|
|
36
36
|
})
|
|
37
|
-
</script>
|
|
37
|
+
</script>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<div class="page-content-wrap">
|
|
4
4
|
<div class="panel panel-default">
|
|
5
5
|
<div class="panel-heading">
|
|
6
|
-
<h4><span class="fa fa-cog"></span> <%=
|
|
6
|
+
<h4><span class="fa fa-cog"></span> <%= safe_join([t('camaleon_cms.admin.settings.configuration_site'), ': ', @site.the_title, ' ']) %> </h4>
|
|
7
7
|
</div>
|
|
8
8
|
<%= form_for @site, as: "site", url: {action: :site_saved}, html: {id: "site_settings_form", class: "panel-body cama_ajax_request validate"} do |f| %>
|
|
9
9
|
<div class="tabs">
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<div class="col-md-8 col-md-offset-2">
|
|
6
6
|
<div class="panel panel-default">
|
|
7
7
|
<div class="panel-heading">
|
|
8
|
-
<h4><span class="fa fa-cog"></span> <%= @site.new_record? ? t('camaleon_cms.admin.page_title.new_site') :
|
|
8
|
+
<h4><span class="fa fa-cog"></span> <%= @site.new_record? ? t('camaleon_cms.admin.page_title.new_site') : safe_join([t('camaleon_cms.admin.page_title.edit_site'), ': ', @site.the_title, ' ']) %> </h4>
|
|
9
9
|
</div>
|
|
10
10
|
<div class="panel-body">
|
|
11
11
|
<%= render partial: 'layouts/camaleon_cms/admin/form_error', locals: {data: @site} %>
|
|
@@ -17,6 +17,26 @@
|
|
|
17
17
|
<%= render partial: 'layouts/camaleon_cms/admin/form_error', locals: {data: @user_role} %>
|
|
18
18
|
<% rol_values_post_type = @user_role.new_record? ? {} : @user_role.get_meta("_post_type_#{current_site.id.to_s}") %>
|
|
19
19
|
<% rol_values_manager = @user_role.new_record? ? {} : @user_role.get_meta("_manager_#{current_site.id.to_s}") %>
|
|
20
|
+
<%# A role whose users are administrators holds every permission through `Ability`'s %>
|
|
21
|
+
<%# `can :manage, :all`, which returns before either meta above is read. Their stored %>
|
|
22
|
+
<%# metas are only what `set_default_user_roles` seeded when the site was created, so %>
|
|
23
|
+
<%# every key added to ROLES afterwards rendered unchecked on existing sites and read %>
|
|
24
|
+
<%# as "denied to administrators", which it never was. Deriving the state from the %>
|
|
25
|
+
<%# role keeps it true for keys added later, with no backfill task to run and none to %>
|
|
26
|
+
<%# write again next time. %>
|
|
27
|
+
<%# %>
|
|
28
|
+
<%# Such a role's boxes are also locked, and `UserRolesController` declines to write %>
|
|
29
|
+
<%# its metas — the two conditions are the same predicate, so a locked box, which the %>
|
|
30
|
+
<%# browser never submits, cannot silently clear what is stored. %>
|
|
31
|
+
<% grants_all = @user_role.grants_all_permissions? %>
|
|
32
|
+
<% permissions_editable = @user_role.permissions_editable? %>
|
|
33
|
+
<%# Without this the locked, all-checked boxes look like a bug rather than a statement %>
|
|
34
|
+
<%# about what an administrator is. %>
|
|
35
|
+
<% if grants_all %>
|
|
36
|
+
<div class="alert alert-info">
|
|
37
|
+
<span class="fa fa-info-circle"></span> <%= t('camaleon_cms.admin.users.admin_holds_all_permissions', default: 'Users with this role are administrators, so they hold every permission below regardless of what is selected. These settings cannot be changed.') %>
|
|
38
|
+
</div>
|
|
39
|
+
<% end %>
|
|
20
40
|
<div id="contents-checkbox" class="form-horizontal">
|
|
21
41
|
<div class="">
|
|
22
42
|
<table class="table table-responsive table-hover table-striped">
|
|
@@ -49,7 +69,7 @@
|
|
|
49
69
|
values = [] if values == 0
|
|
50
70
|
%>
|
|
51
71
|
<% if visible %>
|
|
52
|
-
<input type="checkbox" name="rol_values[post_type][<%= value[:key] %>][]" value="<%= pt.id %>" <%= "checked" if values.include?(pt.id) %> <%= "disabled" unless
|
|
72
|
+
<input type="checkbox" name="rol_values[post_type][<%= value[:key] %>][]" value="<%= pt.id %>" <%= "checked" if grants_all || values.include?(pt.id) %> <%= "disabled" unless permissions_editable %> onclick="<%= "cama_user_roles_do_all_publish(this, '#{value[:color]}', '#{value[:key]}')" %>" >
|
|
53
73
|
<% end %>
|
|
54
74
|
</td>
|
|
55
75
|
<% end %>
|
|
@@ -64,9 +84,10 @@
|
|
|
64
84
|
<h5><%= t('camaleon_cms.admin.users.other_permissions')%></h5>
|
|
65
85
|
<div class="row">
|
|
66
86
|
<% values = rol_values_manager || {} %>
|
|
87
|
+
<%# Same rule as the grid above: see `grants_all` where it is assigned. %>
|
|
67
88
|
<% cama_get_roles_values[:manager].each do |value| %>
|
|
68
89
|
<div class="col-md-4">
|
|
69
|
-
<label><input type="checkbox" name="rol_values[manager][<%= value[:key] %>]" value="1" <%= "checked" if values[value[:key].to_sym].present? %> <%= "disabled" unless
|
|
90
|
+
<label><input type="checkbox" name="rol_values[manager][<%= value[:key] %>]" value="1" <%= "checked" if grants_all || values[value[:key].to_sym].present? %> <%= "disabled" unless permissions_editable %> <%= 'data-danger-select-eval=1' if value[:key].to_s == 'select_eval' %> > <%= raw value[:label] %></label>
|
|
70
91
|
<%= raw cama_html_tooltip(value[:description], 'right') if value[:description].present? %>
|
|
71
92
|
</div>
|
|
72
93
|
<% end %>
|
|
@@ -77,7 +98,7 @@
|
|
|
77
98
|
|
|
78
99
|
|
|
79
100
|
</div>
|
|
80
|
-
<% if
|
|
101
|
+
<% if permissions_editable %>
|
|
81
102
|
<div id="checked-actions" class="panel-footer text-right">
|
|
82
103
|
<a class="btn btn-default btn-sm" data-type="all" href="#"><%= t('camaleon_cms.admin.button.select_all') %></a>
|
|
83
104
|
<a class="btn btn-default btn-sm" data-type="none" href="#"><%= t('camaleon_cms.admin.button.select_none') %></a>
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
|
|
14
14
|
<div class="row">
|
|
15
15
|
<%= form_for @user, as: "user", url:{action: @user.new_record? ? :create : :update, id: @user.id}, html:{class: 'validate-user form-horizontal cama_ajax_request', id: "user_form"} do |f| %>
|
|
16
|
+
<%# A non-admin may not change an admin's password or recovery identifiers (email/username), so
|
|
17
|
+
the enforcement in UsersController#user_params/#updated_ajax is mirrored here (H10). %>
|
|
18
|
+
<% credentials_locked = !cama_current_user.may_edit_credentials?(@user) %>
|
|
16
19
|
<div class="col-md-3">
|
|
17
20
|
<div class="panel panel-default">
|
|
18
21
|
<div class="panel-body">
|
|
@@ -35,11 +38,11 @@
|
|
|
35
38
|
</div>
|
|
36
39
|
<div class="">
|
|
37
40
|
<label class="control-label"><%= t('camaleon_cms.admin.table.login')%></label>
|
|
38
|
-
<%= f.text_field :username, :class => "form-control required" %>
|
|
41
|
+
<%= f.text_field :username, :class => "form-control required", disabled: credentials_locked %>
|
|
39
42
|
</div>
|
|
40
43
|
<div class="">
|
|
41
44
|
<label class="control-label"><%= t('camaleon_cms.admin.table.e_mail')%></label>
|
|
42
|
-
<%= f.email_field :email, :class => "form-control required email"%>
|
|
45
|
+
<%= f.email_field :email, :class => "form-control required email", disabled: credentials_locked %>
|
|
43
46
|
</div>
|
|
44
47
|
<% if @user.new_record? %>
|
|
45
48
|
<div class="">
|
|
@@ -54,14 +57,15 @@
|
|
|
54
57
|
<div class="">
|
|
55
58
|
<%= f.label "#{t('camaleon_cms.admin.table.role')}", class: "control-label" %>
|
|
56
59
|
<div class="">
|
|
57
|
-
|
|
60
|
+
<%# Only offer the admin role to someone who may actually grant it (H10); keep it listed when editing a user who already holds it so their role still displays. %>
|
|
61
|
+
<%= f.select :role, current_site.user_roles.reorder(:name).decorate.reject { |role| role.slug == 'admin' && !cama_current_user.role_grantor?(@user, 'admin') && @user&.role.to_s != 'admin' }.map{|role| [role.the_title, role.slug]}, {}, {:class => "form-control required", disabled: !cama_current_user.role_grantor?(@user)}%>
|
|
58
62
|
</div>
|
|
59
63
|
</div>
|
|
60
64
|
<hr>
|
|
61
65
|
<div class="">
|
|
62
66
|
<button type="submit" class="btn btn-success btn-block" ><%= @user.new_record? ? t('camaleon_cms.admin.button.create') : t('camaleon_cms.admin.button.update') %></button>
|
|
63
67
|
</div>
|
|
64
|
-
<% if !@user.new_record? %>
|
|
68
|
+
<% if !@user.new_record? && !credentials_locked %>
|
|
65
69
|
<div class="">
|
|
66
70
|
<a href="#" class="btn btn-warning btn-block btn-rounded" data-toggle="modal" data-target="#modal_change_password"><%= t('camaleon_cms.admin.button.change_password') %></a>
|
|
67
71
|
</div>
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
<%= link_to raw('<i class="fa fa-times"></i>'), { action: :destroy, id: f.id },
|
|
46
46
|
method: :delete, data: { confirm: t('camaleon_cms.admin.message.delete_item') }, class: "btn btn-danger btn-xs cama_ajax_request", title: "#{t('camaleon_cms.admin.button.delete')}" %>
|
|
47
47
|
<% end %>
|
|
48
|
-
<%= link_to raw('<i class="fa fa-retweet"></i>'), {action: :impersonate, id: f.id }, class: "btn btn-default btn-xs cama_ajax_request", title: "#{cama_t('camaleon_cms.admin.users.impersonate')}" if can? :impersonate, f %>
|
|
48
|
+
<%= link_to raw('<i class="fa fa-retweet"></i>'), {action: :impersonate, id: f.id }, method: :post, class: "btn btn-default btn-xs cama_ajax_request", title: "#{cama_t('camaleon_cms.admin.users.impersonate')}" if can? :impersonate, f %>
|
|
49
49
|
</td>
|
|
50
50
|
</tr>
|
|
51
51
|
<% end %>
|
|
@@ -41,9 +41,15 @@
|
|
|
41
41
|
%>
|
|
42
42
|
<p><%= post.decorate.the_title if post.present? %></p>
|
|
43
43
|
<% when 'field_attrs'
|
|
44
|
-
|
|
44
|
+
attrs = JSON.parse(value) rescue nil
|
|
45
45
|
%>
|
|
46
|
-
|
|
46
|
+
<% if attrs.is_a?(Hash) && attrs.present? %>
|
|
47
|
+
<%# Security (scan-and-reject policy): attr/value are gated at save like editor %>
|
|
48
|
+
<%# values -- CustomFieldsRelationship scans the DECODED JSON members (any shape) -- %>
|
|
49
|
+
<%# so stored values equal authored values and render verbatim. Guard on Hash so a %>
|
|
50
|
+
<%# non-object JSON value (array/scalar) renders nothing instead of raising a 500. %>
|
|
51
|
+
<p><strong><%= raw attrs['attr'] %>: </strong><%= raw attrs['value'] %></p>
|
|
52
|
+
<% end %>
|
|
47
53
|
<% else %>
|
|
48
54
|
<p><%= value %></p>
|
|
49
55
|
<% end %>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<li>
|
|
7
7
|
<h3><a href="<%= ptype.the_url %>"><%= ptype.the_title %></a></h3>
|
|
8
8
|
<% if ptype.manage_categories? %>
|
|
9
|
-
<%= raw(cama_sitemap_cats_generator(ptype.the_categories)) %>
|
|
9
|
+
<%= raw(cama_sitemap_cats_generator(ptype.the_categories, @r)) %>
|
|
10
10
|
<% else %>
|
|
11
11
|
<ul>
|
|
12
12
|
<% ptype.the_posts.decorate.each do |post| next if @r[:skip_post_ids].include?(post.id) %>
|
|
@@ -57,7 +57,7 @@ xml.urlset 'xmlns' => 'https://www.sitemaps.org/schemas/sitemap/0.9' do
|
|
|
57
57
|
@r[:custom].each_value do |item|
|
|
58
58
|
xml.url do
|
|
59
59
|
xml.loc item[:url]
|
|
60
|
-
xml.lastmod item[:lastmod] || Date.
|
|
60
|
+
xml.lastmod item[:lastmod] || Date.current.to_s
|
|
61
61
|
xml.changefreq item[:changefreq] || 'monthly'
|
|
62
62
|
xml.priority item[:priority] || '0.5'
|
|
63
63
|
end
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
<a href="<%= cama_admin_profile_edit_path %>" class="btn btn-primary cama_ajax_request"><%= t("camaleon_cms.admin.users.profile") %></a>
|
|
39
39
|
</div>
|
|
40
40
|
<div class="pull-right">
|
|
41
|
-
|
|
41
|
+
<%= button_to t("camaleon_cms.admin.logout.logout"), cama_admin_logout_path, method: :post, class: "btn btn-danger" %>
|
|
42
42
|
</div>
|
|
43
43
|
</li>
|
|
44
44
|
</ul>
|
|
@@ -7,11 +7,14 @@ module ActionView
|
|
|
7
7
|
# fix to add camaleon prefix to search partials and layouts
|
|
8
8
|
def find(name, prefixes = [], partial = false, keys = [], options = {})
|
|
9
9
|
if use_camaleon_partial_prefixes.present?
|
|
10
|
-
|
|
10
|
+
scoped_prefixes = cama_theme_scoped_prefixes(prefixes)
|
|
11
|
+
theme_scoped = scoped_prefixes.present?
|
|
12
|
+
prefixes = scoped_prefixes if theme_scoped
|
|
13
|
+
if !partial && prefixes.blank? && File.exist?(name) # fix for windows ==> render file: '....'
|
|
11
14
|
# puts "rendering specific file (render file: '....')"
|
|
12
15
|
else
|
|
13
|
-
prefixes = ['']
|
|
14
|
-
prefixes = (self.prefixes + prefixes).uniq if prefixes.is_a?(Array)
|
|
16
|
+
prefixes = [''] if prefixes.blank?
|
|
17
|
+
prefixes = (self.prefixes + prefixes).uniq if prefixes.is_a?(Array) && !theme_scoped
|
|
15
18
|
end
|
|
16
19
|
end
|
|
17
20
|
@view_paths.find(*cama_args_for_lookup(name, prefixes, partial, keys, options))
|
|
@@ -21,8 +24,11 @@ module ActionView
|
|
|
21
24
|
# fix to add camaleon prefixes on verify template exist
|
|
22
25
|
def exists?(name, prefixes = [], partial = false, keys = [], **options)
|
|
23
26
|
if use_camaleon_partial_prefixes.present?
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
scoped_prefixes = cama_theme_scoped_prefixes(prefixes)
|
|
28
|
+
theme_scoped = scoped_prefixes.present?
|
|
29
|
+
prefixes = scoped_prefixes if theme_scoped
|
|
30
|
+
prefixes = [''] if prefixes.blank?
|
|
31
|
+
prefixes = (prefixes + self.prefixes).uniq if prefixes.is_a?(Array) && !theme_scoped
|
|
26
32
|
end
|
|
27
33
|
@view_paths.exists?(*cama_args_for_lookup(name, prefixes, partial, keys, options))
|
|
28
34
|
end
|
|
@@ -43,6 +49,37 @@ module ActionView
|
|
|
43
49
|
[name, prefixes, partial || false, details, details_key, keys]
|
|
44
50
|
end
|
|
45
51
|
end
|
|
52
|
+
|
|
53
|
+
# Detects a lookup whose explicit prefixes are *entirely* scoped to the
|
|
54
|
+
# current (frontend) theme -- i.e. its `themes/<slug>/views...` prefixes
|
|
55
|
+
# and/or the gem `camaleon_cms/default_theme` fallback, and nothing else
|
|
56
|
+
# (e.g. a partial rendered from within a theme, or a theme preview). In
|
|
57
|
+
# that case the lookup is restricted to that theme and the global
|
|
58
|
+
# `self.prefixes` are NOT merged, so a different theme / per-site override
|
|
59
|
+
# does not leak in.
|
|
60
|
+
#
|
|
61
|
+
# When the explicit prefixes also include non-theme prefixes (e.g. a
|
|
62
|
+
# plugin front controller rendering its own `plugins/<name>/...`
|
|
63
|
+
# templates), it returns a blank list, signalling the caller to merge
|
|
64
|
+
# `self.prefixes` as before -- this keeps the plugin's own
|
|
65
|
+
# `plugins/<name>/views/...` lookup prefix reachable.
|
|
66
|
+
#
|
|
67
|
+
# Known limitation (regression audit M30, deliberately kept): an explicit
|
|
68
|
+
# `render prefixes:` whose list is *entirely* theme-scoped but whose target
|
|
69
|
+
# template actually lives under a controller prefix raises MissingTemplate,
|
|
70
|
+
# because `self.prefixes` are not merged in that case. Merging them would
|
|
71
|
+
# reopen the per-site-override / cross-theme leak this guard exists to close,
|
|
72
|
+
# and no stock or ecosystem caller hits it, so the isolation is kept.
|
|
73
|
+
def cama_theme_scoped_prefixes(prefixes)
|
|
74
|
+
theme = CurrentRequest.frontend_current_theme
|
|
75
|
+
slug = theme&.slug
|
|
76
|
+
return if slug.blank? || prefixes.blank? || !prefixes.is_a?(Array)
|
|
77
|
+
|
|
78
|
+
selected = prefixes.select do |prefix|
|
|
79
|
+
prefix.include?("themes/#{slug}/views") || prefix == 'camaleon_cms/default_theme'
|
|
80
|
+
end
|
|
81
|
+
selected if selected.length == prefixes.length
|
|
82
|
+
end
|
|
46
83
|
end
|
|
47
84
|
end
|
|
48
85
|
end
|
|
@@ -1,25 +1,3 @@
|
|
|
1
|
-
module ActiveRecordExtras
|
|
2
|
-
module Relation
|
|
3
|
-
extend ActiveSupport::Concern
|
|
4
|
-
|
|
5
|
-
module ClassMethods
|
|
6
|
-
def update_or_create(attributes = {})
|
|
7
|
-
assign_or_new(attributes).save
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def update_or_create!(attributes = {})
|
|
11
|
-
assign_or_new(attributes).save!
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def assign_or_new(attributes)
|
|
15
|
-
obj = first || new
|
|
16
|
-
obj.assign_attributes(attributes)
|
|
17
|
-
obj
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
1
|
ActiveRecord::Associations::CollectionProxy.class_eval do
|
|
24
2
|
# order a collection by custom fields
|
|
25
3
|
# Arguments:
|
|
@@ -28,9 +6,17 @@ ActiveRecord::Associations::CollectionProxy.class_eval do
|
|
|
28
6
|
# sample: CamaleonCms::Site.first.posts.sort_by_field("untitled-field-attributes", "desc")
|
|
29
7
|
def sort_by_field(key, order = 'ASC')
|
|
30
8
|
cfr_table = CamaleonCms::CustomFieldsRelationship.table_name
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
9
|
+
# Security (audit 2026-08-11, Tier-2 #8): sort_by_field is a public API themes/plugins reach as
|
|
10
|
+
# sort_by_field(key, params[:order]), so interpolating `order` straight into ORDER BY was an
|
|
11
|
+
# injection sink. Whitelist the direction to ASC/DESC and order by a quoted Arel column, so a
|
|
12
|
+
# hostile direction can neither append extra ORDER BY terms nor raise -- without relying on
|
|
13
|
+
# ActiveRecord's implicit raw-SQL guard. The whitelist reads the leading token so previously
|
|
14
|
+
# working spellings (' desc ', 'DESC NULLS LAST') keep their direction; punctuation sticks to
|
|
15
|
+
# the token ('DESC;...' != 'DESC'), so hostile strings still fail closed to ascending.
|
|
16
|
+
direction = order.to_s.strip[/\A\S+/]&.casecmp?('DESC') ? :desc : :asc
|
|
17
|
+
joins("LEFT OUTER JOIN #{cfr_table} ON #{cfr_table}.objectid = #{klass.table_name}.id").where(
|
|
18
|
+
"#{cfr_table}.custom_field_slug = ? and #{cfr_table}.object_class = ?", key, klass.name.parseCamaClass
|
|
19
|
+
).reorder(CamaleonCms::CustomFieldsRelationship.arel_table[:value].public_send(direction))
|
|
34
20
|
end
|
|
35
21
|
|
|
36
22
|
# Filter by custom field values
|
|
@@ -43,8 +29,8 @@ ActiveRecord::Associations::CollectionProxy.class_eval do
|
|
|
43
29
|
# .where("#{CamaleonCms::CustomFieldsRelationship.table_name}.value=?", "my_value_for_field")
|
|
44
30
|
def filter_by_field(key, args = {})
|
|
45
31
|
cfr_table = CamaleonCms::CustomFieldsRelationship.table_name
|
|
46
|
-
res = joins("LEFT OUTER JOIN #{cfr_table} ON #{cfr_table}.objectid = #{
|
|
47
|
-
"#{cfr_table}.custom_field_slug = ? and #{cfr_table}.object_class = ?", key,
|
|
32
|
+
res = joins("LEFT OUTER JOIN #{cfr_table} ON #{cfr_table}.objectid = #{klass.table_name}.id").where(
|
|
33
|
+
"#{cfr_table}.custom_field_slug = ? and #{cfr_table}.object_class = ?", key, klass.name.parseCamaClass
|
|
48
34
|
)
|
|
49
35
|
res = res.where("#{cfr_table}.value = ?", args[:value]) if args[:value]
|
|
50
36
|
res
|
|
@@ -1,34 +1,63 @@
|
|
|
1
1
|
# Be sure to restart your server when you modify this file.
|
|
2
2
|
|
|
3
3
|
# Version of your assets, change this if you want to expire all your assets.
|
|
4
|
-
Rails.application.config.assets.version = '1.
|
|
4
|
+
Rails.application.config.assets.version = '1.1'
|
|
5
5
|
|
|
6
6
|
Rails.application.config.tinymce.install = :copy
|
|
7
7
|
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
#
|
|
8
|
+
# TinyMCE editor icons in development.
|
|
9
|
+
#
|
|
10
|
+
# sprockets-rails >= 3.5 registers `Sprockets::Rails::AssetUrlProcessor`, a `text/css`
|
|
11
|
+
# post-processor that rewrites every relative `url(...)` reference to a digested asset
|
|
12
|
+
# path. TinyMCE's bundled skin (`tinymce/skins/lightgray/skin.min.css`) references its
|
|
13
|
+
# icon font with directory-relative urls such as `url('fonts/tinymce.woff')`. Sprockets
|
|
14
|
+
# resolves `url()` paths against the asset load roots (not the referencing file's own
|
|
15
|
+
# directory), so it cannot find `fonts/tinymce.woff` (its real logical path is
|
|
16
|
+
# `tinymce/skins/lightgray/fonts/...`) and rewrites it to an invalid root path
|
|
17
|
+
# (`/fonts/tinymce.woff`) which 404s, leaving the editor toolbar without icons.
|
|
18
|
+
#
|
|
19
|
+
# In production this never happens: `tinymce.install = :copy` ships the skin as raw static
|
|
20
|
+
# files under `public/assets`, bypassing Sprockets (and this processor) entirely. The bug
|
|
21
|
+
# only surfaces in environments that compile assets on the fly (development).
|
|
22
|
+
#
|
|
23
|
+
# We must NOT disable the processor globally: other stylesheets (e.g. Bootstrap, whose
|
|
24
|
+
# glyphicon @font-face urls are relative) rely on it to produce resolvable digested paths.
|
|
25
|
+
# Instead, swap it for a thin subclass that, for the TinyMCE skin only, first expands the
|
|
26
|
+
# skin's directory-relative font urls into full logical asset paths (prefixing them with the
|
|
27
|
+
# skin's own logical directory) before delegating to the original processor. The original
|
|
28
|
+
# then resolves and digests them correctly. Every other stylesheet is processed unchanged.
|
|
29
|
+
if defined?(Sprockets::Rails::AssetUrlProcessor) && Rails.application.config.assets.compile &&
|
|
30
|
+
Sprockets.respond_to?(:unregister_postprocessor) && Sprockets.respond_to?(:register_postprocessor)
|
|
31
|
+
class TinymceSkinSafeAssetUrlProcessor < Sprockets::Rails::AssetUrlProcessor
|
|
32
|
+
SKIN_MARKER = 'tinymce/skins/'.freeze
|
|
33
|
+
# Directory-relative `url(...)` references that are not absolute/external/data urls.
|
|
34
|
+
RELATIVE_URL = %r{url\(\s*["']?(?!(?:#|data|http|/))(?:\./)?(?<path>[^"'\s)]+)\s*["']?\)}
|
|
11
35
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if dirname.start_with?('plugins/') || dirname.start_with?('themes/')
|
|
20
|
-
name = File.basename(path)
|
|
21
|
-
content_type = begin
|
|
22
|
-
MIME::Types.type_for(name).first.content_type
|
|
23
|
-
rescue StandardError
|
|
24
|
-
''
|
|
25
|
-
end
|
|
26
|
-
if (path =~ /\.(css|js|svg|ttf|woff|eot|swf|pdf|png|jpg|gif)\z/ ||
|
|
27
|
-
content_type.scan(%r{(javascript|image/|audio|video|font)}).any?) &&
|
|
28
|
-
!name.start_with?('_') && !path.include?('/views/')
|
|
29
|
-
res = true
|
|
36
|
+
def self.call(input)
|
|
37
|
+
filename = input[:filename].to_s
|
|
38
|
+
return super unless filename.include?(SKIN_MARKER)
|
|
39
|
+
|
|
40
|
+
logical_dir = File.dirname(filename[filename.index('tinymce/')..])
|
|
41
|
+
rewritten = input[:data].gsub(RELATIVE_URL) do
|
|
42
|
+
"url(#{logical_dir}/#{Regexp.last_match(:path)})"
|
|
30
43
|
end
|
|
44
|
+
super(input.merge(data: rewritten))
|
|
31
45
|
end
|
|
32
|
-
res
|
|
33
46
|
end
|
|
47
|
+
|
|
48
|
+
Sprockets.unregister_postprocessor('text/css', Sprockets::Rails::AssetUrlProcessor)
|
|
49
|
+
Sprockets.register_postprocessor('text/css', TinymceSkinSafeAssetUrlProcessor)
|
|
34
50
|
end
|
|
51
|
+
|
|
52
|
+
# Add additional assets to the asset load path
|
|
53
|
+
Rails.application.config.assets.precompile += %w[camaleon_cms/*]
|
|
54
|
+
# Rails.application.config.assets.precompile += %w( themes/*/assets/* )
|
|
55
|
+
|
|
56
|
+
# Precompile plugin/theme assets that live under app/apps/{plugins,themes}/.../assets.
|
|
57
|
+
# Rails' default precompile rules only cover app/assets, so without this plugin/theme
|
|
58
|
+
# assets are never declared as precompiled and `javascript_include_tag` /
|
|
59
|
+
# `stylesheet_link_tag` raise `AssetNotPrecompiledError` on Sprockets >= 4 when
|
|
60
|
+
# `unknown_asset_fallback` is disabled. Sprockets 4 only resolves exact logical paths
|
|
61
|
+
# (globs/procs are not honored by `asset_precompiled?`), so we enumerate them as strings.
|
|
62
|
+
require 'camaleon_cms/assets_precompile'
|
|
63
|
+
Rails.application.config.assets.precompile += CamaleonCms::AssetsPrecompile.logical_paths
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# load all custom initializers of plugins or themes
|
|
2
2
|
Rails.application.config.to_prepare do |_config|
|
|
3
3
|
PluginRoutes.all_apps.each do |ap|
|
|
4
|
-
next
|
|
4
|
+
next if ap['path'].blank?
|
|
5
5
|
|
|
6
6
|
f = File.join(ap['path'], 'config', 'initializer.rb')
|
|
7
7
|
load f if File.exist?(f)
|
|
@@ -136,6 +136,7 @@ ar:
|
|
|
136
136
|
message:
|
|
137
137
|
success: 'Welcome!!!'
|
|
138
138
|
fail: 'Username or Password incorrect'
|
|
139
|
+
too_many_attempts: 'محاولات فاشلة كثيرة جدًا. يرجى المحاولة مرة أخرى لاحقًا.'
|
|
139
140
|
forgot_url_incorrect: 'URL incorrect'
|
|
140
141
|
forgot_expired: 'Reset expired.'
|
|
141
142
|
hello: 'Hello'
|
|
@@ -135,6 +135,7 @@ de:
|
|
|
135
135
|
message:
|
|
136
136
|
success: 'Willkommen!!!'
|
|
137
137
|
fail: 'Benutzername oder Passwort falsch'
|
|
138
|
+
too_many_attempts: 'Zu viele fehlgeschlagene Versuche. Bitte versuchen Sie es später erneut.'
|
|
138
139
|
forgot_url_incorrect: 'URL inkorrekt'
|
|
139
140
|
forgot_expired: 'Resetfunktion abgelaufen'
|
|
140
141
|
hello: 'Hallo'
|